summaryrefslogtreecommitdiffstats
path: root/contrib/bind9/lib/dns/nsec3.c
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/bind9/lib/dns/nsec3.c')
-rw-r--r--contrib/bind9/lib/dns/nsec3.c490
1 files changed, 448 insertions, 42 deletions
diff --git a/contrib/bind9/lib/dns/nsec3.c b/contrib/bind9/lib/dns/nsec3.c
index 9c85781..e75e744 100644
--- a/contrib/bind9/lib/dns/nsec3.c
+++ b/contrib/bind9/lib/dns/nsec3.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2006, 2008, 2009 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 2006, 2008-2010 Internet Systems Consortium, Inc. ("ISC")
*
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
@@ -14,7 +14,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: nsec3.c,v 1.6.12.4 2009-11-03 23:47:46 tbox Exp $ */
+/* $Id: nsec3.c,v 1.19.96.1 2011-06-21 20:15:48 each Exp $ */
#include <config.h>
@@ -28,6 +28,8 @@
#include <dst/dst.h>
#include <dns/db.h>
+#include <dns/zone.h>
+#include <dns/compress.h>
#include <dns/dbiterator.h>
#include <dns/diff.h>
#include <dns/fixedname.h>
@@ -472,7 +474,6 @@ delete(dns_db_t *db, dns_dbversion_t *version, dns_name_t *name,
return (result);
}
-#ifndef RFC5155_STRICT
static isc_boolean_t
better_param(dns_rdataset_t *nsec3paramset, dns_rdata_t *param) {
dns_rdataset_t rdataset;
@@ -487,7 +488,17 @@ better_param(dns_rdataset_t *nsec3paramset, dns_rdata_t *param) {
result == ISC_R_SUCCESS;
result = dns_rdataset_next(&rdataset)) {
dns_rdata_t rdata = DNS_RDATA_INIT;
- dns_rdataset_current(&rdataset, &rdata);
+ unsigned char buf[DNS_NSEC3PARAM_BUFFERSIZE];
+
+ if (rdataset.type != dns_rdatatype_nsec3param) {
+ dns_rdata_t tmprdata = DNS_RDATA_INIT;
+ dns_rdataset_current(&rdataset, &tmprdata);
+ if (!dns_nsec3param_fromprivate(&tmprdata, &rdata,
+ buf, sizeof(buf)))
+ continue;
+ } else
+ dns_rdataset_current(&rdataset, &rdata);
+
if (rdata.length != param->length)
continue;
if (rdata.data[0] != param->data[0] ||
@@ -505,7 +516,6 @@ better_param(dns_rdataset_t *nsec3paramset, dns_rdata_t *param) {
dns_rdataset_disassociate(&rdataset);
return (ISC_FALSE);
}
-#endif
static isc_result_t
find_nsec3(dns_rdata_nsec3_t *nsec3, dns_rdataset_t *rdataset,
@@ -548,7 +558,7 @@ dns_nsec3_addnsec3(dns_db_t *db, dns_dbversion_t *version,
dns_rdataset_t rdataset;
int pass;
isc_boolean_t exists;
- isc_boolean_t remove_unsecure = ISC_FALSE;
+ isc_boolean_t maybe_remove_unsecure = ISC_FALSE;
isc_uint8_t flags;
isc_buffer_t buffer;
isc_result_t result;
@@ -629,8 +639,12 @@ dns_nsec3_addnsec3(dns_db_t *db, dns_dbversion_t *version,
*/
if (!unsecure)
goto addnsec3;
- else
- remove_unsecure = ISC_TRUE;
+ else if (CREATE(nsec3param->flags) && OPTOUT(flags)) {
+ result = dns_nsec3_delnsec3(db, version, name,
+ nsec3param, diff);
+ goto failure;
+ } else
+ maybe_remove_unsecure = ISC_TRUE;
} else {
dns_rdataset_disassociate(&rdataset);
if (result != ISC_R_NOMORE)
@@ -666,26 +680,19 @@ dns_nsec3_addnsec3(dns_db_t *db, dns_dbversion_t *version,
if (result != ISC_R_SUCCESS)
goto failure;
- if (remove_unsecure) {
+ if (maybe_remove_unsecure) {
dns_rdataset_disassociate(&rdataset);
/*
- * We have found the previous NSEC3 record and can now
- * see if the existing NSEC3 record needs to be
- * updated or deleted.
+ * If we have OPTOUT set in the previous NSEC3 record
+ * we actually need to delete the NSEC3 record.
+ * Otherwise we just need to replace the NSEC3 record.
*/
- if (!OPTOUT(nsec3.flags)) {
- /*
- * Just update the NSEC3 record.
- */
- goto addnsec3;
- } else {
- /*
- * This is actually a deletion not a add.
- */
+ if (OPTOUT(nsec3.flags)) {
result = dns_nsec3_delnsec3(db, version, name,
nsec3param, diff);
goto failure;
}
+ goto addnsec3;
} else {
/*
* Is this is a unsecure delegation we are adding?
@@ -928,17 +935,323 @@ dns_nsec3_addnsec3s(dns_db_t *db, dns_dbversion_t *version,
dns_rdata_t rdata = DNS_RDATA_INIT;
dns_rdataset_current(&rdataset, &rdata);
- dns_rdata_tostruct(&rdata, &nsec3param, NULL);
+ CHECK(dns_rdata_tostruct(&rdata, &nsec3param, NULL));
+
+ if (nsec3param.flags != 0)
+ continue;
+ /*
+ * We have a active chain. Update it.
+ */
+ CHECK(dns_nsec3_addnsec3(db, version, name, &nsec3param,
+ nsecttl, unsecure, diff));
+ }
+ if (result == ISC_R_NOMORE)
+ result = ISC_R_SUCCESS;
+
+ failure:
+ if (dns_rdataset_isassociated(&rdataset))
+ dns_rdataset_disassociate(&rdataset);
+ if (node != NULL)
+ dns_db_detachnode(db, &node);
+
+ return (result);
+}
+
+isc_boolean_t
+dns_nsec3param_fromprivate(dns_rdata_t *src, dns_rdata_t *target,
+ unsigned char *buf, size_t buflen)
+{
+ dns_decompress_t dctx;
+ isc_result_t result;
+ isc_buffer_t buf1;
+ isc_buffer_t buf2;
+
+ /*
+ * Algorithm 0 (reserved by RFC 4034) is used to identify
+ * NSEC3PARAM records from DNSKEY pointers.
+ */
+ if (src->length < 1 || src->data[0] != 0)
+ return (ISC_FALSE);
+
+ isc_buffer_init(&buf1, src->data + 1, src->length - 1);
+ isc_buffer_add(&buf1, src->length - 1);
+ isc_buffer_setactive(&buf1, src->length - 1);
+ isc_buffer_init(&buf2, buf, buflen);
+ dns_decompress_init(&dctx, -1, DNS_DECOMPRESS_NONE);
+ result = dns_rdata_fromwire(target, src->rdclass,
+ dns_rdatatype_nsec3param,
+ &buf1, &dctx, 0, &buf2);
+ dns_decompress_invalidate(&dctx);
+
+ return (ISC_TF(result == ISC_R_SUCCESS));
+}
+
+void
+dns_nsec3param_toprivate(dns_rdata_t *src, dns_rdata_t *target,
+ dns_rdatatype_t privatetype,
+ unsigned char *buf, size_t buflen)
+{
+ REQUIRE(buflen >= src->length + 1);
+
+ REQUIRE(DNS_RDATA_INITIALIZED(target));
+
+ memcpy(buf + 1, src->data, src->length);
+ buf[0] = 0;
+ target->data = buf;
+ target->length = src->length + 1;
+ target->type = privatetype;
+ target->rdclass = src->rdclass;
+ target->flags = 0;
+ ISC_LINK_INIT(target, link);
+}
+
+#ifdef BIND9
+static isc_result_t
+rr_exists(dns_db_t *db, dns_dbversion_t *ver, dns_name_t *name,
+ const dns_rdata_t *rdata, isc_boolean_t *flag)
+{
+ dns_rdataset_t rdataset;
+ dns_dbnode_t *node = NULL;
+ isc_result_t result;
+
+ dns_rdataset_init(&rdataset);
+ if (rdata->type == dns_rdatatype_nsec3)
+ CHECK(dns_db_findnsec3node(db, name, ISC_FALSE, &node));
+ else
+ CHECK(dns_db_findnode(db, name, ISC_FALSE, &node));
+ result = dns_db_findrdataset(db, node, ver, rdata->type, 0,
+ (isc_stdtime_t) 0, &rdataset, NULL);
+ if (result == ISC_R_NOTFOUND) {
+ *flag = ISC_FALSE;
+ result = ISC_R_SUCCESS;
+ goto failure;
+ }
+
+ for (result = dns_rdataset_first(&rdataset);
+ result == ISC_R_SUCCESS;
+ result = dns_rdataset_next(&rdataset)) {
+ dns_rdata_t myrdata = DNS_RDATA_INIT;
+ dns_rdataset_current(&rdataset, &myrdata);
+ if (!dns_rdata_casecompare(&myrdata, rdata))
+ break;
+ }
+ dns_rdataset_disassociate(&rdataset);
+ if (result == ISC_R_SUCCESS) {
+ *flag = ISC_TRUE;
+ } else if (result == ISC_R_NOMORE) {
+ *flag = ISC_FALSE;
+ result = ISC_R_SUCCESS;
+ }
+
+ failure:
+ if (node != NULL)
+ dns_db_detachnode(db, &node);
+ return (result);
+}
+#endif
+
+#ifdef BIND9
+isc_result_t
+dns_nsec3param_deletechains(dns_db_t *db, dns_dbversion_t *ver,
+ dns_zone_t *zone, dns_diff_t *diff)
+{
+ dns_dbnode_t *node = NULL;
+ dns_difftuple_t *tuple = NULL;
+ dns_name_t next;
+ dns_rdata_t rdata = DNS_RDATA_INIT;
+ dns_rdataset_t rdataset;
+ isc_boolean_t flag;
+ isc_result_t result = ISC_R_SUCCESS;
+ unsigned char buf[DNS_NSEC3PARAM_BUFFERSIZE + 1];
+ dns_name_t *origin = dns_zone_getorigin(zone);
+ dns_rdatatype_t privatetype = dns_zone_getprivatetype(zone);
+
+ dns_name_init(&next, NULL);
+ dns_rdataset_init(&rdataset);
+
+ result = dns_db_getoriginnode(db, &node);
+ if (result != ISC_R_SUCCESS)
+ return (result);
+
+ /*
+ * Cause all NSEC3 chains to be deleted.
+ */
+ result = dns_db_findrdataset(db, node, ver, dns_rdatatype_nsec3param,
+ 0, (isc_stdtime_t) 0, &rdataset, NULL);
+ if (result == ISC_R_NOTFOUND)
+ goto try_private;
+ if (result != ISC_R_SUCCESS)
+ goto failure;
+
+ for (result = dns_rdataset_first(&rdataset);
+ result == ISC_R_SUCCESS;
+ result = dns_rdataset_next(&rdataset)) {
+ dns_rdata_t private = DNS_RDATA_INIT;
+
+ dns_rdataset_current(&rdataset, &rdata);
+
+ CHECK(dns_difftuple_create(diff->mctx, DNS_DIFFOP_DEL, origin,
+ rdataset.ttl, &rdata, &tuple));
+ CHECK(do_one_tuple(&tuple, db, ver, diff));
+ INSIST(tuple == NULL);
+
+ dns_nsec3param_toprivate(&rdata, &private, privatetype,
+ buf, sizeof(buf));
+ buf[2] = DNS_NSEC3FLAG_REMOVE | DNS_NSEC3FLAG_NONSEC;
+
+ CHECK(rr_exists(db, ver, origin, &private, &flag));
+
+ if (!flag) {
+ CHECK(dns_difftuple_create(diff->mctx, DNS_DIFFOP_ADD,
+ origin, 0, &private,
+ &tuple));
+ CHECK(do_one_tuple(&tuple, db, ver, diff));
+ INSIST(tuple == NULL);
+ }
+ dns_rdata_reset(&rdata);
+ }
+ if (result != ISC_R_NOMORE)
+ goto failure;
+
+ dns_rdataset_disassociate(&rdataset);
+
+ try_private:
+ if (privatetype == 0)
+ goto success;
+ result = dns_db_findrdataset(db, node, ver, privatetype, 0,
+ (isc_stdtime_t) 0, &rdataset, NULL);
+ if (result == ISC_R_NOTFOUND)
+ goto success;
+ if (result != ISC_R_SUCCESS)
+ goto failure;
+
+ for (result = dns_rdataset_first(&rdataset);
+ result == ISC_R_SUCCESS;
+ result = dns_rdataset_next(&rdataset)) {
+ dns_rdataset_current(&rdataset, &rdata);
+ INSIST(rdata.length <= sizeof(buf));
+ memcpy(buf, rdata.data, rdata.length);
+
+ if (buf[0] != 0 ||
+ buf[2] == (DNS_NSEC3FLAG_REMOVE | DNS_NSEC3FLAG_NONSEC)) {
+ dns_rdata_reset(&rdata);
+ continue;
+ }
+
+ CHECK(dns_difftuple_create(diff->mctx, DNS_DIFFOP_DEL, origin,
+ 0, &rdata, &tuple));
+ CHECK(do_one_tuple(&tuple, db, ver, diff));
+ INSIST(tuple == NULL);
+
+ rdata.data = buf;
+ buf[2] = DNS_NSEC3FLAG_REMOVE | DNS_NSEC3FLAG_NONSEC;
+
+ CHECK(rr_exists(db, ver, origin, &rdata, &flag));
+
+ if (!flag) {
+ CHECK(dns_difftuple_create(diff->mctx, DNS_DIFFOP_ADD,
+ origin, 0, &rdata, &tuple));
+ CHECK(do_one_tuple(&tuple, db, ver, diff));
+ INSIST(tuple == NULL);
+ }
+ dns_rdata_reset(&rdata);
+ }
+ if (result != ISC_R_NOMORE)
+ goto failure;
+ success:
+ result = ISC_R_SUCCESS;
+
+ failure:
+ if (dns_rdataset_isassociated(&rdataset))
+ dns_rdataset_disassociate(&rdataset);
+ dns_db_detachnode(db, &node);
+ return (result);
+}
+#endif
+
+isc_result_t
+dns_nsec3_addnsec3sx(dns_db_t *db, dns_dbversion_t *version,
+ dns_name_t *name, dns_ttl_t nsecttl,
+ isc_boolean_t unsecure, dns_rdatatype_t type,
+ dns_diff_t *diff)
+{
+ dns_dbnode_t *node = NULL;
+ dns_rdata_nsec3param_t nsec3param;
+ dns_rdataset_t rdataset;
+ dns_rdataset_t prdataset;
+ isc_result_t result;
+
+ dns_rdataset_init(&rdataset);
+ dns_rdataset_init(&prdataset);
+
+ /*
+ * Find the NSEC3 parameters for this zone.
+ */
+ result = dns_db_getoriginnode(db, &node);
+ if (result != ISC_R_SUCCESS)
+ return (result);
+
+ result = dns_db_findrdataset(db, node, version, type, 0, 0,
+ &prdataset, NULL);
+ if (result != ISC_R_SUCCESS && result != ISC_R_NOTFOUND)
+ goto failure;
+
+ result = dns_db_findrdataset(db, node, version,
+ dns_rdatatype_nsec3param, 0, 0,
+ &rdataset, NULL);
+ if (result == ISC_R_NOTFOUND)
+ goto try_private;
+ if (result != ISC_R_SUCCESS)
+ goto failure;
+
+ /*
+ * Update each active NSEC3 chain.
+ */
+ for (result = dns_rdataset_first(&rdataset);
+ result == ISC_R_SUCCESS;
+ result = dns_rdataset_next(&rdataset)) {
+ dns_rdata_t rdata = DNS_RDATA_INIT;
+
+ dns_rdataset_current(&rdataset, &rdata);
+ CHECK(dns_rdata_tostruct(&rdata, &nsec3param, NULL));
-#ifdef RFC5155_STRICT
if (nsec3param.flags != 0)
continue;
-#else
+
+ /*
+ * We have a active chain. Update it.
+ */
+ CHECK(dns_nsec3_addnsec3(db, version, name, &nsec3param,
+ nsecttl, unsecure, diff));
+ }
+ if (result != ISC_R_NOMORE)
+ goto failure;
+
+ dns_rdataset_disassociate(&rdataset);
+
+ try_private:
+ if (!dns_rdataset_isassociated(&prdataset))
+ goto success;
+ /*
+ * Update each active NSEC3 chain.
+ */
+ for (result = dns_rdataset_first(&prdataset);
+ result == ISC_R_SUCCESS;
+ result = dns_rdataset_next(&prdataset)) {
+ dns_rdata_t rdata1 = DNS_RDATA_INIT;
+ dns_rdata_t rdata2 = DNS_RDATA_INIT;
+ unsigned char buf[DNS_NSEC3PARAM_BUFFERSIZE];
+
+ dns_rdataset_current(&prdataset, &rdata1);
+ if (!dns_nsec3param_fromprivate(&rdata1, &rdata2,
+ buf, sizeof(buf)))
+ continue;
+ CHECK(dns_rdata_tostruct(&rdata2, &nsec3param, NULL));
+
if ((nsec3param.flags & DNS_NSEC3FLAG_REMOVE) != 0)
continue;
- if (better_param(&rdataset, &rdata))
+ if (better_param(&prdataset, &rdata2))
continue;
-#endif
/*
* We have a active chain. Update it.
@@ -947,11 +1260,13 @@ dns_nsec3_addnsec3s(dns_db_t *db, dns_dbversion_t *version,
nsecttl, unsecure, diff));
}
if (result == ISC_R_NOMORE)
+ success:
result = ISC_R_SUCCESS;
-
failure:
if (dns_rdataset_isassociated(&rdataset))
dns_rdataset_disassociate(&rdataset);
+ if (dns_rdataset_isassociated(&prdataset))
+ dns_rdataset_disassociate(&prdataset);
if (node != NULL)
dns_db_detachnode(db, &node);
@@ -1120,6 +1435,8 @@ dns_nsec3_delnsec3(dns_db_t *db, dns_dbversion_t *version, dns_name_t *name,
*/
nsec3.next = nexthash;
nsec3.next_length = next_length;
+ if (CREATE(nsec3param->flags))
+ nsec3.flags = nsec3param->flags & DNS_NSEC3FLAG_OPTOUT;
isc_buffer_init(&buffer, nsec3buf, sizeof(nsec3buf));
CHECK(dns_rdata_fromstruct(&rdata, rdataset.rdclass,
dns_rdatatype_nsec3, &nsec3,
@@ -1257,6 +1574,13 @@ isc_result_t
dns_nsec3_delnsec3s(dns_db_t *db, dns_dbversion_t *version, dns_name_t *name,
dns_diff_t *diff)
{
+ return (dns_nsec3_delnsec3sx(db, version, name, 0, diff));
+}
+
+isc_result_t
+dns_nsec3_delnsec3sx(dns_db_t *db, dns_dbversion_t *version, dns_name_t *name,
+ dns_rdatatype_t privatetype, dns_diff_t *diff)
+{
dns_dbnode_t *node = NULL;
dns_rdata_nsec3param_t nsec3param;
dns_rdataset_t rdataset;
@@ -1274,11 +1598,10 @@ dns_nsec3_delnsec3s(dns_db_t *db, dns_dbversion_t *version, dns_name_t *name,
result = dns_db_findrdataset(db, node, version,
dns_rdatatype_nsec3param, 0, 0,
&rdataset, NULL);
- dns_db_detachnode(db, &node);
if (result == ISC_R_NOTFOUND)
- return (ISC_R_SUCCESS);
+ goto try_private;
if (result != ISC_R_SUCCESS)
- return (result);
+ goto failure;
/*
* Update each active NSEC3 chain.
@@ -1289,17 +1612,47 @@ dns_nsec3_delnsec3s(dns_db_t *db, dns_dbversion_t *version, dns_name_t *name,
dns_rdata_t rdata = DNS_RDATA_INIT;
dns_rdataset_current(&rdataset, &rdata);
- dns_rdata_tostruct(&rdata, &nsec3param, NULL);
+ CHECK(dns_rdata_tostruct(&rdata, &nsec3param, NULL));
-#ifdef RFC5155_STRICT
if (nsec3param.flags != 0)
continue;
-#else
+ /*
+ * We have a active chain. Update it.
+ */
+ CHECK(dns_nsec3_delnsec3(db, version, name, &nsec3param, diff));
+ }
+ dns_rdataset_disassociate(&rdataset);
+
+ try_private:
+ if (privatetype == 0)
+ goto success;
+ result = dns_db_findrdataset(db, node, version, privatetype, 0, 0,
+ &rdataset, NULL);
+ if (result == ISC_R_NOTFOUND)
+ goto success;
+ if (result != ISC_R_SUCCESS)
+ goto failure;
+
+ /*
+ * Update each NSEC3 chain being built.
+ */
+ for (result = dns_rdataset_first(&rdataset);
+ result == ISC_R_SUCCESS;
+ result = dns_rdataset_next(&rdataset)) {
+ dns_rdata_t rdata1 = DNS_RDATA_INIT;
+ dns_rdata_t rdata2 = DNS_RDATA_INIT;
+ unsigned char buf[DNS_NSEC3PARAM_BUFFERSIZE];
+
+ dns_rdataset_current(&rdataset, &rdata1);
+ if (!dns_nsec3param_fromprivate(&rdata1, &rdata2,
+ buf, sizeof(buf)))
+ continue;
+ CHECK(dns_rdata_tostruct(&rdata2, &nsec3param, NULL));
+
if ((nsec3param.flags & DNS_NSEC3FLAG_REMOVE) != 0)
continue;
- if (better_param(&rdataset, &rdata))
+ if (better_param(&rdataset, &rdata2))
continue;
-#endif
/*
* We have a active chain. Update it.
@@ -1307,6 +1660,7 @@ dns_nsec3_delnsec3s(dns_db_t *db, dns_dbversion_t *version, dns_name_t *name,
CHECK(dns_nsec3_delnsec3(db, version, name, &nsec3param, diff));
}
if (result == ISC_R_NOMORE)
+ success:
result = ISC_R_SUCCESS;
failure:
@@ -1322,6 +1676,14 @@ isc_result_t
dns_nsec3_active(dns_db_t *db, dns_dbversion_t *version,
isc_boolean_t complete, isc_boolean_t *answer)
{
+ return (dns_nsec3_activex(db, version, complete, 0, answer));
+}
+
+isc_result_t
+dns_nsec3_activex(dns_db_t *db, dns_dbversion_t *version,
+ isc_boolean_t complete, dns_rdatatype_t privatetype,
+ isc_boolean_t *answer)
+{
dns_dbnode_t *node = NULL;
dns_rdataset_t rdataset;
dns_rdata_nsec3param_t nsec3param;
@@ -1338,34 +1700,78 @@ dns_nsec3_active(dns_db_t *db, dns_dbversion_t *version,
result = dns_db_findrdataset(db, node, version,
dns_rdatatype_nsec3param, 0, 0,
&rdataset, NULL);
- dns_db_detachnode(db, &node);
+ if (result == ISC_R_NOTFOUND)
+ goto try_private;
+
+ if (result != ISC_R_SUCCESS) {
+ dns_db_detachnode(db, &node);
+ return (result);
+ }
+ for (result = dns_rdataset_first(&rdataset);
+ result == ISC_R_SUCCESS;
+ result = dns_rdataset_next(&rdataset)) {
+ dns_rdata_t rdata = DNS_RDATA_INIT;
+
+ dns_rdataset_current(&rdataset, &rdata);
+ result = dns_rdata_tostruct(&rdata, &nsec3param, NULL);
+ RUNTIME_CHECK(result == ISC_R_SUCCESS);
+
+ if (nsec3param.flags == 0)
+ break;
+ }
+ dns_rdataset_disassociate(&rdataset);
+ if (result == ISC_R_SUCCESS) {
+ dns_db_detachnode(db, &node);
+ *answer = ISC_TRUE;
+ return (ISC_R_SUCCESS);
+ }
+ if (result == ISC_R_NOMORE)
+ *answer = ISC_FALSE;
+
+ try_private:
+ if (privatetype == 0 || complete) {
+ *answer = ISC_FALSE;
+ return (ISC_R_SUCCESS);
+ }
+ result = dns_db_findrdataset(db, node, version, privatetype, 0, 0,
+ &rdataset, NULL);
+
+ dns_db_detachnode(db, &node);
if (result == ISC_R_NOTFOUND) {
*answer = ISC_FALSE;
return (ISC_R_SUCCESS);
}
if (result != ISC_R_SUCCESS)
return (result);
+
for (result = dns_rdataset_first(&rdataset);
result == ISC_R_SUCCESS;
result = dns_rdataset_next(&rdataset)) {
- dns_rdata_t rdata = DNS_RDATA_INIT;
+ dns_rdata_t rdata1 = DNS_RDATA_INIT;
+ dns_rdata_t rdata2 = DNS_RDATA_INIT;
+ unsigned char buf[DNS_NSEC3PARAM_BUFFERSIZE];
- dns_rdataset_current(&rdataset, &rdata);
- result = dns_rdata_tostruct(&rdata, &nsec3param, NULL);
+ dns_rdataset_current(&rdataset, &rdata1);
+ if (!dns_nsec3param_fromprivate(&rdata1, &rdata2,
+ buf, sizeof(buf)))
+ continue;
+ result = dns_rdata_tostruct(&rdata2, &nsec3param, NULL);
RUNTIME_CHECK(result == ISC_R_SUCCESS);
- if ((nsec3param.flags) == 0 ||
- (!complete && CREATE(nsec3param.flags)))
+ if (!complete && CREATE(nsec3param.flags))
break;
}
dns_rdataset_disassociate(&rdataset);
- if (result == ISC_R_SUCCESS)
+ if (result == ISC_R_SUCCESS) {
*answer = ISC_TRUE;
+ result = ISC_R_SUCCESS;
+ }
if (result == ISC_R_NOMORE) {
*answer = ISC_FALSE;
result = ISC_R_SUCCESS;
}
+
return (result);
}
OpenPOWER on IntegriCloud