4 * Copyright (C) 2006, 2008, 2009 Internet Systems Consortium, Inc. ("ISC")
6 * Permission to use, copy, modify, and/or distribute this software for any
7 * purpose with or without fee is hereby granted, provided that the above
8 * copyright notice and this permission notice appear in all copies.
10 * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
11 * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
12 * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
13 * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
14 * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
15 * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
16 * PERFORMANCE OF THIS SOFTWARE.
19 /* Id: nsec3.c,v 1.13 2009/12/01 05:28:40 marka Exp */
23 #include <isc/base32.h>
24 #include <isc/buffer.h>
26 #include <isc/iterated_hash.h>
27 #include <isc/string.h>
33 #include <dns/compress.h>
34 #include <dns/dbiterator.h>
36 #include <dns/fixedname.h>
37 #include <dns/nsec3.h>
38 #include <dns/rdata.h>
39 #include <dns/rdatalist.h>
40 #include <dns/rdataset.h>
41 #include <dns/rdatasetiter.h>
42 #include <dns/rdatastruct.h>
43 #include <dns/result.h>
45 #define CHECK(x) do { \
47 if (result != ISC_R_SUCCESS) \
51 #define OPTOUT(x) (((x) & DNS_NSEC3FLAG_OPTOUT) != 0)
52 #define CREATE(x) (((x) & DNS_NSEC3FLAG_CREATE) != 0)
53 #define REMOVE(x) (((x) & DNS_NSEC3FLAG_REMOVE) != 0)
56 set_bit(unsigned char *array
, unsigned int index
, unsigned int bit
) {
57 unsigned int shift
, mask
;
59 shift
= 7 - (index
% 8);
63 array
[index
/ 8] |= mask
;
65 array
[index
/ 8] &= (~mask
& 0xFF);
69 bit_isset(unsigned char *array
, unsigned int index
) {
70 unsigned int byte
, shift
, mask
;
72 byte
= array
[index
/ 8];
73 shift
= 7 - (index
% 8);
76 return ((byte
& mask
) != 0);
80 dns_nsec3_buildrdata(dns_db_t
*db
, dns_dbversion_t
*version
,
81 dns_dbnode_t
*node
, unsigned int hashalg
,
82 unsigned int flags
, unsigned int iterations
,
83 const unsigned char *salt
, size_t salt_length
,
84 const unsigned char *nexthash
, size_t hash_length
,
85 unsigned char *buffer
, dns_rdata_t
*rdata
)
88 dns_rdataset_t rdataset
;
90 unsigned int i
, window
;
93 isc_boolean_t found_ns
;
94 isc_boolean_t need_rrsig
;
96 unsigned char *nsec_bits
, *bm
;
97 unsigned int max_type
;
98 dns_rdatasetiter_t
*rdsiter
;
101 REQUIRE(salt_length
< 256U);
102 REQUIRE(hash_length
< 256U);
103 REQUIRE(flags
<= 0xffU
);
104 REQUIRE(hashalg
<= 0xffU
);
105 REQUIRE(iterations
<= 0xffffU
);
109 REQUIRE(hash_length
== ISC_SHA1_DIGESTLENGTH
);
113 memset(buffer
, 0, DNS_NSEC3_BUFFERSIZE
);
120 *p
++ = iterations
>> 8;
124 memcpy(p
, salt
, salt_length
);
128 memcpy(p
, nexthash
, hash_length
);
131 r
.length
= p
- buffer
;
135 * Use the end of the space for a raw bitmap leaving enough
136 * space for the window identifiers and length octets.
138 bm
= r
.base
+ r
.length
+ 512;
139 nsec_bits
= r
.base
+ r
.length
;
142 goto collapse_bitmap
;
143 dns_rdataset_init(&rdataset
);
145 result
= dns_db_allrdatasets(db
, node
, version
, 0, &rdsiter
);
146 if (result
!= ISC_R_SUCCESS
)
148 found
= found_ns
= need_rrsig
= ISC_FALSE
;
149 for (result
= dns_rdatasetiter_first(rdsiter
);
150 result
== ISC_R_SUCCESS
;
151 result
= dns_rdatasetiter_next(rdsiter
))
153 dns_rdatasetiter_current(rdsiter
, &rdataset
);
154 if (rdataset
.type
!= dns_rdatatype_nsec
&&
155 rdataset
.type
!= dns_rdatatype_nsec3
&&
156 rdataset
.type
!= dns_rdatatype_rrsig
) {
157 if (rdataset
.type
> max_type
)
158 max_type
= rdataset
.type
;
159 set_bit(bm
, rdataset
.type
, 1);
161 * Work out if we need to set the RRSIG bit for
162 * this node. We set the RRSIG bit if either of
163 * the following conditions are met:
164 * 1) We have a SOA or DS then we need to set
165 * the RRSIG bit as both always will be signed.
166 * 2) We set the RRSIG bit if we don't have
167 * a NS record but do have other data.
169 if (rdataset
.type
== dns_rdatatype_soa
||
170 rdataset
.type
== dns_rdatatype_ds
)
171 need_rrsig
= ISC_TRUE
;
172 else if (rdataset
.type
== dns_rdatatype_ns
)
177 dns_rdataset_disassociate(&rdataset
);
179 if ((found
&& !found_ns
) || need_rrsig
) {
180 if (dns_rdatatype_rrsig
> max_type
)
181 max_type
= dns_rdatatype_rrsig
;
182 set_bit(bm
, dns_rdatatype_rrsig
, 1);
186 * At zone cuts, deny the existence of glue in the parent zone.
188 if (bit_isset(bm
, dns_rdatatype_ns
) &&
189 ! bit_isset(bm
, dns_rdatatype_soa
)) {
190 for (i
= 0; i
<= max_type
; i
++) {
191 if (bit_isset(bm
, i
) &&
192 ! dns_rdatatype_iszonecutauth((dns_rdatatype_t
)i
))
197 dns_rdatasetiter_destroy(&rdsiter
);
198 if (result
!= ISC_R_NOMORE
)
202 for (window
= 0; window
< 256; window
++) {
203 if (window
* 256 > max_type
)
205 for (octet
= 31; octet
>= 0; octet
--)
206 if (bm
[window
* 32 + octet
] != 0)
210 nsec_bits
[0] = window
;
211 nsec_bits
[1] = octet
+ 1;
213 * Note: potentially overlapping move.
215 memmove(&nsec_bits
[2], &bm
[window
* 32], octet
+ 1);
216 nsec_bits
+= 3 + octet
;
218 r
.length
= nsec_bits
- r
.base
;
219 INSIST(r
.length
<= DNS_NSEC3_BUFFERSIZE
);
220 dns_rdata_fromregion(rdata
, dns_db_class(db
), dns_rdatatype_nsec3
, &r
);
222 return (ISC_R_SUCCESS
);
226 dns_nsec3_typepresent(dns_rdata_t
*rdata
, dns_rdatatype_t type
) {
227 dns_rdata_nsec3_t nsec3
;
229 isc_boolean_t present
;
230 unsigned int i
, len
, window
;
232 REQUIRE(rdata
!= NULL
);
233 REQUIRE(rdata
->type
== dns_rdatatype_nsec3
);
235 /* This should never fail */
236 result
= dns_rdata_tostruct(rdata
, &nsec3
, NULL
);
237 INSIST(result
== ISC_R_SUCCESS
);
240 for (i
= 0; i
< nsec3
.len
; i
+= len
) {
241 INSIST(i
+ 2 <= nsec3
.len
);
242 window
= nsec3
.typebits
[i
];
243 len
= nsec3
.typebits
[i
+ 1];
244 INSIST(len
> 0 && len
<= 32);
246 INSIST(i
+ len
<= nsec3
.len
);
247 if (window
* 256 > type
)
249 if ((window
+ 1) * 256 <= type
)
251 if (type
< (window
* 256) + len
* 8)
252 present
= ISC_TF(bit_isset(&nsec3
.typebits
[i
],
256 dns_rdata_freestruct(&nsec3
);
261 dns_nsec3_hashname(dns_fixedname_t
*result
,
262 unsigned char rethash
[NSEC3_MAX_HASH_LENGTH
],
263 size_t *hash_length
, dns_name_t
*name
, dns_name_t
*origin
,
264 dns_hash_t hashalg
, unsigned int iterations
,
265 const unsigned char *salt
, size_t saltlength
)
267 unsigned char hash
[NSEC3_MAX_HASH_LENGTH
];
268 unsigned char nametext
[DNS_NAME_FORMATSIZE
];
269 dns_fixedname_t fixed
;
270 dns_name_t
*downcased
;
271 isc_buffer_t namebuffer
;
278 memset(rethash
, 0, NSEC3_MAX_HASH_LENGTH
);
280 dns_fixedname_init(&fixed
);
281 downcased
= dns_fixedname_name(&fixed
);
282 dns_name_downcase(name
, downcased
, NULL
);
284 /* hash the node name */
285 len
= isc_iterated_hash(rethash
, hashalg
, iterations
, salt
, saltlength
,
286 downcased
->ndata
, downcased
->length
);
288 return (DNS_R_BADALG
);
290 if (hash_length
!= NULL
)
293 /* convert the hash to base32hex */
294 region
.base
= rethash
;
296 isc_buffer_init(&namebuffer
, nametext
, sizeof nametext
);
297 isc_base32hex_totext(®ion
, 1, "", &namebuffer
);
299 /* convert the hex to a domain name */
300 dns_fixedname_init(result
);
301 return (dns_name_fromtext(dns_fixedname_name(result
), &namebuffer
,
306 dns_nsec3_hashlength(dns_hash_t hash
) {
309 case dns_hash_sha1
: return(ISC_SHA1_DIGESTLENGTH
);
315 dns_nsec3_supportedhash(dns_hash_t hash
) {
317 case dns_hash_sha1
: return (ISC_TRUE
);
323 * Update a single RR in version 'ver' of 'db' and log the
327 * \li '*tuple' == NULL. Either the tuple is freed, or its
328 * ownership has been transferred to the diff.
331 do_one_tuple(dns_difftuple_t
**tuple
, dns_db_t
*db
, dns_dbversion_t
*ver
,
334 dns_diff_t temp_diff
;
338 * Create a singleton diff.
340 dns_diff_init(diff
->mctx
, &temp_diff
);
341 temp_diff
.resign
= diff
->resign
;
342 ISC_LIST_APPEND(temp_diff
.tuples
, *tuple
, link
);
345 * Apply it to the database.
347 result
= dns_diff_apply(&temp_diff
, db
, ver
);
348 ISC_LIST_UNLINK(temp_diff
.tuples
, *tuple
, link
);
349 if (result
!= ISC_R_SUCCESS
) {
350 dns_difftuple_free(tuple
);
355 * Merge it into the current pending journal entry.
357 dns_diff_appendminimal(diff
, tuple
);
360 * Do not clear temp_diff.
362 return (ISC_R_SUCCESS
);
366 * Set '*exists' to true iff the given name exists, to false otherwise.
369 name_exists(dns_db_t
*db
, dns_dbversion_t
*version
, dns_name_t
*name
,
370 isc_boolean_t
*exists
)
373 dns_dbnode_t
*node
= NULL
;
374 dns_rdatasetiter_t
*iter
= NULL
;
376 result
= dns_db_findnode(db
, name
, ISC_FALSE
, &node
);
377 if (result
== ISC_R_NOTFOUND
) {
379 return (ISC_R_SUCCESS
);
381 if (result
!= ISC_R_SUCCESS
)
384 result
= dns_db_allrdatasets(db
, node
, version
,
385 (isc_stdtime_t
) 0, &iter
);
386 if (result
!= ISC_R_SUCCESS
)
389 result
= dns_rdatasetiter_first(iter
);
390 if (result
== ISC_R_SUCCESS
) {
392 } else if (result
== ISC_R_NOMORE
) {
394 result
= ISC_R_SUCCESS
;
397 dns_rdatasetiter_destroy(&iter
);
400 dns_db_detachnode(db
, &node
);
405 match_nsec3param(const dns_rdata_nsec3_t
*nsec3
,
406 const dns_rdata_nsec3param_t
*nsec3param
)
408 if (nsec3
->hash
== nsec3param
->hash
&&
409 nsec3
->iterations
== nsec3param
->iterations
&&
410 nsec3
->salt_length
== nsec3param
->salt_length
&&
411 !memcmp(nsec3
->salt
, nsec3param
->salt
, nsec3
->salt_length
))
417 * Delete NSEC3 records at "name" which match "param", recording the
421 delete(dns_db_t
*db
, dns_dbversion_t
*version
, dns_name_t
*name
,
422 const dns_rdata_nsec3param_t
*nsec3param
, dns_diff_t
*diff
)
424 dns_dbnode_t
*node
= NULL
;
425 dns_difftuple_t
*tuple
= NULL
;
426 dns_rdata_nsec3_t nsec3
;
427 dns_rdataset_t rdataset
;
430 result
= dns_db_findnsec3node(db
, name
, ISC_FALSE
, &node
);
431 if (result
== ISC_R_NOTFOUND
)
432 return (ISC_R_SUCCESS
);
433 if (result
!= ISC_R_SUCCESS
)
436 dns_rdataset_init(&rdataset
);
437 result
= dns_db_findrdataset(db
, node
, version
, dns_rdatatype_nsec3
, 0,
438 (isc_stdtime_t
) 0, &rdataset
, NULL
);
440 if (result
== ISC_R_NOTFOUND
) {
441 result
= ISC_R_SUCCESS
;
444 if (result
!= ISC_R_SUCCESS
)
447 for (result
= dns_rdataset_first(&rdataset
);
448 result
== ISC_R_SUCCESS
;
449 result
= dns_rdataset_next(&rdataset
))
451 dns_rdata_t rdata
= DNS_RDATA_INIT
;
452 dns_rdataset_current(&rdataset
, &rdata
);
453 CHECK(dns_rdata_tostruct(&rdata
, &nsec3
, NULL
));
455 if (!match_nsec3param(&nsec3
, nsec3param
))
458 result
= dns_difftuple_create(diff
->mctx
, DNS_DIFFOP_DEL
, name
,
459 rdataset
.ttl
, &rdata
, &tuple
);
460 if (result
!= ISC_R_SUCCESS
)
462 result
= do_one_tuple(&tuple
, db
, version
, diff
);
463 if (result
!= ISC_R_SUCCESS
)
466 if (result
!= ISC_R_NOMORE
)
468 result
= ISC_R_SUCCESS
;
471 dns_rdataset_disassociate(&rdataset
);
473 dns_db_detachnode(db
, &node
);
479 better_param(dns_rdataset_t
*nsec3paramset
, dns_rdata_t
*param
) {
480 dns_rdataset_t rdataset
;
483 if (REMOVE(param
->data
[1]))
486 dns_rdataset_init(&rdataset
);
487 dns_rdataset_clone(nsec3paramset
, &rdataset
);
488 for (result
= dns_rdataset_first(&rdataset
);
489 result
== ISC_R_SUCCESS
;
490 result
= dns_rdataset_next(&rdataset
)) {
491 dns_rdata_t rdata
= DNS_RDATA_INIT
;
492 unsigned char buf
[DNS_NSEC3PARAM_BUFFERSIZE
];
494 if (rdataset
.type
!= dns_rdatatype_nsec3param
) {
495 dns_rdata_t tmprdata
= DNS_RDATA_INIT
;
496 dns_rdataset_current(&rdataset
, &tmprdata
);
497 if (!dns_nsec3param_fromprivate(&tmprdata
, &rdata
,
501 dns_rdataset_current(&rdataset
, &rdata
);
503 if (rdata
.length
!= param
->length
)
505 if (rdata
.data
[0] != param
->data
[0] ||
506 REMOVE(rdata
.data
[1]) ||
507 rdata
.data
[2] != param
->data
[2] ||
508 rdata
.data
[3] != param
->data
[3] ||
509 rdata
.data
[4] != param
->data
[4] ||
510 memcmp(&rdata
.data
[5], ¶m
->data
[5], param
->data
[4]))
512 if (CREATE(rdata
.data
[1]) && !CREATE(param
->data
[1])) {
513 dns_rdataset_disassociate(&rdataset
);
517 dns_rdataset_disassociate(&rdataset
);
522 find_nsec3(dns_rdata_nsec3_t
*nsec3
, dns_rdataset_t
*rdataset
,
523 const dns_rdata_nsec3param_t
*nsec3param
)
526 for (result
= dns_rdataset_first(rdataset
);
527 result
== ISC_R_SUCCESS
;
528 result
= dns_rdataset_next(rdataset
)) {
529 dns_rdata_t rdata
= DNS_RDATA_INIT
;
531 dns_rdataset_current(rdataset
, &rdata
);
532 CHECK(dns_rdata_tostruct(&rdata
, nsec3
, NULL
));
533 dns_rdata_reset(&rdata
);
534 if (match_nsec3param(nsec3
, nsec3param
))
542 dns_nsec3_addnsec3(dns_db_t
*db
, dns_dbversion_t
*version
,
543 dns_name_t
*name
, const dns_rdata_nsec3param_t
*nsec3param
,
544 dns_ttl_t nsecttl
, isc_boolean_t unsecure
, dns_diff_t
*diff
)
546 dns_dbiterator_t
*dbit
= NULL
;
547 dns_dbnode_t
*node
= NULL
;
548 dns_dbnode_t
*newnode
= NULL
;
549 dns_difftuple_t
*tuple
= NULL
;
550 dns_fixedname_t fixed
;
551 dns_fixedname_t fprev
;
553 dns_name_t
*hashname
;
557 dns_rdata_nsec3_t nsec3
;
558 dns_rdata_t rdata
= DNS_RDATA_INIT
;
559 dns_rdataset_t rdataset
;
561 isc_boolean_t exists
;
562 isc_boolean_t remove_unsecure
= ISC_FALSE
;
566 unsigned char *old_next
;
568 unsigned char nexthash
[NSEC3_MAX_HASH_LENGTH
];
569 unsigned char nsec3buf
[DNS_NSEC3_BUFFERSIZE
];
570 unsigned int iterations
;
573 unsigned int old_length
;
574 unsigned int salt_length
;
576 dns_fixedname_init(&fixed
);
577 hashname
= dns_fixedname_name(&fixed
);
578 dns_fixedname_init(&fprev
);
579 prev
= dns_fixedname_name(&fprev
);
581 dns_rdataset_init(&rdataset
);
583 origin
= dns_db_origin(db
);
588 hash
= nsec3param
->hash
;
589 iterations
= nsec3param
->iterations
;
590 salt_length
= nsec3param
->salt_length
;
591 salt
= nsec3param
->salt
;
594 * Default flags for a new chain.
596 flags
= nsec3param
->flags
& DNS_NSEC3FLAG_OPTOUT
;
599 * If this is the first NSEC3 in the chain nexthash will
600 * remain pointing to itself.
602 next_length
= sizeof(nexthash
);
603 CHECK(dns_nsec3_hashname(&fixed
, nexthash
, &next_length
,
604 name
, origin
, hash
, iterations
,
608 * Create the node if it doesn't exist and hold
609 * a reference to it until we have added the NSEC3.
611 CHECK(dns_db_findnsec3node(db
, hashname
, ISC_TRUE
, &newnode
));
614 * Seek the iterator to the 'newnode'.
616 CHECK(dns_db_createiterator(db
, DNS_DB_NSEC3ONLY
, &dbit
));
617 CHECK(dns_dbiterator_seek(dbit
, hashname
));
618 CHECK(dns_dbiterator_pause(dbit
));
619 result
= dns_db_findrdataset(db
, newnode
, version
, dns_rdatatype_nsec3
,
620 0, (isc_stdtime_t
) 0, &rdataset
, NULL
);
622 * If we updating a existing NSEC3 then find its
625 if (result
== ISC_R_SUCCESS
) {
626 result
= find_nsec3(&nsec3
, &rdataset
, nsec3param
);
627 if (result
== ISC_R_SUCCESS
) {
628 if (!CREATE(nsec3param
->flags
))
630 next_length
= nsec3
.next_length
;
631 INSIST(next_length
<= sizeof(nexthash
));
632 memcpy(nexthash
, nsec3
.next
, next_length
);
633 dns_rdataset_disassociate(&rdataset
);
635 * If the NSEC3 is not for a unsecure delegation then
636 * we are just updating it. If it is for a unsecure
637 * delegation then we need find out if we need to
638 * remove the NSEC3 record or not by examining the
639 * previous NSEC3 record.
644 remove_unsecure
= ISC_TRUE
;
646 dns_rdataset_disassociate(&rdataset
);
647 if (result
!= ISC_R_NOMORE
)
653 * Find the previous NSEC3 (if any) and update it if required.
657 result
= dns_dbiterator_prev(dbit
);
658 if (result
== ISC_R_NOMORE
) {
660 CHECK(dns_dbiterator_last(dbit
));
662 CHECK(dns_dbiterator_current(dbit
, &node
, prev
));
663 CHECK(dns_dbiterator_pause(dbit
));
664 result
= dns_db_findrdataset(db
, node
, version
,
665 dns_rdatatype_nsec3
, 0,
666 (isc_stdtime_t
) 0, &rdataset
,
668 dns_db_detachnode(db
, &node
);
669 if (result
!= ISC_R_SUCCESS
)
672 result
= find_nsec3(&nsec3
, &rdataset
, nsec3param
);
673 if (result
== ISC_R_NOMORE
) {
674 dns_rdataset_disassociate(&rdataset
);
677 if (result
!= ISC_R_SUCCESS
)
680 if (remove_unsecure
) {
681 dns_rdataset_disassociate(&rdataset
);
683 * We have found the previous NSEC3 record and can now
684 * see if the existing NSEC3 record needs to be
685 * updated or deleted.
687 if (!OPTOUT(nsec3
.flags
)) {
689 * Just update the NSEC3 record.
694 * This is actually a deletion not a add.
696 result
= dns_nsec3_delnsec3(db
, version
, name
,
702 * Is this is a unsecure delegation we are adding?
703 * If so no change is required.
705 if (OPTOUT(nsec3
.flags
) && unsecure
) {
706 dns_rdataset_disassociate(&rdataset
);
711 old_next
= nsec3
.next
;
712 old_length
= nsec3
.next_length
;
715 * Delete the old previous NSEC3.
717 CHECK(delete(db
, version
, prev
, nsec3param
, diff
));
720 * Fixup the previous NSEC3.
722 nsec3
.next
= nexthash
;
723 nsec3
.next_length
= next_length
;
724 isc_buffer_init(&buffer
, nsec3buf
, sizeof(nsec3buf
));
725 CHECK(dns_rdata_fromstruct(&rdata
, rdataset
.rdclass
,
726 dns_rdatatype_nsec3
, &nsec3
,
728 CHECK(dns_difftuple_create(diff
->mctx
, DNS_DIFFOP_ADD
, prev
,
729 rdataset
.ttl
, &rdata
, &tuple
));
730 CHECK(do_one_tuple(&tuple
, db
, version
, diff
));
731 INSIST(old_length
<= sizeof(nexthash
));
732 memcpy(nexthash
, old_next
, old_length
);
733 if (!CREATE(nsec3param
->flags
))
735 dns_rdata_reset(&rdata
);
736 dns_rdataset_disassociate(&rdataset
);
742 * Create the NSEC3 RDATA.
744 CHECK(dns_db_findnode(db
, name
, ISC_FALSE
, &node
));
745 CHECK(dns_nsec3_buildrdata(db
, version
, node
, hash
, flags
, iterations
,
746 salt
, salt_length
, nexthash
, next_length
,
748 dns_db_detachnode(db
, &node
);
751 * Delete the old NSEC3 and record the change.
753 CHECK(delete(db
, version
, hashname
, nsec3param
, diff
));
755 * Add the new NSEC3 and record the change.
757 CHECK(dns_difftuple_create(diff
->mctx
, DNS_DIFFOP_ADD
,
758 hashname
, nsecttl
, &rdata
, &tuple
));
759 CHECK(do_one_tuple(&tuple
, db
, version
, diff
));
760 INSIST(tuple
== NULL
);
761 dns_rdata_reset(&rdata
);
762 dns_db_detachnode(db
, &newnode
);
765 * Add missing NSEC3 records for empty nodes
767 dns_name_init(&empty
, NULL
);
768 dns_name_clone(name
, &empty
);
770 labels
= dns_name_countlabels(&empty
) - 1;
771 if (labels
<= dns_name_countlabels(origin
))
773 dns_name_getlabelsequence(&empty
, 1, labels
, &empty
);
774 CHECK(name_exists(db
, version
, &empty
, &exists
));
777 CHECK(dns_nsec3_hashname(&fixed
, nexthash
, &next_length
,
778 &empty
, origin
, hash
, iterations
,
782 * Create the node if it doesn't exist and hold
783 * a reference to it until we have added the NSEC3
784 * or we discover we don't need to add make a change.
786 CHECK(dns_db_findnsec3node(db
, hashname
, ISC_TRUE
, &newnode
));
787 result
= dns_db_findrdataset(db
, newnode
, version
,
788 dns_rdatatype_nsec3
, 0,
789 (isc_stdtime_t
) 0, &rdataset
,
791 if (result
== ISC_R_SUCCESS
) {
792 result
= find_nsec3(&nsec3
, &rdataset
, nsec3param
);
793 dns_rdataset_disassociate(&rdataset
);
794 if (result
== ISC_R_SUCCESS
) {
795 dns_db_detachnode(db
, &newnode
);
798 if (result
!= ISC_R_NOMORE
)
803 * Find the previous NSEC3 and update it.
805 CHECK(dns_dbiterator_seek(dbit
, hashname
));
808 result
= dns_dbiterator_prev(dbit
);
809 if (result
== ISC_R_NOMORE
) {
811 CHECK(dns_dbiterator_last(dbit
));
813 CHECK(dns_dbiterator_current(dbit
, &node
, prev
));
814 CHECK(dns_dbiterator_pause(dbit
));
815 result
= dns_db_findrdataset(db
, node
, version
,
816 dns_rdatatype_nsec3
, 0,
819 dns_db_detachnode(db
, &node
);
820 if (result
!= ISC_R_SUCCESS
)
822 result
= find_nsec3(&nsec3
, &rdataset
, nsec3param
);
823 if (result
== ISC_R_NOMORE
) {
824 dns_rdataset_disassociate(&rdataset
);
827 if (result
!= ISC_R_SUCCESS
)
830 old_next
= nsec3
.next
;
831 old_length
= nsec3
.next_length
;
834 * Delete the old previous NSEC3.
836 CHECK(delete(db
, version
, prev
, nsec3param
, diff
));
839 * Fixup the previous NSEC3.
841 nsec3
.next
= nexthash
;
842 nsec3
.next_length
= next_length
;
843 isc_buffer_init(&buffer
, nsec3buf
,
845 CHECK(dns_rdata_fromstruct(&rdata
, rdataset
.rdclass
,
846 dns_rdatatype_nsec3
, &nsec3
,
848 CHECK(dns_difftuple_create(diff
->mctx
, DNS_DIFFOP_ADD
,
849 prev
, rdataset
.ttl
, &rdata
,
851 CHECK(do_one_tuple(&tuple
, db
, version
, diff
));
852 INSIST(old_length
<= sizeof(nexthash
));
853 memcpy(nexthash
, old_next
, old_length
);
854 if (!CREATE(nsec3param
->flags
))
856 dns_rdata_reset(&rdata
);
857 dns_rdataset_disassociate(&rdataset
);
864 * Create the NSEC3 RDATA for the empty node.
866 CHECK(dns_nsec3_buildrdata(db
, version
, NULL
, hash
, flags
,
867 iterations
, salt
, salt_length
,
868 nexthash
, next_length
, nsec3buf
,
871 * Delete the old NSEC3 and record the change.
873 CHECK(delete(db
, version
, hashname
, nsec3param
, diff
));
876 * Add the new NSEC3 and record the change.
878 CHECK(dns_difftuple_create(diff
->mctx
, DNS_DIFFOP_ADD
,
879 hashname
, nsecttl
, &rdata
, &tuple
));
880 CHECK(do_one_tuple(&tuple
, db
, version
, diff
));
881 INSIST(tuple
== NULL
);
882 dns_rdata_reset(&rdata
);
883 dns_db_detachnode(db
, &newnode
);
886 if (result
== ISC_R_NOMORE
)
887 result
= ISC_R_SUCCESS
;
891 dns_dbiterator_destroy(&dbit
);
892 if (dns_rdataset_isassociated(&rdataset
))
893 dns_rdataset_disassociate(&rdataset
);
895 dns_db_detachnode(db
, &node
);
897 dns_db_detachnode(db
, &newnode
);
902 * Add NSEC3 records for "name", recording the change in "diff".
903 * The existing NSEC3 records are removed.
906 dns_nsec3_addnsec3s(dns_db_t
*db
, dns_dbversion_t
*version
,
907 dns_name_t
*name
, dns_ttl_t nsecttl
,
908 isc_boolean_t unsecure
, dns_diff_t
*diff
)
910 dns_dbnode_t
*node
= NULL
;
911 dns_rdata_nsec3param_t nsec3param
;
912 dns_rdataset_t rdataset
;
915 dns_rdataset_init(&rdataset
);
918 * Find the NSEC3 parameters for this zone.
920 result
= dns_db_getoriginnode(db
, &node
);
921 if (result
!= ISC_R_SUCCESS
)
924 result
= dns_db_findrdataset(db
, node
, version
,
925 dns_rdatatype_nsec3param
, 0, 0,
927 dns_db_detachnode(db
, &node
);
928 if (result
== ISC_R_NOTFOUND
)
929 return (ISC_R_SUCCESS
);
930 if (result
!= ISC_R_SUCCESS
)
934 * Update each active NSEC3 chain.
936 for (result
= dns_rdataset_first(&rdataset
);
937 result
== ISC_R_SUCCESS
;
938 result
= dns_rdataset_next(&rdataset
)) {
939 dns_rdata_t rdata
= DNS_RDATA_INIT
;
941 dns_rdataset_current(&rdataset
, &rdata
);
942 CHECK(dns_rdata_tostruct(&rdata
, &nsec3param
, NULL
));
944 if (nsec3param
.flags
!= 0)
947 * We have a active chain. Update it.
949 CHECK(dns_nsec3_addnsec3(db
, version
, name
, &nsec3param
,
950 nsecttl
, unsecure
, diff
));
952 if (result
== ISC_R_NOMORE
)
953 result
= ISC_R_SUCCESS
;
956 if (dns_rdataset_isassociated(&rdataset
))
957 dns_rdataset_disassociate(&rdataset
);
959 dns_db_detachnode(db
, &node
);
965 dns_nsec3param_fromprivate(dns_rdata_t
*src
, dns_rdata_t
*target
,
966 unsigned char *buf
, size_t buflen
)
968 dns_decompress_t dctx
;
974 * Algorithm 0 (reserved by RFC 4034) is used to identify
975 * NSEC3PARAM records from DNSKEY pointers.
977 if (src
->length
< 1 || src
->data
[0] != 0)
980 isc_buffer_init(&buf1
, src
->data
+ 1, src
->length
- 1);
981 isc_buffer_add(&buf1
, src
->length
- 1);
982 isc_buffer_setactive(&buf1
, src
->length
- 1);
983 isc_buffer_init(&buf2
, buf
, buflen
);
984 dns_decompress_init(&dctx
, -1, DNS_DECOMPRESS_NONE
);
985 result
= dns_rdata_fromwire(target
, src
->rdclass
,
986 dns_rdatatype_nsec3param
,
987 &buf1
, &dctx
, 0, &buf2
);
988 dns_decompress_invalidate(&dctx
);
990 return (ISC_TF(result
== ISC_R_SUCCESS
));
994 dns_nsec3param_toprivate(dns_rdata_t
*src
, dns_rdata_t
*target
,
995 dns_rdatatype_t privatetype
,
996 unsigned char *buf
, size_t buflen
)
998 REQUIRE(buflen
>= src
->length
+ 1);
1000 REQUIRE(DNS_RDATA_INITIALIZED(target
));
1002 memcpy(buf
+ 1, src
->data
, src
->length
);
1005 target
->length
= src
->length
+ 1;
1006 target
->type
= privatetype
;
1007 target
->rdclass
= src
->rdclass
;
1009 ISC_LINK_INIT(target
, link
);
1013 dns_nsec3_addnsec3sx(dns_db_t
*db
, dns_dbversion_t
*version
,
1014 dns_name_t
*name
, dns_ttl_t nsecttl
,
1015 isc_boolean_t unsecure
, dns_rdatatype_t type
,
1018 dns_dbnode_t
*node
= NULL
;
1019 dns_rdata_nsec3param_t nsec3param
;
1020 dns_rdataset_t rdataset
;
1021 dns_rdataset_t prdataset
;
1022 isc_result_t result
;
1024 dns_rdataset_init(&rdataset
);
1025 dns_rdataset_init(&prdataset
);
1028 * Find the NSEC3 parameters for this zone.
1030 result
= dns_db_getoriginnode(db
, &node
);
1031 if (result
!= ISC_R_SUCCESS
)
1034 result
= dns_db_findrdataset(db
, node
, version
, type
, 0, 0,
1036 if (result
!= ISC_R_SUCCESS
&& result
!= ISC_R_NOTFOUND
)
1039 result
= dns_db_findrdataset(db
, node
, version
,
1040 dns_rdatatype_nsec3param
, 0, 0,
1042 if (result
== ISC_R_NOTFOUND
)
1044 if (result
!= ISC_R_SUCCESS
)
1048 * Update each active NSEC3 chain.
1050 for (result
= dns_rdataset_first(&rdataset
);
1051 result
== ISC_R_SUCCESS
;
1052 result
= dns_rdataset_next(&rdataset
)) {
1053 dns_rdata_t rdata
= DNS_RDATA_INIT
;
1055 dns_rdataset_current(&rdataset
, &rdata
);
1056 CHECK(dns_rdata_tostruct(&rdata
, &nsec3param
, NULL
));
1058 if (nsec3param
.flags
!= 0)
1062 * We have a active chain. Update it.
1064 CHECK(dns_nsec3_addnsec3(db
, version
, name
, &nsec3param
,
1065 nsecttl
, unsecure
, diff
));
1067 if (result
!= ISC_R_NOMORE
)
1070 dns_rdataset_disassociate(&rdataset
);
1073 if (!dns_rdataset_isassociated(&prdataset
))
1076 * Update each active NSEC3 chain.
1078 for (result
= dns_rdataset_first(&prdataset
);
1079 result
== ISC_R_SUCCESS
;
1080 result
= dns_rdataset_next(&prdataset
)) {
1081 dns_rdata_t rdata1
= DNS_RDATA_INIT
;
1082 dns_rdata_t rdata2
= DNS_RDATA_INIT
;
1083 unsigned char buf
[DNS_NSEC3PARAM_BUFFERSIZE
];
1085 dns_rdataset_current(&prdataset
, &rdata1
);
1086 if (!dns_nsec3param_fromprivate(&rdata1
, &rdata2
,
1089 CHECK(dns_rdata_tostruct(&rdata2
, &nsec3param
, NULL
));
1091 if ((nsec3param
.flags
& DNS_NSEC3FLAG_REMOVE
) != 0)
1093 if (better_param(&prdataset
, &rdata2
))
1097 * We have a active chain. Update it.
1099 CHECK(dns_nsec3_addnsec3(db
, version
, name
, &nsec3param
,
1100 nsecttl
, unsecure
, diff
));
1102 if (result
== ISC_R_NOMORE
)
1104 result
= ISC_R_SUCCESS
;
1106 if (dns_rdataset_isassociated(&rdataset
))
1107 dns_rdataset_disassociate(&rdataset
);
1108 if (dns_rdataset_isassociated(&prdataset
))
1109 dns_rdataset_disassociate(&prdataset
);
1111 dns_db_detachnode(db
, &node
);
1117 * Determine whether any NSEC3 records that were associated with
1118 * 'name' should be deleted or if they should continue to exist.
1119 * ISC_TRUE indicates they should be deleted.
1120 * ISC_FALSE indicates they should be retained.
1123 deleteit(dns_db_t
*db
, dns_dbversion_t
*ver
, dns_name_t
*name
,
1124 isc_boolean_t
*yesno
)
1126 isc_result_t result
;
1127 dns_fixedname_t foundname
;
1128 dns_fixedname_init(&foundname
);
1130 result
= dns_db_find(db
, name
, ver
, dns_rdatatype_any
,
1131 DNS_DBFIND_GLUEOK
| DNS_DBFIND_NOWILD
,
1132 (isc_stdtime_t
) 0, NULL
,
1133 dns_fixedname_name(&foundname
),
1135 if (result
== DNS_R_EMPTYNAME
|| result
== ISC_R_SUCCESS
||
1136 result
== DNS_R_ZONECUT
) {
1138 return (ISC_R_SUCCESS
);
1140 if (result
== DNS_R_GLUE
|| result
== DNS_R_DNAME
||
1141 result
== DNS_R_DELEGATION
|| result
== DNS_R_NXDOMAIN
) {
1143 return (ISC_R_SUCCESS
);
1153 dns_nsec3_delnsec3(dns_db_t
*db
, dns_dbversion_t
*version
, dns_name_t
*name
,
1154 const dns_rdata_nsec3param_t
*nsec3param
, dns_diff_t
*diff
)
1156 dns_dbiterator_t
*dbit
= NULL
;
1157 dns_dbnode_t
*node
= NULL
;
1158 dns_difftuple_t
*tuple
= NULL
;
1159 dns_fixedname_t fixed
;
1160 dns_fixedname_t fprev
;
1162 dns_name_t
*hashname
;
1166 dns_rdata_nsec3_t nsec3
;
1167 dns_rdata_t rdata
= DNS_RDATA_INIT
;
1168 dns_rdataset_t rdataset
;
1170 isc_boolean_t yesno
;
1171 isc_buffer_t buffer
;
1172 isc_result_t result
;
1173 unsigned char *salt
;
1174 unsigned char nexthash
[NSEC3_MAX_HASH_LENGTH
];
1175 unsigned char nsec3buf
[DNS_NSEC3_BUFFERSIZE
];
1176 unsigned int iterations
;
1177 unsigned int labels
;
1179 unsigned int salt_length
;
1181 dns_fixedname_init(&fixed
);
1182 hashname
= dns_fixedname_name(&fixed
);
1183 dns_fixedname_init(&fprev
);
1184 prev
= dns_fixedname_name(&fprev
);
1186 dns_rdataset_init(&rdataset
);
1188 origin
= dns_db_origin(db
);
1193 hash
= nsec3param
->hash
;
1194 iterations
= nsec3param
->iterations
;
1195 salt_length
= nsec3param
->salt_length
;
1196 salt
= nsec3param
->salt
;
1199 * If this is the first NSEC3 in the chain nexthash will
1200 * remain pointing to itself.
1202 next_length
= sizeof(nexthash
);
1203 CHECK(dns_nsec3_hashname(&fixed
, nexthash
, &next_length
,
1204 name
, origin
, hash
, iterations
,
1205 salt
, salt_length
));
1207 CHECK(dns_db_createiterator(db
, DNS_DB_NSEC3ONLY
, &dbit
));
1209 result
= dns_dbiterator_seek(dbit
, hashname
);
1210 if (result
== ISC_R_NOTFOUND
)
1212 if (result
!= ISC_R_SUCCESS
)
1215 CHECK(dns_dbiterator_current(dbit
, &node
, NULL
));
1216 CHECK(dns_dbiterator_pause(dbit
));
1217 result
= dns_db_findrdataset(db
, node
, version
, dns_rdatatype_nsec3
,
1218 0, (isc_stdtime_t
) 0, &rdataset
, NULL
);
1219 dns_db_detachnode(db
, &node
);
1220 if (result
== ISC_R_NOTFOUND
)
1222 if (result
!= ISC_R_SUCCESS
)
1226 * If we find a existing NSEC3 for this chain then save the
1229 result
= find_nsec3(&nsec3
, &rdataset
, nsec3param
);
1230 if (result
== ISC_R_SUCCESS
) {
1231 next_length
= nsec3
.next_length
;
1232 INSIST(next_length
<= sizeof(nexthash
));
1233 memcpy(nexthash
, nsec3
.next
, next_length
);
1235 dns_rdataset_disassociate(&rdataset
);
1236 if (result
== ISC_R_NOMORE
)
1238 if (result
!= ISC_R_SUCCESS
)
1242 * Find the previous NSEC3 and update it.
1246 result
= dns_dbiterator_prev(dbit
);
1247 if (result
== ISC_R_NOMORE
) {
1249 CHECK(dns_dbiterator_last(dbit
));
1251 CHECK(dns_dbiterator_current(dbit
, &node
, prev
));
1252 CHECK(dns_dbiterator_pause(dbit
));
1253 result
= dns_db_findrdataset(db
, node
, version
,
1254 dns_rdatatype_nsec3
, 0,
1255 (isc_stdtime_t
) 0, &rdataset
,
1257 dns_db_detachnode(db
, &node
);
1258 if (result
!= ISC_R_SUCCESS
)
1260 result
= find_nsec3(&nsec3
, &rdataset
, nsec3param
);
1261 if (result
== ISC_R_NOMORE
) {
1262 dns_rdataset_disassociate(&rdataset
);
1265 if (result
!= ISC_R_SUCCESS
)
1269 * Delete the old previous NSEC3.
1271 CHECK(delete(db
, version
, prev
, nsec3param
, diff
));
1274 * Fixup the previous NSEC3.
1276 nsec3
.next
= nexthash
;
1277 nsec3
.next_length
= next_length
;
1278 isc_buffer_init(&buffer
, nsec3buf
, sizeof(nsec3buf
));
1279 CHECK(dns_rdata_fromstruct(&rdata
, rdataset
.rdclass
,
1280 dns_rdatatype_nsec3
, &nsec3
,
1282 CHECK(dns_difftuple_create(diff
->mctx
, DNS_DIFFOP_ADD
, prev
,
1283 rdataset
.ttl
, &rdata
, &tuple
));
1284 CHECK(do_one_tuple(&tuple
, db
, version
, diff
));
1285 dns_rdata_reset(&rdata
);
1286 dns_rdataset_disassociate(&rdataset
);
1291 * Delete the old NSEC3 and record the change.
1293 CHECK(delete(db
, version
, hashname
, nsec3param
, diff
));
1296 * Delete NSEC3 records for now non active nodes.
1298 dns_name_init(&empty
, NULL
);
1299 dns_name_clone(name
, &empty
);
1301 labels
= dns_name_countlabels(&empty
) - 1;
1302 if (labels
<= dns_name_countlabels(origin
))
1304 dns_name_getlabelsequence(&empty
, 1, labels
, &empty
);
1305 CHECK(deleteit(db
, version
, &empty
, &yesno
));
1309 CHECK(dns_nsec3_hashname(&fixed
, nexthash
, &next_length
,
1310 &empty
, origin
, hash
, iterations
,
1311 salt
, salt_length
));
1312 result
= dns_dbiterator_seek(dbit
, hashname
);
1313 if (result
== ISC_R_NOTFOUND
)
1315 if (result
!= ISC_R_SUCCESS
)
1318 CHECK(dns_dbiterator_current(dbit
, &node
, NULL
));
1319 CHECK(dns_dbiterator_pause(dbit
));
1320 result
= dns_db_findrdataset(db
, node
, version
,
1321 dns_rdatatype_nsec3
, 0,
1322 (isc_stdtime_t
) 0, &rdataset
,
1324 dns_db_detachnode(db
, &node
);
1325 if (result
== ISC_R_NOTFOUND
)
1327 if (result
!= ISC_R_SUCCESS
)
1330 result
= find_nsec3(&nsec3
, &rdataset
, nsec3param
);
1331 if (result
== ISC_R_SUCCESS
) {
1332 next_length
= nsec3
.next_length
;
1333 INSIST(next_length
<= sizeof(nexthash
));
1334 memcpy(nexthash
, nsec3
.next
, next_length
);
1336 dns_rdataset_disassociate(&rdataset
);
1337 if (result
== ISC_R_NOMORE
)
1339 if (result
!= ISC_R_SUCCESS
)
1344 result
= dns_dbiterator_prev(dbit
);
1345 if (result
== ISC_R_NOMORE
) {
1347 CHECK(dns_dbiterator_last(dbit
));
1349 CHECK(dns_dbiterator_current(dbit
, &node
, prev
));
1350 CHECK(dns_dbiterator_pause(dbit
));
1351 result
= dns_db_findrdataset(db
, node
, version
,
1352 dns_rdatatype_nsec3
, 0,
1355 dns_db_detachnode(db
, &node
);
1356 if (result
!= ISC_R_SUCCESS
)
1358 result
= find_nsec3(&nsec3
, &rdataset
, nsec3param
);
1359 if (result
== ISC_R_NOMORE
) {
1360 dns_rdataset_disassociate(&rdataset
);
1363 if (result
!= ISC_R_SUCCESS
)
1367 * Delete the old previous NSEC3.
1369 CHECK(delete(db
, version
, prev
, nsec3param
, diff
));
1372 * Fixup the previous NSEC3.
1374 nsec3
.next
= nexthash
;
1375 nsec3
.next_length
= next_length
;
1376 isc_buffer_init(&buffer
, nsec3buf
,
1378 CHECK(dns_rdata_fromstruct(&rdata
, rdataset
.rdclass
,
1379 dns_rdatatype_nsec3
, &nsec3
,
1381 CHECK(dns_difftuple_create(diff
->mctx
, DNS_DIFFOP_ADD
,
1382 prev
, rdataset
.ttl
, &rdata
,
1384 CHECK(do_one_tuple(&tuple
, db
, version
, diff
));
1385 dns_rdata_reset(&rdata
);
1386 dns_rdataset_disassociate(&rdataset
);
1393 * Delete the old NSEC3 and record the change.
1395 CHECK(delete(db
, version
, hashname
, nsec3param
, diff
));
1399 result
= ISC_R_SUCCESS
;
1403 dns_dbiterator_destroy(&dbit
);
1404 if (dns_rdataset_isassociated(&rdataset
))
1405 dns_rdataset_disassociate(&rdataset
);
1407 dns_db_detachnode(db
, &node
);
1412 dns_nsec3_delnsec3s(dns_db_t
*db
, dns_dbversion_t
*version
, dns_name_t
*name
,
1415 return (dns_nsec3_delnsec3sx(db
, version
, name
, 0, diff
));
1419 dns_nsec3_delnsec3sx(dns_db_t
*db
, dns_dbversion_t
*version
, dns_name_t
*name
,
1420 dns_rdatatype_t type
, dns_diff_t
*diff
)
1422 dns_dbnode_t
*node
= NULL
;
1423 dns_rdata_nsec3param_t nsec3param
;
1424 dns_rdataset_t rdataset
;
1425 isc_result_t result
;
1427 dns_rdataset_init(&rdataset
);
1430 * Find the NSEC3 parameters for this zone.
1432 result
= dns_db_getoriginnode(db
, &node
);
1433 if (result
!= ISC_R_SUCCESS
)
1436 result
= dns_db_findrdataset(db
, node
, version
,
1437 dns_rdatatype_nsec3param
, 0, 0,
1439 if (result
== ISC_R_NOTFOUND
)
1441 if (result
!= ISC_R_SUCCESS
)
1445 * Update each active NSEC3 chain.
1447 for (result
= dns_rdataset_first(&rdataset
);
1448 result
== ISC_R_SUCCESS
;
1449 result
= dns_rdataset_next(&rdataset
)) {
1450 dns_rdata_t rdata
= DNS_RDATA_INIT
;
1452 dns_rdataset_current(&rdataset
, &rdata
);
1453 CHECK(dns_rdata_tostruct(&rdata
, &nsec3param
, NULL
));
1455 if (nsec3param
.flags
!= 0)
1458 * We have a active chain. Update it.
1460 CHECK(dns_nsec3_delnsec3(db
, version
, name
, &nsec3param
, diff
));
1462 dns_rdataset_disassociate(&rdataset
);
1467 result
= dns_db_findrdataset(db
, node
, version
, type
, 0, 0,
1469 if (result
== ISC_R_NOTFOUND
)
1471 if (result
!= ISC_R_SUCCESS
)
1475 * Update each NSEC3 chain being built.
1477 for (result
= dns_rdataset_first(&rdataset
);
1478 result
== ISC_R_SUCCESS
;
1479 result
= dns_rdataset_next(&rdataset
)) {
1480 dns_rdata_t rdata1
= DNS_RDATA_INIT
;
1481 dns_rdata_t rdata2
= DNS_RDATA_INIT
;
1482 unsigned char buf
[DNS_NSEC3PARAM_BUFFERSIZE
];
1484 dns_rdataset_current(&rdataset
, &rdata1
);
1485 if (!dns_nsec3param_fromprivate(&rdata1
, &rdata2
,
1488 CHECK(dns_rdata_tostruct(&rdata2
, &nsec3param
, NULL
));
1490 if ((nsec3param
.flags
& DNS_NSEC3FLAG_REMOVE
) != 0)
1492 if (better_param(&rdataset
, &rdata2
))
1496 * We have a active chain. Update it.
1498 CHECK(dns_nsec3_delnsec3(db
, version
, name
, &nsec3param
, diff
));
1500 if (result
== ISC_R_NOMORE
)
1502 result
= ISC_R_SUCCESS
;
1505 if (dns_rdataset_isassociated(&rdataset
))
1506 dns_rdataset_disassociate(&rdataset
);
1508 dns_db_detachnode(db
, &node
);
1514 dns_nsec3_active(dns_db_t
*db
, dns_dbversion_t
*version
,
1515 isc_boolean_t complete
, isc_boolean_t
*answer
)
1517 return (dns_nsec3_activex(db
, version
, complete
, 0, answer
));
1521 dns_nsec3_activex(dns_db_t
*db
, dns_dbversion_t
*version
,
1522 isc_boolean_t complete
, dns_rdatatype_t type
,
1523 isc_boolean_t
*answer
)
1525 dns_dbnode_t
*node
= NULL
;
1526 dns_rdataset_t rdataset
;
1527 dns_rdata_nsec3param_t nsec3param
;
1528 isc_result_t result
;
1530 REQUIRE(answer
!= NULL
);
1532 dns_rdataset_init(&rdataset
);
1534 result
= dns_db_getoriginnode(db
, &node
);
1535 if (result
!= ISC_R_SUCCESS
)
1538 result
= dns_db_findrdataset(db
, node
, version
,
1539 dns_rdatatype_nsec3param
, 0, 0,
1542 if (result
== ISC_R_NOTFOUND
)
1545 if (result
!= ISC_R_SUCCESS
) {
1546 dns_db_detachnode(db
, &node
);
1549 for (result
= dns_rdataset_first(&rdataset
);
1550 result
== ISC_R_SUCCESS
;
1551 result
= dns_rdataset_next(&rdataset
)) {
1552 dns_rdata_t rdata
= DNS_RDATA_INIT
;
1554 dns_rdataset_current(&rdataset
, &rdata
);
1555 result
= dns_rdata_tostruct(&rdata
, &nsec3param
, NULL
);
1556 RUNTIME_CHECK(result
== ISC_R_SUCCESS
);
1558 if (nsec3param
.flags
== 0)
1561 dns_rdataset_disassociate(&rdataset
);
1562 if (result
== ISC_R_SUCCESS
) {
1563 dns_db_detachnode(db
, &node
);
1565 return (ISC_R_SUCCESS
);
1567 if (result
== ISC_R_NOMORE
)
1568 *answer
= ISC_FALSE
;
1571 if (type
== 0 || complete
) {
1572 *answer
= ISC_FALSE
;
1573 return (ISC_R_SUCCESS
);
1575 result
= dns_db_findrdataset(db
, node
, version
, type
, 0, 0,
1578 dns_db_detachnode(db
, &node
);
1579 if (result
== ISC_R_NOTFOUND
) {
1580 *answer
= ISC_FALSE
;
1581 return (ISC_R_SUCCESS
);
1583 if (result
!= ISC_R_SUCCESS
)
1586 for (result
= dns_rdataset_first(&rdataset
);
1587 result
== ISC_R_SUCCESS
;
1588 result
= dns_rdataset_next(&rdataset
)) {
1589 dns_rdata_t rdata1
= DNS_RDATA_INIT
;
1590 dns_rdata_t rdata2
= DNS_RDATA_INIT
;
1591 unsigned char buf
[DNS_NSEC3PARAM_BUFFERSIZE
];
1593 dns_rdataset_current(&rdataset
, &rdata1
);
1594 if (!dns_nsec3param_fromprivate(&rdata1
, &rdata2
,
1597 result
= dns_rdata_tostruct(&rdata2
, &nsec3param
, NULL
);
1598 RUNTIME_CHECK(result
== ISC_R_SUCCESS
);
1600 if (!complete
&& CREATE(nsec3param
.flags
))
1603 dns_rdataset_disassociate(&rdataset
);
1604 if (result
== ISC_R_SUCCESS
) {
1606 result
= ISC_R_SUCCESS
;
1608 if (result
== ISC_R_NOMORE
) {
1609 *answer
= ISC_FALSE
;
1610 result
= ISC_R_SUCCESS
;
1617 dns_nsec3_maxiterations(dns_db_t
*db
, dns_dbversion_t
*version
,
1618 isc_mem_t
*mctx
, unsigned int *iterationsp
)
1620 dns_dbnode_t
*node
= NULL
;
1621 dns_rdataset_t rdataset
;
1622 dst_key_t
*key
= NULL
;
1623 isc_buffer_t buffer
;
1624 isc_result_t result
;
1625 isc_uint16_t bits
, minbits
= 4096;
1627 result
= dns_db_getoriginnode(db
, &node
);
1628 if (result
!= ISC_R_SUCCESS
)
1631 dns_rdataset_init(&rdataset
);
1632 result
= dns_db_findrdataset(db
, node
, version
, dns_rdatatype_dnskey
,
1633 0, 0, &rdataset
, NULL
);
1634 dns_db_detachnode(db
, &node
);
1635 if (result
== ISC_R_NOTFOUND
) {
1637 return (ISC_R_SUCCESS
);
1639 if (result
!= ISC_R_SUCCESS
)
1642 for (result
= dns_rdataset_first(&rdataset
);
1643 result
== ISC_R_SUCCESS
;
1644 result
= dns_rdataset_next(&rdataset
)) {
1645 dns_rdata_t rdata
= DNS_RDATA_INIT
;
1647 dns_rdataset_current(&rdataset
, &rdata
);
1648 isc_buffer_init(&buffer
, rdata
.data
, rdata
.length
);
1649 isc_buffer_add(&buffer
, rdata
.length
);
1650 CHECK(dst_key_fromdns(dns_db_origin(db
), rdataset
.rdclass
,
1651 &buffer
, mctx
, &key
));
1652 bits
= dst_key_getbits(key
);
1657 if (result
!= ISC_R_NOMORE
)
1660 if (minbits
<= 1024)
1662 else if (minbits
<= 2048)
1665 *iterationsp
= 2500;
1666 result
= ISC_R_SUCCESS
;
1669 if (dns_rdataset_isassociated(&rdataset
))
1670 dns_rdataset_disassociate(&rdataset
);