mirror of
https://gitlab.isc.org/isc-projects/bind9
synced 2025-08-29 13:38:26 +00:00
2349. [func] Provide incremental re-signing support for secure
dynamic zones. [RT #1091]
This commit is contained in:
parent
28b3569d62
commit
a76b380643
3
CHANGES
3
CHANGES
@ -1,3 +1,6 @@
|
||||
2349. [func] Provide incremental re-signing support for secure
|
||||
dynamic zones. [RT #1091]
|
||||
|
||||
2348. [func] Use the EVP interface to OpenSSL. Add PKCS#11 support.
|
||||
Documentation is in the new README.pkcs11 file.
|
||||
[RT #16844]
|
||||
|
@ -15,7 +15,7 @@
|
||||
* PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
/* $Id: query.c,v 1.303 2008/01/24 02:00:43 jinmei Exp $ */
|
||||
/* $Id: query.c,v 1.304 2008/04/01 01:37:24 marka Exp $ */
|
||||
|
||||
/*! \file */
|
||||
|
||||
@ -1087,8 +1087,12 @@ query_addadditional(void *arg, dns_name_t *name, dns_rdatatype_t qtype) {
|
||||
result = dns_db_find(db, name, version, type, client->query.dboptions,
|
||||
client->now, &node, fname, rdataset,
|
||||
sigrdataset);
|
||||
if (result == ISC_R_SUCCESS)
|
||||
if (result == ISC_R_SUCCESS) {
|
||||
if (sigrdataset != NULL && !dns_db_issecure(db) &&
|
||||
dns_rdataset_isassociated(sigrdataset))
|
||||
dns_rdataset_disassociate(sigrdataset);
|
||||
goto found;
|
||||
}
|
||||
|
||||
if (dns_rdataset_isassociated(rdataset))
|
||||
dns_rdataset_disassociate(rdataset);
|
||||
@ -2025,7 +2029,7 @@ query_addsoa(ns_client_t *client, dns_db_t *db, dns_dbversion_t *version,
|
||||
eresult = DNS_R_SERVFAIL;
|
||||
goto cleanup;
|
||||
}
|
||||
if (WANTDNSSEC(client)) {
|
||||
if (WANTDNSSEC(client) && dns_db_issecure(db)) {
|
||||
sigrdataset = query_newrdataset(client);
|
||||
if (sigrdataset == NULL) {
|
||||
eresult = DNS_R_SERVFAIL;
|
||||
@ -2143,7 +2147,7 @@ query_addns(ns_client_t *client, dns_db_t *db, dns_dbversion_t *version) {
|
||||
eresult = DNS_R_SERVFAIL;
|
||||
goto cleanup;
|
||||
}
|
||||
if (WANTDNSSEC(client)) {
|
||||
if (WANTDNSSEC(client) && dns_db_issecure(db)) {
|
||||
sigrdataset = query_newrdataset(client);
|
||||
if (sigrdataset == NULL) {
|
||||
CTRACE("query_addns: query_newrdataset failed");
|
||||
@ -3534,7 +3538,7 @@ query_find(ns_client_t *client, dns_fetchevent_t *event, dns_rdatatype_t qtype)
|
||||
QUERY_ERROR(DNS_R_SERVFAIL);
|
||||
goto cleanup;
|
||||
}
|
||||
if (WANTDNSSEC(client)) {
|
||||
if (WANTDNSSEC(client) && (!is_zone || dns_db_issecure(db))) {
|
||||
sigrdataset = query_newrdataset(client);
|
||||
if (sigrdataset == NULL) {
|
||||
QUERY_ERROR(DNS_R_SERVFAIL);
|
||||
@ -4173,7 +4177,16 @@ query_find(ns_client_t *client, dns_fetchevent_t *event, dns_rdatatype_t qtype)
|
||||
result = dns_rdatasetiter_first(rdsiter);
|
||||
while (result == ISC_R_SUCCESS) {
|
||||
dns_rdatasetiter_current(rdsiter, rdataset);
|
||||
if ((qtype == dns_rdatatype_any ||
|
||||
if (is_zone && qtype == dns_rdatatype_any &&
|
||||
!dns_db_issecure(db) &&
|
||||
dns_rdatatype_isdnssec(rdataset->type)) {
|
||||
/*
|
||||
* The zone is transitioning from insecure
|
||||
* to secure. Hide the dnssec records from
|
||||
* ANY queries.
|
||||
*/
|
||||
dns_rdataset_disassociate(rdataset);
|
||||
} else if ((qtype == dns_rdatatype_any ||
|
||||
rdataset->type == qtype) && rdataset->type != 0) {
|
||||
query_addrrset(client,
|
||||
fname != NULL ? &fname : &tname,
|
||||
|
@ -15,12 +15,13 @@
|
||||
* PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
/* $Id: update.c,v 1.142 2008/02/07 03:12:15 marka Exp $ */
|
||||
/* $Id: update.c,v 1.143 2008/04/01 01:37:24 marka Exp $ */
|
||||
|
||||
#include <config.h>
|
||||
|
||||
#include <isc/netaddr.h>
|
||||
#include <isc/print.h>
|
||||
#include <isc/serial.h>
|
||||
#include <isc/string.h>
|
||||
#include <isc/taskpool.h>
|
||||
#include <isc/util.h>
|
||||
@ -1063,9 +1064,17 @@ rr_equal_p(dns_rdata_t *update_rr, dns_rdata_t *db_rr) {
|
||||
*
|
||||
* RFC2136 does not mention NSEC or DNAME, but multiple NSECs or DNAMEs
|
||||
* make little sense, so we replace those, too.
|
||||
*
|
||||
* Additionally replace RRSIG that have been generated by the same key
|
||||
* for the same type. This simplifies refreshing a offline KSK by not
|
||||
* requiring that the old RRSIG be deleted. It also simpifies key
|
||||
* rollover by only requiring that the new RRSIG be added.
|
||||
*/
|
||||
static isc_boolean_t
|
||||
replaces_p(dns_rdata_t *update_rr, dns_rdata_t *db_rr) {
|
||||
dns_rdata_rrsig_t updatesig, dbsig;
|
||||
isc_result_t result;
|
||||
|
||||
if (db_rr->type != update_rr->type)
|
||||
return (ISC_FALSE);
|
||||
if (db_rr->type == dns_rdatatype_cname)
|
||||
@ -1076,6 +1085,20 @@ replaces_p(dns_rdata_t *update_rr, dns_rdata_t *db_rr) {
|
||||
return (ISC_TRUE);
|
||||
if (db_rr->type == dns_rdatatype_nsec)
|
||||
return (ISC_TRUE);
|
||||
if (db_rr->type == dns_rdatatype_rrsig) {
|
||||
/*
|
||||
* Replace existing RRSIG with the same keyid,
|
||||
* covered and algorithm.
|
||||
*/
|
||||
result = dns_rdata_tostruct(db_rr, &dbsig, NULL);
|
||||
RUNTIME_CHECK(result == ISC_R_SUCCESS);
|
||||
result = dns_rdata_tostruct(update_rr, &updatesig, NULL);
|
||||
RUNTIME_CHECK(result == ISC_R_SUCCESS);
|
||||
if (dbsig.keyid == updatesig.keyid &&
|
||||
dbsig.covered == updatesig.covered &&
|
||||
dbsig.algorithm == updatesig.algorithm)
|
||||
return (ISC_TRUE);
|
||||
}
|
||||
if (db_rr->type == dns_rdatatype_wks) {
|
||||
/*
|
||||
* Compare the address and protocol fields only. These
|
||||
@ -1493,6 +1516,7 @@ next_active(ns_client_t *client, dns_zone_t *zone, dns_db_t *db,
|
||||
dns_dbiterator_t *dbit = NULL;
|
||||
isc_boolean_t has_nsec;
|
||||
unsigned int wraps = 0;
|
||||
isc_boolean_t secure = dns_db_issecure(db);
|
||||
|
||||
CHECK(dns_db_createiterator(db, ISC_FALSE, &dbit));
|
||||
|
||||
@ -1530,9 +1554,29 @@ next_active(ns_client_t *client, dns_zone_t *zone, dns_db_t *db,
|
||||
* we must pause the iterator first.
|
||||
*/
|
||||
CHECK(dns_dbiterator_pause(dbit));
|
||||
if (secure) {
|
||||
CHECK(rrset_exists(db, ver, newname,
|
||||
dns_rdatatype_nsec, 0, &has_nsec));
|
||||
|
||||
} else {
|
||||
dns_fixedname_t ffound;
|
||||
dns_name_t *found;
|
||||
dns_fixedname_init(&ffound);
|
||||
found = dns_fixedname_name(&ffound);
|
||||
result = dns_db_find(db, newname, ver,
|
||||
dns_rdatatype_soa,
|
||||
DNS_DBFIND_NOWILD, 0, NULL, found,
|
||||
NULL, NULL);
|
||||
if (result == ISC_R_SUCCESS ||
|
||||
result == DNS_R_EMPTYNAME ||
|
||||
result == DNS_R_NXRRSET ||
|
||||
result == DNS_R_CNAME ||
|
||||
(result == DNS_R_DELEGATION &&
|
||||
dns_name_equal(newname, found))) {
|
||||
has_nsec = ISC_TRUE;
|
||||
result = ISC_R_SUCCESS;
|
||||
} else if (result != DNS_R_NXDOMAIN)
|
||||
break;
|
||||
}
|
||||
} while (! has_nsec);
|
||||
failure:
|
||||
if (dbit != NULL)
|
||||
@ -1541,6 +1585,35 @@ next_active(ns_client_t *client, dns_zone_t *zone, dns_db_t *db,
|
||||
return (result);
|
||||
}
|
||||
|
||||
static isc_boolean_t
|
||||
has_opt_bit(dns_db_t *db, dns_dbversion_t *version, dns_dbnode_t *node) {
|
||||
isc_result_t result;
|
||||
dns_rdata_t rdata = DNS_RDATA_INIT;
|
||||
dns_rdataset_t rdataset;
|
||||
isc_boolean_t has_bit = ISC_FALSE;
|
||||
|
||||
dns_rdataset_init(&rdataset);
|
||||
CHECK(dns_db_findrdataset(db, node, version, dns_rdatatype_nsec,
|
||||
dns_rdatatype_none, 0, &rdataset, NULL));
|
||||
CHECK(dns_rdataset_first(&rdataset));
|
||||
dns_rdataset_current(&rdataset, &rdata);
|
||||
has_bit = dns_nsec_typepresent(&rdata, dns_rdatatype_opt);
|
||||
failure:
|
||||
if (dns_rdataset_isassociated(&rdataset))
|
||||
dns_rdataset_disassociate(&rdataset);
|
||||
return (has_bit);
|
||||
}
|
||||
|
||||
static void
|
||||
set_bit(unsigned char *array, unsigned int index) {
|
||||
unsigned int shift, mask;
|
||||
|
||||
shift = 7 - (index % 8);
|
||||
mask = 1 << shift;
|
||||
|
||||
array[index / 8] |= mask;
|
||||
}
|
||||
|
||||
/*%
|
||||
* Add a NSEC record for "name", recording the change in "diff".
|
||||
* The existing NSEC is removed.
|
||||
@ -1572,6 +1645,24 @@ add_nsec(ns_client_t *client, dns_zone_t *zone, dns_db_t *db,
|
||||
CHECK(dns_db_findnode(db, name, ISC_FALSE, &node));
|
||||
dns_rdata_init(&rdata);
|
||||
CHECK(dns_nsec_buildrdata(db, ver, node, target, buffer, &rdata));
|
||||
/*
|
||||
* Preserve the status of the OPT bit in the origin's NSEC record.
|
||||
*/
|
||||
if (dns_name_equal(dns_db_origin(db), name) &&
|
||||
has_opt_bit(db, ver, node))
|
||||
{
|
||||
isc_region_t region;
|
||||
dns_name_t next;
|
||||
|
||||
dns_name_init(&next, NULL);
|
||||
dns_rdata_toregion(&rdata, ®ion);
|
||||
dns_name_fromregion(&next, ®ion);
|
||||
isc_region_consume(®ion, next.length);
|
||||
INSIST(region.length > (2 + dns_rdatatype_opt / 8) &&
|
||||
region.base[0] == 0 &&
|
||||
region.base[1] > dns_rdatatype_opt / 8);
|
||||
set_bit(region.base + 2, dns_rdatatype_opt);
|
||||
}
|
||||
dns_db_detachnode(db, &node);
|
||||
|
||||
/*
|
||||
@ -1715,7 +1806,7 @@ add_sigs(ns_client_t *client, dns_zone_t *zone, dns_db_t *db,
|
||||
|
||||
/* Update the database and journal with the RRSIG. */
|
||||
/* XXX inefficient - will cause dataset merging */
|
||||
CHECK(update_one_rr(db, ver, diff, DNS_DIFFOP_ADD, name,
|
||||
CHECK(update_one_rr(db, ver, diff, DNS_DIFFOP_ADDRESIGN, name,
|
||||
rdataset.ttl, &sig_rdata));
|
||||
dns_rdata_reset(&sig_rdata);
|
||||
added_sig = ISC_TRUE;
|
||||
@ -1735,6 +1826,84 @@ add_sigs(ns_client_t *client, dns_zone_t *zone, dns_db_t *db,
|
||||
return (result);
|
||||
}
|
||||
|
||||
/*
|
||||
* Delete expired RRsigs and any RRsigs we are about to re-sign.
|
||||
* See also zone.c:del_sigs().
|
||||
*/
|
||||
static isc_result_t
|
||||
del_keysigs(dns_db_t *db, dns_dbversion_t *ver, dns_name_t *name,
|
||||
dns_diff_t *diff, dst_key_t **keys, unsigned int nkeys)
|
||||
{
|
||||
isc_result_t result;
|
||||
dns_dbnode_t *node = NULL;
|
||||
dns_rdataset_t rdataset;
|
||||
dns_rdata_t rdata = DNS_RDATA_INIT;
|
||||
unsigned int i;
|
||||
dns_rdata_rrsig_t rrsig;
|
||||
isc_boolean_t found;
|
||||
|
||||
fprintf(stderr, "del_keysigs\n");
|
||||
|
||||
dns_rdataset_init(&rdataset);
|
||||
|
||||
result = dns_db_findnode(db, name, ISC_FALSE, &node);
|
||||
if (result == ISC_R_NOTFOUND)
|
||||
return (ISC_R_SUCCESS);
|
||||
if (result != ISC_R_SUCCESS)
|
||||
goto failure;
|
||||
result = dns_db_findrdataset(db, node, ver, dns_rdatatype_rrsig,
|
||||
dns_rdatatype_dnskey, (isc_stdtime_t) 0,
|
||||
&rdataset, NULL);
|
||||
dns_db_detachnode(db, &node);
|
||||
|
||||
if (result == ISC_R_NOTFOUND)
|
||||
return (ISC_R_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);
|
||||
result = dns_rdata_tostruct(&rdata, &rrsig, NULL);
|
||||
RUNTIME_CHECK(result == ISC_R_SUCCESS);
|
||||
found = ISC_FALSE;
|
||||
for (i = 0; i < nkeys; i++) {
|
||||
if (rrsig.keyid == dst_key_id(keys[i])) {
|
||||
found = ISC_TRUE;
|
||||
if (!dst_key_isprivate(keys[i])) {
|
||||
/*
|
||||
* The re-signing code in zone.c
|
||||
* will mark this as offline.
|
||||
* Just skip the record for now.
|
||||
*/
|
||||
break;
|
||||
}
|
||||
result = update_one_rr(db, ver, diff,
|
||||
DNS_DIFFOP_DEL, name,
|
||||
rdataset.ttl, &rdata);
|
||||
break;
|
||||
}
|
||||
}
|
||||
/*
|
||||
* If there is not a matching DNSKEY then delete the RRSIG.
|
||||
*/
|
||||
if (!found)
|
||||
result = update_one_rr(db, ver, diff, DNS_DIFFOP_DEL,
|
||||
name, rdataset.ttl, &rdata);
|
||||
dns_rdata_reset(&rdata);
|
||||
if (result != ISC_R_SUCCESS)
|
||||
break;
|
||||
}
|
||||
dns_rdataset_disassociate(&rdataset);
|
||||
if (result == ISC_R_NOMORE)
|
||||
result = ISC_R_SUCCESS;
|
||||
failure:
|
||||
if (node != NULL)
|
||||
dns_db_detachnode(db, &node);
|
||||
return (result);
|
||||
}
|
||||
|
||||
/*%
|
||||
* Update RRSIG and NSEC records affected by an update. The original
|
||||
* update, including the SOA serial update but exluding the RRSIG & NSEC
|
||||
@ -1749,7 +1918,8 @@ add_sigs(ns_client_t *client, dns_zone_t *zone, dns_db_t *db,
|
||||
static isc_result_t
|
||||
update_signatures(ns_client_t *client, dns_zone_t *zone, dns_db_t *db,
|
||||
dns_dbversion_t *oldver, dns_dbversion_t *newver,
|
||||
dns_diff_t *diff, isc_uint32_t sigvalidityinterval)
|
||||
dns_diff_t *diff, isc_uint32_t sigvalidityinterval,
|
||||
isc_boolean_t *deleted_zsk)
|
||||
{
|
||||
isc_result_t result;
|
||||
dns_difftuple_t *t;
|
||||
@ -1797,8 +1967,27 @@ update_signatures(ns_client_t *client, dns_zone_t *zone, dns_db_t *db,
|
||||
*/
|
||||
check_ksk = ISC_TF((dns_zone_getoptions(zone) &
|
||||
DNS_ZONEOPT_UPDATECHECKKSK) != 0);
|
||||
if (check_ksk)
|
||||
/*
|
||||
* If we are not checking the ZSK flag then all DNSKEY's are
|
||||
* already signing all RRsets so we don't need to trigger special
|
||||
* changes.
|
||||
*/
|
||||
if (*deleted_zsk && (!check_ksk || !ksk_sanity(db, oldver)))
|
||||
*deleted_zsk = ISC_FALSE;
|
||||
|
||||
if (check_ksk) {
|
||||
check_ksk = ksk_sanity(db, newver);
|
||||
if (!check_ksk && ksk_sanity(db, oldver))
|
||||
update_log(client, zone, ISC_LOG_WARNING,
|
||||
"disabling update-check-ksk");
|
||||
}
|
||||
|
||||
/*
|
||||
* If we have deleted a ZSK and we we still have some ZSK's
|
||||
* we don't need to convert the KSK's to a ZSK's.
|
||||
*/
|
||||
if (*deleted_zsk && check_ksk)
|
||||
*deleted_zsk = ISC_FALSE;
|
||||
|
||||
/*
|
||||
* Get the NSEC's TTL from the SOA MINIMUM field.
|
||||
@ -1845,7 +2034,14 @@ update_signatures(ns_client_t *client, dns_zone_t *zone, dns_db_t *db,
|
||||
* Delete all old RRSIGs covering this type, since they
|
||||
* are all invalid when the signed RRset has changed.
|
||||
* We may not be able to recreate all of them - tough.
|
||||
* Special case changes to the zone's DNSKEY records
|
||||
* to support offline KSKs.
|
||||
*/
|
||||
fprintf(stderr, "delete signatures %u\n", type);
|
||||
if (type == dns_rdatatype_dnskey)
|
||||
del_keysigs(db, newver, name, &sig_diff,
|
||||
zone_keys, nkeys);
|
||||
else
|
||||
CHECK(delete_if(true_p, db, newver, name,
|
||||
dns_rdatatype_rrsig, type,
|
||||
NULL, &sig_diff));
|
||||
@ -2349,6 +2545,52 @@ check_mx(ns_client_t *client, dns_zone_t *zone,
|
||||
return (ok ? ISC_R_SUCCESS : DNS_R_REFUSED);
|
||||
}
|
||||
|
||||
static isc_result_t
|
||||
add_signing_records(dns_db_t *db, dns_name_t *name, dns_dbversion_t *ver,
|
||||
dns_diff_t *diff)
|
||||
{
|
||||
isc_result_t result = ISC_R_SUCCESS;
|
||||
dns_difftuple_t *tuple, *newtuple = NULL;
|
||||
dns_rdata_dnskey_t dnskey;
|
||||
dns_rdata_t rdata = DNS_RDATA_INIT;
|
||||
unsigned char buf[4];
|
||||
isc_region_t r;
|
||||
isc_uint16_t keyid;
|
||||
|
||||
for (tuple = ISC_LIST_HEAD(diff->tuples);
|
||||
tuple != NULL;
|
||||
tuple = ISC_LIST_NEXT(tuple, link)) {
|
||||
if (tuple->rdata.type != dns_rdatatype_dnskey ||
|
||||
tuple->op != DNS_DIFFOP_ADD)
|
||||
continue;
|
||||
|
||||
dns_rdata_tostruct(&tuple->rdata, &dnskey, NULL);
|
||||
if ((dnskey.flags &
|
||||
(DNS_KEYFLAG_OWNERMASK|DNS_KEYTYPE_NOAUTH))
|
||||
!= DNS_KEYOWNER_ZONE)
|
||||
continue;
|
||||
|
||||
dns_rdata_toregion(&tuple->rdata, &r);
|
||||
keyid = dst_region_computeid(&r, dnskey.algorithm);
|
||||
|
||||
buf[0] = dnskey.algorithm;
|
||||
buf[1] = (keyid & 0xff00) >> 8;
|
||||
buf[2] = (keyid & 0xff);
|
||||
buf[3] = 0;
|
||||
rdata.data = buf;
|
||||
rdata.length = sizeof(buf);
|
||||
rdata.type = 0xFFFF; /* XXXMPA make user settable */
|
||||
rdata.rdclass = tuple->rdata.rdclass;
|
||||
|
||||
CHECK(dns_difftuple_create(diff->mctx, DNS_DIFFOP_ADD, name,
|
||||
0, &rdata, &newtuple));
|
||||
CHECK(do_one_tuple(&newtuple, db, ver, diff));
|
||||
INSIST(newtuple == NULL);
|
||||
}
|
||||
failure:
|
||||
return (result);
|
||||
}
|
||||
|
||||
static void
|
||||
update_action(isc_task_t *task, isc_event_t *event) {
|
||||
update_event_t *uev = (update_event_t *) event;
|
||||
@ -2371,6 +2613,9 @@ update_action(isc_task_t *task, isc_event_t *event) {
|
||||
dns_fixedname_t tmpnamefixed;
|
||||
dns_name_t *tmpname = NULL;
|
||||
unsigned int options;
|
||||
isc_boolean_t deleted_zsk;
|
||||
dns_difftuple_t *tuple;
|
||||
dns_rdata_dnskey_t dnskey;
|
||||
|
||||
INSIST(event->ev_type == DNS_EVENT_UPDATE);
|
||||
|
||||
@ -2567,16 +2812,18 @@ update_action(isc_task_t *task, isc_event_t *event) {
|
||||
* "Unlike traditional dynamic update, the client
|
||||
* is forbidden from updating NSEC records."
|
||||
*/
|
||||
if (dns_db_issecure(db)) {
|
||||
if (dns_db_isdnssec(db)) {
|
||||
if (rdata.type == dns_rdatatype_nsec) {
|
||||
FAILC(DNS_R_REFUSED,
|
||||
"explicit NSEC updates are not allowed "
|
||||
"in secure zones");
|
||||
}
|
||||
else if (rdata.type == dns_rdatatype_rrsig) {
|
||||
else if (rdata.type == dns_rdatatype_rrsig &&
|
||||
!dns_name_equal(name, zonename)) {
|
||||
FAILC(DNS_R_REFUSED,
|
||||
"explicit RRSIG updates are currently "
|
||||
"not supported in secure zones");
|
||||
"not supported in secure zones except "
|
||||
"at the apex.");
|
||||
}
|
||||
}
|
||||
|
||||
@ -2852,6 +3099,7 @@ update_action(isc_task_t *task, isc_event_t *event) {
|
||||
if (! ISC_LIST_EMPTY(diff.tuples)) {
|
||||
char *journalfile;
|
||||
dns_journal_t *journal;
|
||||
isc_boolean_t has_dnskey;
|
||||
|
||||
/*
|
||||
* Increment the SOA serial, but only if it was not
|
||||
@ -2865,10 +3113,17 @@ update_action(isc_task_t *task, isc_event_t *event) {
|
||||
|
||||
CHECK(remove_orphaned_ds(db, ver, &diff));
|
||||
|
||||
if (dns_db_issecure(db)) {
|
||||
CHECK(add_signing_records(db, zonename, ver, &diff));
|
||||
|
||||
CHECK(rrset_exists(db, ver, zonename, dns_rdatatype_dnskey,
|
||||
0, &has_dnskey));
|
||||
|
||||
if (has_dnskey && dns_db_isdnssec(db)) {
|
||||
isc_uint32_t interval;
|
||||
interval = dns_zone_getsigvalidityinterval(zone);
|
||||
result = update_signatures(client, zone, db, oldver,
|
||||
ver, &diff,
|
||||
dns_zone_getsigvalidityinterval(zone));
|
||||
ver, &diff, interval,
|
||||
&deleted_zsk);
|
||||
if (result != ISC_R_SUCCESS) {
|
||||
update_log(client, zone,
|
||||
ISC_LOG_ERROR,
|
||||
@ -2905,6 +3160,7 @@ update_action(isc_task_t *task, isc_event_t *event) {
|
||||
*/
|
||||
update_log(client, zone, LOGLEVEL_DEBUG,
|
||||
"committing update transaction");
|
||||
|
||||
dns_db_closeversion(db, &ver, ISC_TRUE);
|
||||
|
||||
/*
|
||||
@ -2916,6 +3172,35 @@ update_action(isc_task_t *task, isc_event_t *event) {
|
||||
* Notify slaves of the change we just made.
|
||||
*/
|
||||
dns_zone_notify(zone);
|
||||
|
||||
for (tuple = ISC_LIST_HEAD(diff.tuples);
|
||||
tuple != NULL;
|
||||
tuple = ISC_LIST_NEXT(tuple, link)) {
|
||||
isc_region_t r;
|
||||
dns_secalg_t algorithm;
|
||||
isc_uint16_t keyid;
|
||||
|
||||
if (tuple->rdata.type != dns_rdatatype_dnskey ||
|
||||
tuple->op != DNS_DIFFOP_ADD)
|
||||
continue;
|
||||
|
||||
dns_rdata_tostruct(&tuple->rdata, &dnskey, NULL);
|
||||
if ((dnskey.flags &
|
||||
(DNS_KEYFLAG_OWNERMASK|DNS_KEYTYPE_NOAUTH))
|
||||
!= DNS_KEYOWNER_ZONE)
|
||||
continue;
|
||||
|
||||
dns_rdata_toregion(&tuple->rdata, &r);
|
||||
algorithm = dnskey.algorithm;
|
||||
keyid = dst_region_computeid(&r, algorithm);
|
||||
|
||||
result = dns_zone_signwithkey(zone, algorithm, keyid);
|
||||
if (result != ISC_R_SUCCESS) {
|
||||
update_log(client, zone, ISC_LOG_ERROR,
|
||||
"dns_zone_signwithkey failed: %s",
|
||||
dns_result_totext(result));
|
||||
}
|
||||
}
|
||||
} else {
|
||||
update_log(client, zone, LOGLEVEL_DEBUG, "redundant request");
|
||||
dns_db_closeversion(db, &ver, ISC_TRUE);
|
||||
|
@ -15,7 +15,7 @@
|
||||
* PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
/* $Id: nsupdate.c,v 1.157 2008/01/18 23:46:57 tbox Exp $ */
|
||||
/* $Id: nsupdate.c,v 1.158 2008/04/01 01:37:24 marka Exp $ */
|
||||
|
||||
/*! \file */
|
||||
|
||||
@ -1032,7 +1032,7 @@ parse_rdata(char **cmdlinep, dns_rdataclass_t rdataclass,
|
||||
check_result(result, "isc_lex_openbuffer");
|
||||
result = isc_buffer_allocate(mctx, &buf, MAXWIRE);
|
||||
check_result(result, "isc_buffer_allocate");
|
||||
result = dns_rdata_fromtext(rdata, rdataclass, rdatatype, lex,
|
||||
result = dns_rdata_fromtext(NULL, rdataclass, rdatatype, lex,
|
||||
dns_rootname, 0, mctx, buf,
|
||||
&callbacks);
|
||||
isc_lex_destroy(&lex);
|
||||
|
@ -15,7 +15,7 @@
|
||||
* PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
/* $Id: check.c,v 1.89 2008/03/29 23:47:08 tbox Exp $ */
|
||||
/* $Id: check.c,v 1.90 2008/04/01 01:37:24 marka Exp $ */
|
||||
|
||||
/*! \file */
|
||||
|
||||
@ -654,6 +654,7 @@ check_options(const cfg_obj_t *options, isc_log_t *logctx, isc_mem_t *mctx) {
|
||||
if (tresult != ISC_R_SUCCESS &&
|
||||
result == ISC_R_SUCCESS)
|
||||
result = tresult;
|
||||
goto trust_anchor;
|
||||
}
|
||||
/*
|
||||
* XXXMPA to be removed when multiple lookaside
|
||||
@ -666,6 +667,7 @@ check_options(const cfg_obj_t *options, isc_log_t *logctx, isc_mem_t *mctx) {
|
||||
if (result == ISC_R_SUCCESS)
|
||||
result = ISC_R_FAILURE;
|
||||
}
|
||||
trust_anchor:
|
||||
dlv = cfg_obj_asstring(cfg_tuple_get(obj,
|
||||
"trust-anchor"));
|
||||
isc_buffer_init(&b, dlv, strlen(dlv));
|
||||
|
41
lib/dns/db.c
41
lib/dns/db.c
@ -15,7 +15,7 @@
|
||||
* PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
/* $Id: db.c,v 1.83 2007/06/18 23:47:40 tbox Exp $ */
|
||||
/* $Id: db.c,v 1.84 2008/04/01 01:37:24 marka Exp $ */
|
||||
|
||||
/*! \file */
|
||||
|
||||
@ -228,6 +228,21 @@ dns_db_isstub(dns_db_t *db) {
|
||||
return (ISC_FALSE);
|
||||
}
|
||||
|
||||
isc_boolean_t
|
||||
dns_db_isdnssec(dns_db_t *db) {
|
||||
|
||||
/*
|
||||
* Is 'db' secure or partially secure?
|
||||
*/
|
||||
|
||||
REQUIRE(DNS_DB_VALID(db));
|
||||
REQUIRE((db->attributes & DNS_DBATTR_CACHE) == 0);
|
||||
|
||||
if (db->methods->isdnssec != NULL)
|
||||
return ((db->methods->isdnssec)(db));
|
||||
return ((db->methods->issecure)(db));
|
||||
}
|
||||
|
||||
isc_boolean_t
|
||||
dns_db_issecure(dns_db_t *db) {
|
||||
|
||||
@ -843,3 +858,27 @@ dns_db_getoriginnode(dns_db_t *db, dns_dbnode_t **nodep) {
|
||||
|
||||
return (ISC_R_NOTFOUND);
|
||||
}
|
||||
|
||||
isc_result_t
|
||||
dns_db_setsigningtime(dns_db_t *db, dns_rdataset_t *rdataset,
|
||||
isc_stdtime_t resign)
|
||||
{
|
||||
if (db->methods->setsigningtime != NULL)
|
||||
return ((db->methods->setsigningtime)(db, rdataset, resign));
|
||||
return (ISC_R_NOTIMPLEMENTED);
|
||||
}
|
||||
|
||||
isc_result_t
|
||||
dns_db_getsigningtime(dns_db_t *db, dns_rdataset_t *rdataset, dns_name_t *name)
|
||||
{
|
||||
if (db->methods->getsigningtime != NULL)
|
||||
return ((db->methods->getsigningtime)(db, rdataset, name));
|
||||
return (ISC_R_NOTFOUND);
|
||||
}
|
||||
|
||||
void
|
||||
dns_db_resigned(dns_db_t *db, dns_rdataset_t *rdataset, dns_dbversion_t *version)
|
||||
{
|
||||
if (db->methods->resigned != NULL)
|
||||
return ((db->methods->resigned)(db, rdataset, version));
|
||||
}
|
||||
|
121
lib/dns/diff.c
121
lib/dns/diff.c
@ -15,7 +15,7 @@
|
||||
* PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
/* $Id: diff.c,v 1.14 2007/06/19 23:47:16 tbox Exp $ */
|
||||
/* $Id: diff.c,v 1.15 2008/04/01 01:37:24 marka Exp $ */
|
||||
|
||||
/*! \file */
|
||||
|
||||
@ -35,6 +35,7 @@
|
||||
#include <dns/rdataclass.h>
|
||||
#include <dns/rdatalist.h>
|
||||
#include <dns/rdataset.h>
|
||||
#include <dns/rdatastruct.h>
|
||||
#include <dns/rdatatype.h>
|
||||
#include <dns/result.h>
|
||||
|
||||
@ -192,6 +193,52 @@ dns_diff_appendminimal(dns_diff_t *diff, dns_difftuple_t **tuplep)
|
||||
ENSURE(*tuplep == NULL);
|
||||
}
|
||||
|
||||
static isc_stdtime_t
|
||||
setresign(dns_rdataset_t *modified, dns_diffop_t op) {
|
||||
dns_rdata_t rdata = DNS_RDATA_INIT;
|
||||
dns_rdata_rrsig_t sig;
|
||||
isc_stdtime_t when;
|
||||
unsigned int delta;
|
||||
isc_result_t result;
|
||||
|
||||
result = dns_rdataset_first(modified);
|
||||
INSIST(result == ISC_R_SUCCESS);
|
||||
dns_rdataset_current(modified, &rdata);
|
||||
(void)dns_rdata_tostruct(&rdata, &sig, NULL);
|
||||
if ((rdata.flags & DNS_RDATA_OFFLINE) != 0) {
|
||||
when = 0;
|
||||
} else {
|
||||
delta = (sig.timeexpire - sig.timesigned) * 3 / 4;
|
||||
when = sig.timesigned + delta;
|
||||
}
|
||||
dns_rdata_reset(&rdata);
|
||||
|
||||
result = dns_rdataset_next(modified);
|
||||
while (result == ISC_R_SUCCESS) {
|
||||
dns_rdataset_current(modified, &rdata);
|
||||
(void)dns_rdata_tostruct(&rdata, &sig, NULL);
|
||||
if ((rdata.flags & DNS_RDATA_OFFLINE) != 0) {
|
||||
goto next_rr;
|
||||
}
|
||||
delta = (sig.timeexpire - sig.timesigned)* 3 / 4;
|
||||
switch (op) {
|
||||
case DNS_DIFFOP_ADDRESIGN:
|
||||
case DNS_DIFFOP_DELRESIGN:
|
||||
if (when == 0 || sig.timesigned + delta < when)
|
||||
when = sig.timesigned + delta;
|
||||
break;
|
||||
default:
|
||||
INSIST(0);
|
||||
}
|
||||
next_rr:
|
||||
dns_rdata_reset(&rdata);
|
||||
result = dns_rdataset_next(modified);
|
||||
}
|
||||
INSIST(result == ISC_R_NOMORE);
|
||||
fprintf(stderr, "setresign %u %u\n", modified->covers, when);
|
||||
return (when);
|
||||
}
|
||||
|
||||
static isc_result_t
|
||||
diff_apply(dns_diff_t *diff, dns_db_t *db, dns_dbversion_t *ver,
|
||||
isc_boolean_t warn)
|
||||
@ -228,6 +275,9 @@ diff_apply(dns_diff_t *diff, dns_db_t *db, dns_dbversion_t *ver,
|
||||
dns_diffop_t op;
|
||||
dns_rdatalist_t rdl;
|
||||
dns_rdataset_t rds;
|
||||
dns_rdataset_t ardataset;
|
||||
dns_rdataset_t *modified = NULL;
|
||||
isc_boolean_t offline;
|
||||
|
||||
op = t->op;
|
||||
type = t->rdata.type;
|
||||
@ -255,6 +305,7 @@ diff_apply(dns_diff_t *diff, dns_db_t *db, dns_dbversion_t *ver,
|
||||
ISC_LIST_INIT(rdl.rdata);
|
||||
ISC_LINK_INIT(&rdl, link);
|
||||
|
||||
offline = ISC_FALSE;
|
||||
while (t != NULL &&
|
||||
dns_name_equal(&t->name, name) &&
|
||||
t->op == op &&
|
||||
@ -276,6 +327,10 @@ diff_apply(dns_diff_t *diff, dns_db_t *db, dns_dbversion_t *ver,
|
||||
namebuf, typebuf, classbuf,
|
||||
(unsigned long) t->ttl,
|
||||
(unsigned long) rdl.ttl);
|
||||
if (t->rdata.flags &DNS_RDATA_OFFLINE) {
|
||||
fprintf(stderr, "diff_apply offline\n");
|
||||
offline = ISC_TRUE;
|
||||
}
|
||||
ISC_LIST_APPEND(rdl.rdata, &t->rdata, link);
|
||||
t = ISC_LIST_NEXT(t, link);
|
||||
}
|
||||
@ -285,27 +340,50 @@ diff_apply(dns_diff_t *diff, dns_db_t *db, dns_dbversion_t *ver,
|
||||
*/
|
||||
dns_rdataset_init(&rds);
|
||||
CHECK(dns_rdatalist_tordataset(&rdl, &rds));
|
||||
if (rds.type == dns_rdatatype_rrsig)
|
||||
switch (op) {
|
||||
case DNS_DIFFOP_ADDRESIGN:
|
||||
case DNS_DIFFOP_DELRESIGN:
|
||||
modified = &ardataset;
|
||||
dns_rdataset_init(modified);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
rds.trust = dns_trust_ultimate;
|
||||
|
||||
/*
|
||||
* Merge the rdataset into the database.
|
||||
*/
|
||||
if (op == DNS_DIFFOP_ADD) {
|
||||
switch (op) {
|
||||
case DNS_DIFFOP_ADD:
|
||||
case DNS_DIFFOP_ADDRESIGN:
|
||||
result = dns_db_addrdataset(db, node, ver,
|
||||
0, &rds,
|
||||
DNS_DBADD_MERGE|
|
||||
DNS_DBADD_EXACT|
|
||||
DNS_DBADD_EXACTTTL,
|
||||
NULL);
|
||||
} else if (op == DNS_DIFFOP_DEL) {
|
||||
modified);
|
||||
break;
|
||||
case DNS_DIFFOP_DEL:
|
||||
case DNS_DIFFOP_DELRESIGN:
|
||||
result = dns_db_subtractrdataset(db, node, ver,
|
||||
&rds,
|
||||
DNS_DBSUB_EXACT,
|
||||
NULL);
|
||||
} else {
|
||||
modified);
|
||||
break;
|
||||
default:
|
||||
INSIST(0);
|
||||
}
|
||||
if (result == DNS_R_UNCHANGED) {
|
||||
|
||||
if (result == ISC_R_SUCCESS) {
|
||||
if (modified != NULL) {
|
||||
isc_stdtime_t resign;
|
||||
resign = setresign(modified, op);
|
||||
dns_db_setsigningtime(db, modified,
|
||||
resign);
|
||||
}
|
||||
} else if (result == DNS_R_UNCHANGED) {
|
||||
/*
|
||||
* This will not happen when executing a
|
||||
* dynamic update, because that code will
|
||||
@ -318,14 +396,21 @@ diff_apply(dns_diff_t *diff, dns_db_t *db, dns_dbversion_t *ver,
|
||||
isc_log_write(DIFF_COMMON_LOGARGS,
|
||||
ISC_LOG_WARNING,
|
||||
"update with no effect");
|
||||
} else if (result == ISC_R_SUCCESS ||
|
||||
result == DNS_R_NXRRSET) {
|
||||
} else if (result == DNS_R_NXRRSET) {
|
||||
/*
|
||||
* OK.
|
||||
*/
|
||||
} else {
|
||||
if (modified != NULL &&
|
||||
dns_rdataset_isassociated(modified))
|
||||
dns_rdataset_disassociate(modified);
|
||||
CHECK(result);
|
||||
}
|
||||
if (modified != NULL &&
|
||||
dns_rdataset_isassociated(modified))
|
||||
dns_rdataset_disassociate(modified);
|
||||
if (offline)
|
||||
fprintf(stderr, "end offline\n");
|
||||
}
|
||||
dns_db_detachnode(db, &node);
|
||||
}
|
||||
@ -485,6 +570,7 @@ dns_diff_print(dns_diff_t *diff, FILE *file) {
|
||||
dns_difftuple_t *t;
|
||||
char *mem = NULL;
|
||||
unsigned int size = 2048;
|
||||
const char *op = NULL;
|
||||
|
||||
REQUIRE(DNS_DIFF_VALID(diff));
|
||||
|
||||
@ -536,15 +622,20 @@ dns_diff_print(dns_diff_t *diff, FILE *file) {
|
||||
buf.used--;
|
||||
|
||||
isc_buffer_usedregion(&buf, &r);
|
||||
switch (t->op) {
|
||||
case DNS_DIFFOP_EXISTS: op = "exists"; break;
|
||||
case DNS_DIFFOP_ADD: op = "add"; break;
|
||||
case DNS_DIFFOP_DEL: op = "del"; break;
|
||||
case DNS_DIFFOP_ADDRESIGN: op = "add re-sign"; break;
|
||||
case DNS_DIFFOP_DELRESIGN: op = "del re-sign"; break;
|
||||
}
|
||||
if (file != NULL)
|
||||
fprintf(file, "%s %.*s\n",
|
||||
t->op == DNS_DIFFOP_ADD ? "add" : "del",
|
||||
(int) r.length, (char *) r.base);
|
||||
fprintf(file, "%s %.*s\n", op, (int) r.length,
|
||||
(char *) r.base);
|
||||
else
|
||||
isc_log_write(DIFF_COMMON_LOGARGS, ISC_LOG_DEBUG(7),
|
||||
"%s %.*s",
|
||||
t->op == DNS_DIFFOP_ADD ? "add" : "del",
|
||||
(int) r.length, (char *) r.base);
|
||||
"%s %.*s", op, (int) r.length,
|
||||
(char *) r.base);
|
||||
}
|
||||
result = ISC_R_SUCCESS;
|
||||
cleanup:
|
||||
|
@ -15,7 +15,7 @@
|
||||
* PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
/* $Id: db.h,v 1.89 2007/06/18 23:47:42 tbox Exp $ */
|
||||
/* $Id: db.h,v 1.90 2008/04/01 01:37:25 marka Exp $ */
|
||||
|
||||
#ifndef DNS_DB_H
|
||||
#define DNS_DB_H 1
|
||||
@ -148,6 +148,15 @@ typedef struct dns_dbmethods {
|
||||
isc_result_t (*getoriginnode)(dns_db_t *db, dns_dbnode_t **nodep);
|
||||
void (*transfernode)(dns_db_t *db, dns_dbnode_t **sourcep,
|
||||
dns_dbnode_t **targetp);
|
||||
isc_result_t (*setsigningtime)(dns_db_t *db,
|
||||
dns_rdataset_t *rdataset,
|
||||
isc_stdtime_t resign);
|
||||
isc_result_t (*getsigningtime)(dns_db_t *db,
|
||||
dns_rdataset_t *rdataset,
|
||||
dns_name_t *name);
|
||||
void (*resigned)(dns_db_t *db, dns_rdataset_t *rdataset,
|
||||
dns_dbversion_t *version);
|
||||
isc_boolean_t (*isdnssec)(dns_db_t *db);
|
||||
} dns_dbmethods_t;
|
||||
|
||||
typedef isc_result_t
|
||||
@ -357,6 +366,20 @@ dns_db_issecure(dns_db_t *db);
|
||||
* \li #ISC_FALSE 'db' is not secure.
|
||||
*/
|
||||
|
||||
isc_boolean_t
|
||||
dns_db_isdnssec(dns_db_t *db);
|
||||
/*%<
|
||||
* Is 'db' secure or partially secure?
|
||||
*
|
||||
* Requires:
|
||||
*
|
||||
* \li 'db' is a valid database with zone semantics.
|
||||
*
|
||||
* Returns:
|
||||
* \li #ISC_TRUE 'db' is secure or is partially.
|
||||
* \li #ISC_FALSE 'db' is not secure.
|
||||
*/
|
||||
|
||||
dns_name_t *
|
||||
dns_db_origin(dns_db_t *db);
|
||||
/*%<
|
||||
@ -1317,6 +1340,54 @@ dns_db_getoriginnode(dns_db_t *db, dns_dbnode_t **nodep);
|
||||
* \li #ISC_R_NOTFOUND - the DB implementation does not support this feature.
|
||||
*/
|
||||
|
||||
isc_result_t
|
||||
dns_db_setsigningtime(dns_db_t *db, dns_rdataset_t *rdataset,
|
||||
isc_stdtime_t resign);
|
||||
/*%<
|
||||
* Sets the re-signing time associated with 'rdataset' to 'resign'.
|
||||
*
|
||||
* Requires:
|
||||
* \li 'db' is a valid zone database.
|
||||
* \li 'rdataset' to be associated with 'db'.
|
||||
*
|
||||
* Returns:
|
||||
* \li #ISC_R_SUCCESS
|
||||
* \li #ISC_R_NOMEMORY
|
||||
* \li #ISC_R_NOTIMPLEMENTED - Not supported by this DB implementation.
|
||||
*/
|
||||
|
||||
isc_result_t
|
||||
dns_db_getsigningtime(dns_db_t *db, dns_rdataset_t *rdataset, dns_name_t *name);
|
||||
/*%<
|
||||
* Return the rdataset with the earliest signing time in the zone.
|
||||
* Note: the rdataset is version agnostic.
|
||||
*
|
||||
* Requires:
|
||||
* \li 'db' is a valid zone database.
|
||||
* \li 'rdataset' to be initialized but not associated.
|
||||
* \li 'name' to be NULL or have a buffer associated with it.
|
||||
*
|
||||
* Returns:
|
||||
* \li #ISC_R_SUCCESS
|
||||
* \li #ISC_R_NOTFOUND - No dataset exists.
|
||||
*/
|
||||
|
||||
void
|
||||
dns_db_resigned(dns_db_t *db, dns_rdataset_t *rdataset,
|
||||
dns_dbversion_t *version);
|
||||
/*%<
|
||||
* Mark 'rdataset' as not being available to be returned by
|
||||
* dns_db_getsigningtime(). If the changes associated with 'version'
|
||||
* are committed this will be permanent. If the version is not committed
|
||||
* this change will be rolled back when the version is closed.
|
||||
*
|
||||
* Requires:
|
||||
* \li 'db' is a valid zone database.
|
||||
* \li 'rdataset' to be associated with 'db'.
|
||||
* \li 'version' to be open for writing.
|
||||
*/
|
||||
|
||||
|
||||
ISC_LANG_ENDDECLS
|
||||
|
||||
#endif /* DNS_DB_H */
|
||||
|
@ -15,7 +15,7 @@
|
||||
* PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
/* $Id: diff.h,v 1.12 2007/06/19 23:47:16 tbox Exp $ */
|
||||
/* $Id: diff.h,v 1.13 2008/04/01 01:37:25 marka Exp $ */
|
||||
|
||||
#ifndef DNS_DIFF_H
|
||||
#define DNS_DIFF_H 1
|
||||
@ -59,12 +59,16 @@
|
||||
* individual RRs of a "RRset exists (value dependent)"
|
||||
* prerequisite set. In this case, op==DNS_DIFFOP_EXISTS,
|
||||
* and the TTL is ignored.
|
||||
*
|
||||
* DNS_DIFFOP_*RESIGN will cause the 'resign' attribute to be recomputed.
|
||||
*/
|
||||
|
||||
typedef enum {
|
||||
DNS_DIFFOP_ADD, /*%< Add an RR. */
|
||||
DNS_DIFFOP_DEL, /*%< Delete an RR. */
|
||||
DNS_DIFFOP_EXISTS /*%< Assert RR existence. */
|
||||
DNS_DIFFOP_ADD = 0, /*%< Add an RR. */
|
||||
DNS_DIFFOP_DEL = 1, /*%< Delete an RR. */
|
||||
DNS_DIFFOP_EXISTS = 2, /*%< Assert RR existence. */
|
||||
DNS_DIFFOP_ADDRESIGN = 4, /*%< ADD + RESIGN. */
|
||||
DNS_DIFFOP_DELRESIGN = 5, /*%< DEL + RESIGN. */
|
||||
} dns_diffop_t;
|
||||
|
||||
typedef struct dns_difftuple dns_difftuple_t;
|
||||
|
@ -15,7 +15,7 @@
|
||||
* PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
/* $Id: journal.h,v 1.31 2007/06/19 23:47:16 tbox Exp $ */
|
||||
/* $Id: journal.h,v 1.32 2008/04/01 01:37:25 marka Exp $ */
|
||||
|
||||
#ifndef DNS_JOURNAL_H
|
||||
#define DNS_JOURNAL_H 1
|
||||
@ -41,6 +41,11 @@
|
||||
#include <dns/rdata.h>
|
||||
#include <dns/types.h>
|
||||
|
||||
/***
|
||||
*** Defines.
|
||||
***/
|
||||
#define DNS_JOURNALOPT_RESIGN 0x00000001
|
||||
|
||||
/***
|
||||
*** Types
|
||||
***/
|
||||
@ -225,7 +230,8 @@ dns_journal_current_rr(dns_journal_t *j, dns_name_t **name, isc_uint32_t *ttl,
|
||||
*/
|
||||
|
||||
isc_result_t
|
||||
dns_journal_rollforward(isc_mem_t *mctx, dns_db_t *db, const char *filename);
|
||||
dns_journal_rollforward(isc_mem_t *mctx, dns_db_t *db, unsigned int options,
|
||||
const char *filename);
|
||||
/*%<
|
||||
* Roll forward (play back) the journal file "filename" into the
|
||||
* database "db". This should be called when the server starts
|
||||
@ -235,7 +241,7 @@ dns_journal_rollforward(isc_mem_t *mctx, dns_db_t *db, const char *filename);
|
||||
*\li 'mctx' is a valid memory context.
|
||||
*\li 'db' is a valid database which does not have a version
|
||||
* open for writing.
|
||||
* \li 'filename' is the name of the journal file belonging to 'db'.
|
||||
*\li 'filename' is the name of the journal file belonging to 'db'.
|
||||
*
|
||||
* Returns:
|
||||
*\li DNS_R_NOJOURNAL when journal does not exist.
|
||||
|
@ -15,7 +15,7 @@
|
||||
* PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
/* $Id: master.h,v 1.48 2007/06/19 23:47:17 tbox Exp $ */
|
||||
/* $Id: master.h,v 1.49 2008/04/01 01:37:25 marka Exp $ */
|
||||
|
||||
#ifndef DNS_MASTER_H
|
||||
#define DNS_MASTER_H 1
|
||||
@ -55,6 +55,8 @@
|
||||
#define DNS_MASTER_CHECKMX 0x00000800
|
||||
#define DNS_MASTER_CHECKMXFAIL 0x00001000
|
||||
|
||||
#define DNS_MASTER_RESIGN 0x00002000
|
||||
|
||||
ISC_LANG_BEGINDECLS
|
||||
|
||||
/*
|
||||
|
@ -15,7 +15,7 @@
|
||||
* PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
/* $Id: masterdump.h,v 1.39 2007/06/19 23:47:17 tbox Exp $ */
|
||||
/* $Id: masterdump.h,v 1.40 2008/04/01 01:37:25 marka Exp $ */
|
||||
|
||||
#ifndef DNS_MASTERDUMP_H
|
||||
#define DNS_MASTERDUMP_H 1
|
||||
@ -91,12 +91,15 @@ typedef struct dns_master_style dns_master_style_t;
|
||||
/*% Print negative caching entries. */
|
||||
#define DNS_STYLEFLAG_NCACHE 0x00800000U
|
||||
|
||||
/*% Never print the TTL */
|
||||
/*% Never print the TTL. */
|
||||
#define DNS_STYLEFLAG_NO_TTL 0x01000000U
|
||||
|
||||
/*% Never print the CLASS */
|
||||
/*% Never print the CLASS. */
|
||||
#define DNS_STYLEFLAG_NO_CLASS 0x02000000U
|
||||
|
||||
/*% Report re-signing time. */
|
||||
#define DNS_STYLEFLAG_RESIGN 0x04000000U
|
||||
|
||||
ISC_LANG_BEGINDECLS
|
||||
|
||||
/***
|
||||
|
@ -15,7 +15,7 @@
|
||||
* PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
/* $Id: rdata.h,v 1.67 2007/06/19 23:47:17 tbox Exp $ */
|
||||
/* $Id: rdata.h,v 1.68 2008/04/01 01:37:25 marka Exp $ */
|
||||
|
||||
#ifndef DNS_RDATA_H
|
||||
#define DNS_RDATA_H 1
|
||||
@ -124,7 +124,13 @@ struct dns_rdata {
|
||||
|
||||
#define DNS_RDATA_INIT { NULL, 0, 0, 0, 0, {(void*)(-1), (void *)(-1)}}
|
||||
|
||||
#define DNS_RDATA_UPDATE 0x0001 /*%< update pseudo record */
|
||||
#define DNS_RDATA_UPDATE 0x0001 /*%< update pseudo record. */
|
||||
#define DNS_RDATA_OFFLINE 0x0002 /*%< RRSIG has a offline key. */
|
||||
#define DNS_RDATA_WARNMASK 0x001c /*%< RRSIG(DNSKEY) expired
|
||||
warnings number mask. */
|
||||
#define DNS_RDATA_WARNSHIFT 2 /*%< How many bits to shift
|
||||
to find remaining
|
||||
expired warning number. */
|
||||
|
||||
/*
|
||||
* Flags affecting rdata formatting style. Flags 0xFFFF0000
|
||||
|
@ -15,7 +15,7 @@
|
||||
* PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
/* $Id: rdataset.h,v 1.62 2007/06/19 23:47:17 tbox Exp $ */
|
||||
/* $Id: rdataset.h,v 1.63 2008/04/01 01:37:25 marka Exp $ */
|
||||
|
||||
#ifndef DNS_RDATASET_H
|
||||
#define DNS_RDATASET_H 1
|
||||
@ -140,6 +140,11 @@ struct dns_rdataset {
|
||||
* increment the counter.
|
||||
*/
|
||||
isc_uint32_t count;
|
||||
/*
|
||||
* This RRSIG RRset should be re-generated around this time.
|
||||
* Only valid if DNS_RDATASETATTR_RESIGN is set in attributes.
|
||||
*/
|
||||
isc_stdtime_t resign;
|
||||
/*@{*/
|
||||
/*%
|
||||
* These are for use by the rdataset implementation, and MUST NOT
|
||||
@ -152,6 +157,7 @@ struct dns_rdataset {
|
||||
void * private5;
|
||||
void * private6;
|
||||
/*@}*/
|
||||
|
||||
};
|
||||
|
||||
/*!
|
||||
@ -184,6 +190,7 @@ struct dns_rdataset {
|
||||
#define DNS_RDATASETATTR_CHECKNAMES 0x00008000 /*%< Used by resolver. */
|
||||
#define DNS_RDATASETATTR_REQUIREDGLUE 0x00010000
|
||||
#define DNS_RDATASETATTR_LOADORDER 0x00020000
|
||||
#define DNS_RDATASETATTR_RESIGN 0x00040000
|
||||
|
||||
/*%
|
||||
* _OMITDNSSEC:
|
||||
|
@ -15,7 +15,7 @@
|
||||
* PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
/* $Id: rdataslab.h,v 1.31 2007/06/19 23:47:17 tbox Exp $ */
|
||||
/* $Id: rdataslab.h,v 1.32 2008/04/01 01:37:25 marka Exp $ */
|
||||
|
||||
#ifndef DNS_RDATASLAB_H
|
||||
#define DNS_RDATASLAB_H 1
|
||||
@ -57,6 +57,13 @@ ISC_LANG_BEGINDECLS
|
||||
#define DNS_RDATASLAB_FORCE 0x1
|
||||
#define DNS_RDATASLAB_EXACT 0x2
|
||||
|
||||
#define DNS_RDATASLAB_OFFLINE 0x01 /* RRSIG is for offline DNSKEY */
|
||||
#define DNS_RDATASLAB_WARNMASK 0x0E /*%< RRSIG(DNSKEY) expired
|
||||
* warnings number mask. */
|
||||
#define DNS_RDATASLAB_WARNSHIFT 1 /*%< How many bits to shift to find
|
||||
* remaining expired warning number. */
|
||||
|
||||
|
||||
/***
|
||||
*** Functions
|
||||
***/
|
||||
|
@ -15,7 +15,7 @@
|
||||
* PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
/* $Id: zone.h,v 1.155 2008/01/24 23:47:00 tbox Exp $ */
|
||||
/* $Id: zone.h,v 1.156 2008/04/01 01:37:25 marka Exp $ */
|
||||
|
||||
#ifndef DNS_ZONE_H
|
||||
#define DNS_ZONE_H 1
|
||||
@ -879,12 +879,16 @@ isc_boolean_t
|
||||
dns_zone_getupdatedisabled(dns_zone_t *zone);
|
||||
/*%<
|
||||
* Return update disabled.
|
||||
* Transient unless called when running in isc_task_exclusive() mode.
|
||||
*/
|
||||
|
||||
void
|
||||
dns_zone_setupdatedisabled(dns_zone_t *zone, isc_boolean_t state);
|
||||
/*%<
|
||||
* Set update disabled.
|
||||
* Should only be called only when running in isc_task_exclusive() mode.
|
||||
* Failure to do so may result in updates being committed after the
|
||||
* call has been made.
|
||||
*/
|
||||
|
||||
isc_boolean_t
|
||||
@ -1636,6 +1640,9 @@ dns_zone_setisself(dns_zone_t *zone, dns_isselffunc_t isself, void *arg);
|
||||
* delivered to 'myview'.
|
||||
*/
|
||||
|
||||
isc_result_t
|
||||
dns_zone_signwithkey(dns_zone_t *zone, dns_secalg_t algorithm, uint16_t keyid);
|
||||
|
||||
#ifdef HAVE_LIBXML2
|
||||
|
||||
isc_result_t
|
||||
|
@ -15,7 +15,7 @@
|
||||
* PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
/* $Id: journal.c,v 1.99 2007/09/07 05:14:33 marka Exp $ */
|
||||
/* $Id: journal.c,v 1.100 2008/04/01 01:37:24 marka Exp $ */
|
||||
|
||||
#include <config.h>
|
||||
|
||||
@ -709,8 +709,35 @@ ixfr_order(const void *av, const void *bv) {
|
||||
dns_difftuple_t const *a = *ap;
|
||||
dns_difftuple_t const *b = *bp;
|
||||
int r;
|
||||
int bop = 0, aop = 0;
|
||||
|
||||
r = (b->op == DNS_DIFFOP_DEL) - (a->op == DNS_DIFFOP_DEL);
|
||||
switch (a->op) {
|
||||
case DNS_DIFFOP_DEL:
|
||||
case DNS_DIFFOP_DELRESIGN:
|
||||
aop = 1;
|
||||
break;
|
||||
case DNS_DIFFOP_ADD:
|
||||
case DNS_DIFFOP_ADDRESIGN:
|
||||
aop = 0;
|
||||
break;
|
||||
default:
|
||||
INSIST(0);
|
||||
}
|
||||
|
||||
switch (b->op) {
|
||||
case DNS_DIFFOP_DEL:
|
||||
case DNS_DIFFOP_DELRESIGN:
|
||||
bop = 1;
|
||||
break;
|
||||
case DNS_DIFFOP_ADD:
|
||||
case DNS_DIFFOP_ADDRESIGN:
|
||||
bop = 0;
|
||||
break;
|
||||
default:
|
||||
INSIST(0);
|
||||
}
|
||||
|
||||
r = bop - aop;
|
||||
if (r != 0)
|
||||
return (r);
|
||||
|
||||
@ -1191,7 +1218,7 @@ dns_journal_destroy(dns_journal_t **journalp) {
|
||||
/* XXX Share code with incoming IXFR? */
|
||||
|
||||
static isc_result_t
|
||||
roll_forward(dns_journal_t *j, dns_db_t *db) {
|
||||
roll_forward(dns_journal_t *j, dns_db_t *db, unsigned int options) {
|
||||
isc_buffer_t source; /* Transaction data from disk */
|
||||
isc_buffer_t target; /* Ditto after _fromwire check */
|
||||
isc_uint32_t db_serial; /* Database SOA serial */
|
||||
@ -1202,6 +1229,7 @@ roll_forward(dns_journal_t *j, dns_db_t *db) {
|
||||
dns_diff_t diff;
|
||||
unsigned int n_soa = 0;
|
||||
unsigned int n_put = 0;
|
||||
dns_diffop_t op;
|
||||
|
||||
REQUIRE(DNS_JOURNAL_VALID(j));
|
||||
REQUIRE(DNS_DB_VALID(db));
|
||||
@ -1273,9 +1301,14 @@ roll_forward(dns_journal_t *j, dns_db_t *db) {
|
||||
"initial SOA", j->filename);
|
||||
FAIL(ISC_R_UNEXPECTED);
|
||||
}
|
||||
CHECK(dns_difftuple_create(diff.mctx, n_soa == 1 ?
|
||||
DNS_DIFFOP_DEL : DNS_DIFFOP_ADD,
|
||||
name, ttl, rdata, &tuple));
|
||||
if ((options & DNS_JOURNALOPT_RESIGN) != 0)
|
||||
op = (n_soa == 1) ? DNS_DIFFOP_DELRESIGN :
|
||||
DNS_DIFFOP_ADDRESIGN;
|
||||
else
|
||||
op = (n_soa == 1) ? DNS_DIFFOP_DEL : DNS_DIFFOP_ADD;
|
||||
|
||||
CHECK(dns_difftuple_create(diff.mctx, op, name, ttl, rdata,
|
||||
&tuple));
|
||||
dns_diff_append(&diff, &tuple);
|
||||
|
||||
if (++n_put > 100) {
|
||||
@ -1317,7 +1350,9 @@ roll_forward(dns_journal_t *j, dns_db_t *db) {
|
||||
}
|
||||
|
||||
isc_result_t
|
||||
dns_journal_rollforward(isc_mem_t *mctx, dns_db_t *db, const char *filename) {
|
||||
dns_journal_rollforward(isc_mem_t *mctx, dns_db_t *db,
|
||||
unsigned int options, const char *filename)
|
||||
{
|
||||
dns_journal_t *j;
|
||||
isc_result_t result;
|
||||
|
||||
@ -1336,7 +1371,7 @@ dns_journal_rollforward(isc_mem_t *mctx, dns_db_t *db, const char *filename) {
|
||||
if (JOURNAL_EMPTY(&j->header))
|
||||
result = DNS_R_UPTODATE;
|
||||
else
|
||||
result = roll_forward(j, db);
|
||||
result = roll_forward(j, db, options);
|
||||
|
||||
dns_journal_destroy(&j);
|
||||
|
||||
|
@ -15,7 +15,7 @@
|
||||
* PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
/* $Id: master.c,v 1.169 2008/01/18 23:46:58 tbox Exp $ */
|
||||
/* $Id: master.c,v 1.170 2008/04/01 01:37:24 marka Exp $ */
|
||||
|
||||
/*! \file */
|
||||
|
||||
@ -1738,8 +1738,7 @@ load_text(dns_loadctx_t *lctx) {
|
||||
char namebuf[DNS_NAME_FORMATSIZE];
|
||||
dns_name_format(ictx->current, namebuf,
|
||||
sizeof(namebuf));
|
||||
(*callbacks->error)(callbacks,
|
||||
"%s:%lu: SOA "
|
||||
(*callbacks->error)(callbacks, "%s:%lu: SOA "
|
||||
"record not at top of zone (%s)",
|
||||
source, line, namebuf);
|
||||
result = DNS_R_NOTZONETOP;
|
||||
@ -2700,6 +2699,29 @@ grow_rdata(int new_len, dns_rdata_t *old, int old_len,
|
||||
return (new);
|
||||
}
|
||||
|
||||
static isc_uint32_t
|
||||
resign_fromlist(dns_rdatalist_t *this) {
|
||||
dns_rdata_t *rdata;
|
||||
dns_rdata_rrsig_t sig;
|
||||
isc_uint32_t when, delta;
|
||||
|
||||
rdata = ISC_LIST_HEAD(this->rdata);
|
||||
INSIST(rdata != NULL);
|
||||
(void)dns_rdata_tostruct(rdata, &sig, NULL);
|
||||
delta = (sig.timeexpire - sig.timesigned)* 3 / 4;
|
||||
when = sig.timesigned + delta;
|
||||
|
||||
rdata = ISC_LIST_NEXT(rdata, link);
|
||||
while (rdata != NULL) {
|
||||
(void)dns_rdata_tostruct(rdata, &sig, NULL);
|
||||
delta = (sig.timeexpire - sig.timesigned)* 3 / 4;
|
||||
if (sig.timesigned + delta < when)
|
||||
when = sig.timesigned + delta;
|
||||
rdata = ISC_LIST_NEXT(rdata, link);
|
||||
}
|
||||
return (when);
|
||||
}
|
||||
|
||||
/*
|
||||
* Convert each element from a rdatalist_t to rdataset then call commit.
|
||||
* Unlink each element as we go.
|
||||
@ -2726,14 +2748,22 @@ commit(dns_rdatacallbacks_t *callbacks, dns_loadctx_t *lctx,
|
||||
RUNTIME_CHECK(dns_rdatalist_tordataset(this, &dataset)
|
||||
== ISC_R_SUCCESS);
|
||||
dataset.trust = dns_trust_ultimate;
|
||||
/*
|
||||
* If this is a secure dynamic zone set the re-signing time.
|
||||
*/
|
||||
if (dataset.type == dns_rdatatype_rrsig &&
|
||||
(lctx->options & DNS_MASTER_RESIGN) != 0) {
|
||||
dataset.attributes |= DNS_RDATASETATTR_RESIGN;
|
||||
dns_name_format(owner, namebuf, sizeof(namebuf));
|
||||
dataset.resign = resign_fromlist(this);
|
||||
}
|
||||
result = ((*callbacks->add)(callbacks->add_private, owner,
|
||||
&dataset));
|
||||
if (result == ISC_R_NOMEMORY) {
|
||||
(*error)(callbacks, "dns_master_load: %s",
|
||||
dns_result_totext(result));
|
||||
} else if (result != ISC_R_SUCCESS) {
|
||||
dns_name_format(owner, namebuf,
|
||||
sizeof(namebuf));
|
||||
dns_name_format(owner, namebuf, sizeof(namebuf));
|
||||
if (source != NULL) {
|
||||
(*error)(callbacks, "%s: %s:%lu: %s: %s",
|
||||
"dns_master_load", source, line,
|
||||
|
@ -15,7 +15,7 @@
|
||||
* PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
/* $Id: masterdump.c,v 1.89 2007/06/19 23:47:16 tbox Exp $ */
|
||||
/* $Id: masterdump.c,v 1.90 2008/04/01 01:37:24 marka Exp $ */
|
||||
|
||||
/*! \file */
|
||||
|
||||
@ -108,7 +108,8 @@ dns_master_style_default = {
|
||||
|
||||
LIBDNS_EXTERNAL_DATA const dns_master_style_t
|
||||
dns_master_style_full = {
|
||||
DNS_STYLEFLAG_COMMENT,
|
||||
DNS_STYLEFLAG_COMMENT |
|
||||
DNS_STYLEFLAG_RESIGN,
|
||||
46, 46, 46, 64, 120, 8
|
||||
};
|
||||
|
||||
@ -840,6 +841,15 @@ dump_rdatasets_text(isc_mem_t *mctx, dns_name_t *name,
|
||||
if ((ctx->style.flags & DNS_STYLEFLAG_OMIT_OWNER) != 0)
|
||||
name = NULL;
|
||||
}
|
||||
if (ctx->style.flags & DNS_STYLEFLAG_RESIGN &&
|
||||
rds->attributes & DNS_RDATASETATTR_RESIGN) {
|
||||
isc_buffer_t b;
|
||||
char buf[sizeof("YYYYMMDDHHMMSS")];
|
||||
memset(buf, 0, sizeof(buf));
|
||||
isc_buffer_init(&b, buf, sizeof(buf) - 1);
|
||||
dns_time64_totext((isc_uint64_t)rds->resign, &b);
|
||||
fprintf(f, "; resign=%s\n", buf);
|
||||
}
|
||||
dns_rdataset_disassociate(rds);
|
||||
}
|
||||
|
||||
|
354
lib/dns/rbtdb.c
354
lib/dns/rbtdb.c
@ -15,7 +15,7 @@
|
||||
* PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
/* $Id: rbtdb.c,v 1.252 2008/02/01 23:46:58 tbox Exp $ */
|
||||
/* $Id: rbtdb.c,v 1.253 2008/04/01 01:37:24 marka Exp $ */
|
||||
|
||||
/*! \file */
|
||||
|
||||
@ -25,15 +25,16 @@
|
||||
|
||||
#include <config.h>
|
||||
|
||||
#include <isc/heap.h>
|
||||
#include <isc/event.h>
|
||||
#include <isc/heap.h>
|
||||
#include <isc/mem.h>
|
||||
#include <isc/mutex.h>
|
||||
#include <isc/platform.h>
|
||||
#include <isc/print.h>
|
||||
#include <isc/mutex.h>
|
||||
#include <isc/random.h>
|
||||
#include <isc/refcount.h>
|
||||
#include <isc/rwlock.h>
|
||||
#include <isc/serial.h>
|
||||
#include <isc/string.h>
|
||||
#include <isc/task.h>
|
||||
#include <isc/time.h>
|
||||
@ -47,6 +48,7 @@
|
||||
#include <dns/lib.h>
|
||||
#include <dns/log.h>
|
||||
#include <dns/masterdump.h>
|
||||
#include <dns/nsec.h>
|
||||
#include <dns/rbt.h>
|
||||
#include <dns/rdata.h>
|
||||
#include <dns/rdataset.h>
|
||||
@ -261,6 +263,7 @@ typedef struct rdatasetheader {
|
||||
/*%<
|
||||
* Used for TTL-based cache cleaning.
|
||||
*/
|
||||
isc_stdtime_t resign;
|
||||
} rdatasetheader_t;
|
||||
|
||||
typedef ISC_LIST(rdatasetheader_t) rdatasetheaderlist_t;
|
||||
@ -271,6 +274,7 @@ typedef ISC_LIST(dns_rbtnode_t) rbtnodelist_t;
|
||||
#define RDATASET_ATTR_IGNORE 0x0004
|
||||
#define RDATASET_ATTR_RETAIN 0x0008
|
||||
#define RDATASET_ATTR_NXDOMAIN 0x0010
|
||||
#define RDATASET_ATTR_RESIGN 0x0020
|
||||
#define RDATASET_ATTR_CACHE 0x1000 /* for debug */
|
||||
#define RDATASET_ATTR_CANCELED 0x2000 /* for debug */
|
||||
|
||||
@ -307,6 +311,8 @@ struct acachectl {
|
||||
(((header)->attributes & RDATASET_ATTR_RETAIN) != 0)
|
||||
#define NXDOMAIN(header) \
|
||||
(((header)->attributes & RDATASET_ATTR_NXDOMAIN) != 0)
|
||||
#define RESIGN(header) \
|
||||
(((header)->attributes & RDATASET_ATTR_RESIGN) != 0)
|
||||
|
||||
#define DEFAULT_NODE_LOCK_COUNT 7 /*%< Should be prime. */
|
||||
#define DEFAULT_CACHE_NODE_LOCK_COUNT 1009 /*%< Should be prime. */
|
||||
@ -340,6 +346,7 @@ typedef struct rbtdb_version {
|
||||
isc_boolean_t writer;
|
||||
isc_boolean_t commit_ok;
|
||||
rbtdb_changedlist_t changed_list;
|
||||
rdatasetheaderlist_t resigned_list;
|
||||
ISC_LINK(struct rbtdb_version) link;
|
||||
} rbtdb_version_t;
|
||||
|
||||
@ -372,6 +379,12 @@ struct cachestat {
|
||||
};
|
||||
#endif
|
||||
|
||||
typedef enum {
|
||||
dns_db_insecure,
|
||||
dns_db_partial,
|
||||
dns_db_secure
|
||||
} dns_db_secure_t;
|
||||
|
||||
typedef struct {
|
||||
/* Unlocked. */
|
||||
dns_db_t common;
|
||||
@ -419,7 +432,7 @@ typedef struct {
|
||||
|
||||
/* Locked by tree_lock. */
|
||||
dns_rbt_t * tree;
|
||||
isc_boolean_t secure;
|
||||
dns_db_secure_t secure;
|
||||
|
||||
/* Unlocked */
|
||||
unsigned int quantum;
|
||||
@ -498,6 +511,8 @@ static void update_header(dns_rbtdb_t *rbtdb, rdatasetheader_t *header,
|
||||
isc_stdtime_t now);
|
||||
static void check_stale_cache(dns_rbtdb_t *rbtdb, dns_rbtnode_t *rbtnode,
|
||||
isc_stdtime_t now, isc_boolean_t tree_locked);
|
||||
static isc_result_t resign_insert(dns_rbtdb_t *rbtdb, int idx,
|
||||
rdatasetheader_t *newheader);
|
||||
|
||||
static dns_rdatasetmethods_t rdataset_methods = {
|
||||
rdataset_disassociate,
|
||||
@ -653,6 +668,9 @@ set_ttl(dns_rbtdb_t *rbtdb, rdatasetheader_t *header, dns_ttl_t newttl) {
|
||||
oldttl = header->rdh_ttl;
|
||||
header->rdh_ttl = newttl;
|
||||
|
||||
if (!IS_CACHE(rbtdb))
|
||||
return;
|
||||
|
||||
/*
|
||||
* It's possible the rbtdb is not a cache. If this is the case,
|
||||
* we will not have a heap, and we move on. If we do, though,
|
||||
@ -672,7 +690,7 @@ set_ttl(dns_rbtdb_t *rbtdb, rdatasetheader_t *header, dns_ttl_t newttl) {
|
||||
}
|
||||
|
||||
/*%
|
||||
* This function allows the heap code to rank the priority of each
|
||||
* These functions allows the heap code to rank the priority of each
|
||||
* element. It returns ISC_TRUE if v1 happens "sooner" than v2.
|
||||
*/
|
||||
static isc_boolean_t
|
||||
@ -685,11 +703,21 @@ ttl_sooner(void *v1, void *v2) {
|
||||
return (ISC_FALSE);
|
||||
}
|
||||
|
||||
static isc_boolean_t
|
||||
resign_sooner(void *v1, void *v2) {
|
||||
rdatasetheader_t *h1 = v1;
|
||||
rdatasetheader_t *h2 = v2;
|
||||
|
||||
if (h1->resign < h2->resign)
|
||||
return (ISC_TRUE);
|
||||
return (ISC_FALSE);
|
||||
}
|
||||
|
||||
/*%
|
||||
* This function sets the heap index into the header.
|
||||
*/
|
||||
static void
|
||||
ttl_set_index(void *what, unsigned int index) {
|
||||
set_index(void *what, unsigned int index) {
|
||||
rdatasetheader_t *h = what;
|
||||
|
||||
h->heap_index = index;
|
||||
@ -828,7 +856,7 @@ free_rbtdb(dns_rbtdb_t *rbtdb, isc_boolean_t log, isc_event_t *event) {
|
||||
}
|
||||
|
||||
/*
|
||||
* Clean up LRU cache objects.
|
||||
* Clean up LRU / re-signing order lists.
|
||||
*/
|
||||
if (rbtdb->rdatasets != NULL) {
|
||||
for (i = 0; i < rbtdb->node_lock_count; i++)
|
||||
@ -847,7 +875,7 @@ free_rbtdb(dns_rbtdb_t *rbtdb, isc_boolean_t log, isc_event_t *event) {
|
||||
rbtdb->node_lock_count * sizeof(rbtnodelist_t));
|
||||
}
|
||||
/*
|
||||
* Clean up TTL heap cache objects.
|
||||
* Clean up heap objects.
|
||||
*/
|
||||
if (rbtdb->heaps != NULL) {
|
||||
for (i = 0; i < rbtdb->node_lock_count; i++)
|
||||
@ -1005,6 +1033,7 @@ allocate_version(isc_mem_t *mctx, rbtdb_serial_t serial,
|
||||
version->writer = writer;
|
||||
version->commit_ok = ISC_FALSE;
|
||||
ISC_LIST_INIT(version->changed_list);
|
||||
ISC_LIST_INIT(version->resigned_list);
|
||||
ISC_LINK_INIT(version, link);
|
||||
|
||||
return (version);
|
||||
@ -1165,6 +1194,7 @@ static inline void
|
||||
free_rdataset(dns_rbtdb_t *rbtdb, isc_mem_t *mctx, rdatasetheader_t *rdataset)
|
||||
{
|
||||
unsigned int size;
|
||||
int idx;
|
||||
|
||||
#ifdef LRU_DEBUG
|
||||
/*
|
||||
@ -1229,15 +1259,12 @@ free_rdataset(dns_rbtdb_t *rbtdb, isc_mem_t *mctx, rdatasetheader_t *rdataset)
|
||||
}
|
||||
#endif
|
||||
|
||||
if (IS_CACHE(rbtdb) && ISC_LINK_LINKED(rdataset, lru_link)) {
|
||||
int idx = rdataset->node->locknum;
|
||||
idx = rdataset->node->locknum;
|
||||
if (ISC_LINK_LINKED(rdataset, lru_link))
|
||||
ISC_LIST_UNLINK(rbtdb->rdatasets[idx], rdataset, lru_link);
|
||||
if (rdataset->heap_index != 0) {
|
||||
isc_heap_delete(rbtdb->heaps[idx],
|
||||
rdataset->heap_index);
|
||||
}
|
||||
if (rdataset->heap_index != 0)
|
||||
isc_heap_delete(rbtdb->heaps[idx], rdataset->heap_index);
|
||||
rdataset->heap_index = 0;
|
||||
}
|
||||
|
||||
if (rdataset->noqname != NULL)
|
||||
free_noqname(mctx, &rdataset->noqname);
|
||||
@ -1703,12 +1730,14 @@ cleanup_nondirty(rbtdb_version_t *version, rbtdb_changedlist_t *cleanup_list) {
|
||||
}
|
||||
}
|
||||
|
||||
static isc_boolean_t
|
||||
static dns_db_secure_t
|
||||
iszonesecure(dns_db_t *db, dns_dbnode_t *origin) {
|
||||
dns_rdataset_t keyset;
|
||||
dns_rdataset_t nsecset, signsecset;
|
||||
dns_rdata_t rdata = DNS_RDATA_INIT;
|
||||
isc_boolean_t haszonekey = ISC_FALSE;
|
||||
isc_boolean_t hasnsec = ISC_FALSE;
|
||||
isc_boolean_t hasoptbit = ISC_FALSE;
|
||||
isc_result_t result;
|
||||
|
||||
dns_rdataset_init(&keyset);
|
||||
@ -1728,7 +1757,7 @@ iszonesecure(dns_db_t *db, dns_dbnode_t *origin) {
|
||||
dns_rdataset_disassociate(&keyset);
|
||||
}
|
||||
if (!haszonekey)
|
||||
return (ISC_FALSE);
|
||||
return (dns_db_insecure);
|
||||
|
||||
dns_rdataset_init(&nsecset);
|
||||
dns_rdataset_init(&signsecset);
|
||||
@ -1737,11 +1766,20 @@ iszonesecure(dns_db_t *db, dns_dbnode_t *origin) {
|
||||
if (result == ISC_R_SUCCESS) {
|
||||
if (dns_rdataset_isassociated(&signsecset)) {
|
||||
hasnsec = ISC_TRUE;
|
||||
result = dns_rdataset_first(&nsecset);
|
||||
if (result == ISC_R_SUCCESS) {
|
||||
dns_rdataset_current(&nsecset, &rdata);
|
||||
hasoptbit = dns_nsec_typepresent(&rdata,
|
||||
dns_rdatatype_opt);
|
||||
}
|
||||
dns_rdataset_disassociate(&signsecset);
|
||||
}
|
||||
dns_rdataset_disassociate(&nsecset);
|
||||
}
|
||||
return (hasnsec);
|
||||
|
||||
if (hasnsec && hasoptbit)
|
||||
return (dns_db_partial);
|
||||
return (hasnsec ? dns_db_secure : dns_db_insecure);
|
||||
}
|
||||
|
||||
static void
|
||||
@ -1750,10 +1788,12 @@ closeversion(dns_db_t *db, dns_dbversion_t **versionp, isc_boolean_t commit) {
|
||||
rbtdb_version_t *version, *cleanup_version, *least_greater;
|
||||
isc_boolean_t rollback = ISC_FALSE;
|
||||
rbtdb_changedlist_t cleanup_list;
|
||||
rdatasetheaderlist_t resigned_list;
|
||||
rbtdb_changed_t *changed, *next_changed;
|
||||
rbtdb_serial_t serial, least_serial;
|
||||
dns_rbtnode_t *rbtnode;
|
||||
unsigned int refs;
|
||||
rdatasetheader_t *header;
|
||||
isc_boolean_t writer;
|
||||
|
||||
REQUIRE(VALID_RBTDB(rbtdb));
|
||||
@ -1761,6 +1801,7 @@ closeversion(dns_db_t *db, dns_dbversion_t **versionp, isc_boolean_t commit) {
|
||||
|
||||
cleanup_version = NULL;
|
||||
ISC_LIST_INIT(cleanup_list);
|
||||
ISC_LIST_INIT(resigned_list);
|
||||
|
||||
isc_refcount_decrement(&version->references, &refs);
|
||||
if (refs > 0) { /* typical and easy case first */
|
||||
@ -1850,12 +1891,16 @@ closeversion(dns_db_t *db, dns_dbversion_t **versionp, isc_boolean_t commit) {
|
||||
INSIST(cur_ref == 1);
|
||||
PREPEND(rbtdb->open_versions,
|
||||
rbtdb->current_version, link);
|
||||
resigned_list = version->resigned_list;
|
||||
ISC_LIST_INIT(version->resigned_list);
|
||||
} else {
|
||||
/*
|
||||
* We're rolling back this transaction.
|
||||
*/
|
||||
cleanup_list = version->changed_list;
|
||||
ISC_LIST_INIT(version->changed_list);
|
||||
resigned_list = version->resigned_list;
|
||||
ISC_LIST_INIT(version->resigned_list);
|
||||
rollback = ISC_TRUE;
|
||||
cleanup_version = version;
|
||||
rbtdb->future_version = NULL;
|
||||
@ -1916,6 +1961,25 @@ closeversion(dns_db_t *db, dns_dbversion_t **versionp, isc_boolean_t commit) {
|
||||
sizeof(*cleanup_version));
|
||||
}
|
||||
|
||||
/*
|
||||
* Commit/rollback re-signed headers.
|
||||
*/
|
||||
for (header = HEAD(resigned_list);
|
||||
header != NULL;
|
||||
header = HEAD(resigned_list)) {
|
||||
ISC_LIST_UNLINK(resigned_list, header, lru_link);
|
||||
if (rollback) {
|
||||
nodelock_t *lock;
|
||||
lock = &rbtdb->node_locks[header->node->locknum].lock;
|
||||
NODE_LOCK(lock, isc_rwlocktype_write);
|
||||
resign_insert(rbtdb, header->node->locknum, header);
|
||||
NODE_UNLOCK(lock, isc_rwlocktype_write);
|
||||
}
|
||||
decrement_reference(rbtdb, header->node, least_serial,
|
||||
isc_rwlocktype_write,
|
||||
isc_rwlocktype_none);
|
||||
}
|
||||
|
||||
if (!EMPTY(cleanup_list)) {
|
||||
/*
|
||||
* We acquire a tree write lock here in order to make sure
|
||||
@ -2306,6 +2370,14 @@ bind_rdataset(dns_rbtdb_t *rbtdb, dns_rbtnode_t *node,
|
||||
rdataset->private6 = header->noqname;
|
||||
if (rdataset->private6 != NULL)
|
||||
rdataset->attributes |= DNS_RDATASETATTR_NOQNAME;
|
||||
/*
|
||||
* Copy out re-signing information.
|
||||
*/
|
||||
if (RESIGN(header)) {
|
||||
rdataset->attributes |= DNS_RDATASETATTR_RESIGN;
|
||||
rdataset->resign = header->resign;
|
||||
} else
|
||||
rdataset->resign = 0;
|
||||
}
|
||||
|
||||
static inline isc_result_t
|
||||
@ -2993,12 +3065,12 @@ zone_find(dns_db_t *db, dns_name_t *name, dns_dbversion_t *version,
|
||||
* If we're here, then the name does not exist, is not
|
||||
* beneath a zonecut, and there's no matching wildcard.
|
||||
*/
|
||||
if (search.rbtdb->secure ||
|
||||
if (search.rbtdb->secure == dns_db_secure ||
|
||||
(search.options & DNS_DBFIND_FORCENSEC) != 0)
|
||||
{
|
||||
result = find_closest_nsec(&search, nodep, foundname,
|
||||
rdataset, sigrdataset,
|
||||
search.rbtdb->secure);
|
||||
ISC_TRUE);
|
||||
if (result == ISC_R_SUCCESS)
|
||||
result = active ? DNS_R_EMPTYNAME :
|
||||
DNS_R_NXDOMAIN;
|
||||
@ -3222,7 +3294,7 @@ zone_find(dns_db_t *db, dns_name_t *name, dns_dbversion_t *version,
|
||||
* The desired type doesn't exist.
|
||||
*/
|
||||
result = DNS_R_NXRRSET;
|
||||
if (search.rbtdb->secure &&
|
||||
if (search.rbtdb->secure == dns_db_secure &&
|
||||
(nsecheader == NULL || nsecsig == NULL)) {
|
||||
/*
|
||||
* The zone is secure but there's no NSEC,
|
||||
@ -3237,7 +3309,8 @@ zone_find(dns_db_t *db, dns_name_t *name, dns_dbversion_t *version,
|
||||
NODE_UNLOCK(lock, isc_rwlocktype_read);
|
||||
result = find_closest_nsec(&search, nodep, foundname,
|
||||
rdataset, sigrdataset,
|
||||
search.rbtdb->secure);
|
||||
search.rbtdb->secure ==
|
||||
dns_db_secure);
|
||||
if (result == ISC_R_SUCCESS)
|
||||
result = DNS_R_EMPTYWILD;
|
||||
goto tree_exit;
|
||||
@ -3256,7 +3329,7 @@ zone_find(dns_db_t *db, dns_name_t *name, dns_dbversion_t *version,
|
||||
new_reference(search.rbtdb, node);
|
||||
*nodep = node;
|
||||
}
|
||||
if (search.rbtdb->secure ||
|
||||
if (search.rbtdb->secure == dns_db_secure ||
|
||||
(search.options & DNS_DBFIND_FORCENSEC) != 0)
|
||||
{
|
||||
bind_rdataset(search.rbtdb, node, nsecheader,
|
||||
@ -4545,11 +4618,13 @@ printnode(dns_db_t *db, dns_dbnode_t *node, FILE *out) {
|
||||
first = ISC_FALSE;
|
||||
fprintf(out,
|
||||
"\tserial = %lu, ttl = %u, "
|
||||
"trust = %u, attributes = %u\n",
|
||||
"trust = %u, attributes = %u, "
|
||||
"resign = %u\n",
|
||||
(unsigned long)current->serial,
|
||||
current->rdh_ttl,
|
||||
current->trust,
|
||||
current->attributes);
|
||||
current->attributes,
|
||||
current->resign);
|
||||
current = current->down;
|
||||
} while (current != NULL);
|
||||
}
|
||||
@ -4941,6 +5016,16 @@ cachestat_update(dns_rbtdb_t *rbtdb, rdatasetheader_t *header) {
|
||||
}
|
||||
#endif
|
||||
|
||||
static isc_result_t
|
||||
resign_insert(dns_rbtdb_t *rbtdb, int idx, rdatasetheader_t *newheader) {
|
||||
isc_result_t result;
|
||||
|
||||
INSIST(newheader->heap_index == 0);
|
||||
INSIST(!ISC_LINK_LINKED(newheader, lru_link));
|
||||
result = isc_heap_insert(rbtdb->heaps[idx], newheader);
|
||||
return (result);
|
||||
}
|
||||
|
||||
static isc_result_t
|
||||
add(dns_rbtdb_t *rbtdb, dns_rbtnode_t *rbtnode, rbtdb_version_t *rbtversion,
|
||||
rdatasetheader_t *newheader, unsigned int options, isc_boolean_t loading,
|
||||
@ -4956,6 +5041,7 @@ add(dns_rbtdb_t *rbtdb, dns_rbtnode_t *rbtnode, rbtdb_version_t *rbtversion,
|
||||
dns_rdatatype_t rdtype, covers;
|
||||
rbtdb_rdatatype_t negtype;
|
||||
dns_trust_t trust;
|
||||
int idx;
|
||||
|
||||
/*
|
||||
* Add an rdatasetheader_t to a node.
|
||||
@ -5158,6 +5244,10 @@ add(dns_rbtdb_t *rbtdb, dns_rbtnode_t *rbtnode, rbtdb_version_t *rbtversion,
|
||||
free_rdataset(rbtdb, rbtdb->common.mctx,
|
||||
newheader);
|
||||
newheader = (rdatasetheader_t *)merged;
|
||||
if (loading && RESIGN(newheader) &&
|
||||
RESIGN(header) &&
|
||||
header->resign < newheader->resign)
|
||||
newheader->resign = header->resign;
|
||||
} else {
|
||||
free_rdataset(rbtdb, rbtdb->common.mctx,
|
||||
newheader);
|
||||
@ -5250,12 +5340,10 @@ add(dns_rbtdb_t *rbtdb, dns_rbtnode_t *rbtnode, rbtdb_version_t *rbtversion,
|
||||
set_ttl(rbtdb, header, 0);
|
||||
header->attributes |= RDATASET_ATTR_STALE;
|
||||
}
|
||||
idx = newheader->node->locknum;
|
||||
if (IS_CACHE(rbtdb)) {
|
||||
int idx = newheader->node->locknum;
|
||||
|
||||
ISC_LIST_PREPEND(rbtdb->rdatasets[idx],
|
||||
newheader, lru_link);
|
||||
|
||||
/*
|
||||
* XXXMLG We don't check the return value
|
||||
* here. If it fails, we will not do TTL
|
||||
@ -5264,10 +5352,11 @@ add(dns_rbtdb_t *rbtdb, dns_rbtnode_t *rbtnode, rbtdb_version_t *rbtversion,
|
||||
* will not leak... for long.
|
||||
*/
|
||||
isc_heap_insert(rbtdb->heaps[idx], newheader);
|
||||
}
|
||||
#ifdef LRU_DEBUG
|
||||
cachestat_update(rbtdb, newheader);
|
||||
#endif
|
||||
} else if (RESIGN(newheader))
|
||||
resign_insert(rbtdb, idx, newheader);
|
||||
}
|
||||
} else {
|
||||
/*
|
||||
@ -5313,15 +5402,17 @@ add(dns_rbtdb_t *rbtdb, dns_rbtnode_t *rbtnode, rbtdb_version_t *rbtversion,
|
||||
newheader->down = NULL;
|
||||
rbtnode->data = newheader;
|
||||
}
|
||||
idx = newheader->node->locknum;
|
||||
if (IS_CACHE(rbtdb)) {
|
||||
int idx = newheader->node->locknum;
|
||||
ISC_LIST_PREPEND(rbtdb->rdatasets[idx],
|
||||
newheader, lru_link);
|
||||
isc_heap_insert(rbtdb->heaps[idx], newheader);
|
||||
}
|
||||
#ifdef LRU_DEBUG
|
||||
cachestat_update(rbtdb, newheader);
|
||||
#endif
|
||||
} else if (RESIGN(newheader)) {
|
||||
resign_insert(rbtdb, idx, newheader);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
@ -5446,8 +5537,14 @@ addrdataset(dns_db_t *db, dns_dbnode_t *node, dns_dbversion_t *version,
|
||||
if (rbtversion != NULL) {
|
||||
newheader->serial = rbtversion->serial;
|
||||
now = 0;
|
||||
if ((rdataset->attributes & DNS_RDATASETATTR_RESIGN) != 0) {
|
||||
newheader->attributes |= RDATASET_ATTR_RESIGN;
|
||||
newheader->resign = rdataset->resign;
|
||||
} else
|
||||
newheader->resign = 0;
|
||||
} else {
|
||||
newheader->serial = 1;
|
||||
newheader->resign = 0;
|
||||
if ((rdataset->attributes & DNS_RDATASETATTR_NXDOMAIN) != 0)
|
||||
newheader->attributes |= RDATASET_ATTR_NXDOMAIN;
|
||||
if ((rdataset->attributes & DNS_RDATASETATTR_NOQNAME) != 0) {
|
||||
@ -5595,6 +5692,11 @@ subtractrdataset(dns_db_t *db, dns_dbnode_t *node, dns_dbversion_t *version,
|
||||
newheader->additional_glue = NULL;
|
||||
newheader->last_used = 0;
|
||||
newheader->node = rbtnode;
|
||||
if ((rdataset->attributes & DNS_RDATASETATTR_RESIGN) != 0) {
|
||||
newheader->attributes |= RDATASET_ATTR_RESIGN;
|
||||
newheader->resign = rdataset->resign;
|
||||
} else
|
||||
newheader->resign = 0;
|
||||
|
||||
NODE_LOCK(&rbtdb->node_locks[rbtnode->locknum].lock,
|
||||
isc_rwlocktype_write);
|
||||
@ -5644,6 +5746,7 @@ subtractrdataset(dns_db_t *db, dns_dbnode_t *node, dns_dbversion_t *version,
|
||||
if (result == ISC_R_SUCCESS) {
|
||||
free_rdataset(rbtdb, rbtdb->common.mctx, newheader);
|
||||
newheader = (rdatasetheader_t *)subresult;
|
||||
init_rdataset(rbtdb, newheader);
|
||||
/*
|
||||
* We have to set the serial since the rdataslab
|
||||
* subtraction routine copies the reserved portion of
|
||||
@ -5849,9 +5952,13 @@ loading_addrdataset(void *arg, dns_name_t *name, dns_rdataset_t *rdataset) {
|
||||
newheader->count = init_count++;
|
||||
newheader->additional_auth = NULL;
|
||||
newheader->additional_glue = NULL;
|
||||
/* won't be used, but initialize anyway */
|
||||
newheader->last_used = 0;
|
||||
newheader->node = node;
|
||||
if ((rdataset->attributes & DNS_RDATASETATTR_RESIGN) != 0) {
|
||||
newheader->attributes |= RDATASET_ATTR_RESIGN;
|
||||
newheader->resign = rdataset->resign;
|
||||
} else
|
||||
newheader->resign = 0;
|
||||
|
||||
result = add(rbtdb, node, rbtdb->current_version, newheader,
|
||||
DNS_DBADD_MERGE, ISC_TRUE, NULL, 0);
|
||||
@ -5966,12 +6073,28 @@ issecure(dns_db_t *db) {
|
||||
REQUIRE(VALID_RBTDB(rbtdb));
|
||||
|
||||
RWLOCK(&rbtdb->tree_lock, isc_rwlocktype_read);
|
||||
secure = rbtdb->secure;
|
||||
secure = ISC_TF(rbtdb->secure == dns_db_secure);
|
||||
RWUNLOCK(&rbtdb->tree_lock, isc_rwlocktype_read);
|
||||
|
||||
return (secure);
|
||||
}
|
||||
|
||||
static isc_boolean_t
|
||||
isdnssec(dns_db_t *db) {
|
||||
dns_rbtdb_t *rbtdb;
|
||||
isc_boolean_t dnssec;
|
||||
|
||||
rbtdb = (dns_rbtdb_t *)db;
|
||||
|
||||
REQUIRE(VALID_RBTDB(rbtdb));
|
||||
|
||||
RWLOCK(&rbtdb->tree_lock, isc_rwlocktype_read);
|
||||
dnssec = ISC_TF(rbtdb->secure != dns_db_insecure);
|
||||
RWUNLOCK(&rbtdb->tree_lock, isc_rwlocktype_read);
|
||||
|
||||
return (dnssec);
|
||||
}
|
||||
|
||||
static unsigned int
|
||||
nodecount(dns_db_t *db) {
|
||||
dns_rbtdb_t *rbtdb;
|
||||
@ -6035,6 +6158,125 @@ getoriginnode(dns_db_t *db, dns_dbnode_t **nodep) {
|
||||
return (result);
|
||||
}
|
||||
|
||||
static isc_result_t
|
||||
setsigningtime(dns_db_t *db, dns_rdataset_t *rdataset, isc_stdtime_t resign) {
|
||||
dns_rbtdb_t *rbtdb = (dns_rbtdb_t *)db;
|
||||
isc_stdtime_t oldresign;
|
||||
isc_result_t result = ISC_R_SUCCESS;
|
||||
rdatasetheader_t *header;
|
||||
|
||||
REQUIRE(VALID_RBTDB(rbtdb));
|
||||
REQUIRE(!IS_CACHE(rbtdb));
|
||||
REQUIRE(rdataset != NULL);
|
||||
|
||||
header = rdataset->private3;
|
||||
header--;
|
||||
|
||||
NODE_LOCK(&rbtdb->node_locks[header->node->locknum].lock,
|
||||
isc_rwlocktype_write);
|
||||
|
||||
oldresign = header->resign;
|
||||
header->resign = resign;
|
||||
if (header->heap_index != 0) {
|
||||
INSIST(RESIGN(header));
|
||||
if (resign == 0) {
|
||||
isc_heap_delete(rbtdb->heaps[header->node->locknum],
|
||||
header->heap_index);
|
||||
header->heap_index = 0;
|
||||
} else if (resign < oldresign)
|
||||
isc_heap_increased(rbtdb->heaps[header->node->locknum],
|
||||
header->heap_index);
|
||||
else
|
||||
isc_heap_decreased(rbtdb->heaps[header->node->locknum],
|
||||
header->heap_index);
|
||||
} else if (resign && header->heap_index == 0) {
|
||||
header->attributes |= RDATASET_ATTR_RESIGN;
|
||||
result = resign_insert(rbtdb, header->node->locknum, header);
|
||||
}
|
||||
NODE_UNLOCK(&rbtdb->node_locks[header->node->locknum].lock,
|
||||
isc_rwlocktype_write);
|
||||
return (result);
|
||||
}
|
||||
|
||||
static isc_result_t
|
||||
getsigningtime(dns_db_t *db, dns_rdataset_t *rdataset,
|
||||
dns_name_t *foundname)
|
||||
{
|
||||
dns_rbtdb_t *rbtdb = (dns_rbtdb_t *)db;
|
||||
rdatasetheader_t *header = NULL, *this;
|
||||
unsigned int i;
|
||||
isc_result_t result = ISC_R_NOTFOUND;
|
||||
|
||||
REQUIRE(VALID_RBTDB(rbtdb));
|
||||
|
||||
RBTDB_LOCK(&rbtdb->lock, isc_rwlocktype_read);
|
||||
|
||||
for (i = 0; i < rbtdb->node_lock_count; i++) {
|
||||
this = isc_heap_element(rbtdb->heaps[i], 1);
|
||||
if (this == NULL)
|
||||
continue;
|
||||
if (header == NULL)
|
||||
header = this;
|
||||
else if (isc_serial_lt(this->resign, header->resign))
|
||||
header = this;
|
||||
}
|
||||
|
||||
if (header == NULL)
|
||||
goto unlock;
|
||||
|
||||
NODE_LOCK(&rbtdb->node_locks[header->node->locknum].lock,
|
||||
isc_rwlocktype_read);
|
||||
|
||||
bind_rdataset(rbtdb, header->node, header, 0, rdataset);
|
||||
|
||||
if (foundname != NULL)
|
||||
dns_rbt_fullnamefromnode(header->node, foundname);
|
||||
|
||||
NODE_UNLOCK(&rbtdb->node_locks[header->node->locknum].lock,
|
||||
isc_rwlocktype_read);
|
||||
|
||||
result = ISC_R_SUCCESS;
|
||||
|
||||
unlock:
|
||||
RBTDB_UNLOCK(&rbtdb->lock, isc_rwlocktype_read);
|
||||
|
||||
return (result);
|
||||
}
|
||||
|
||||
static void
|
||||
resigned(dns_db_t *db, dns_rdataset_t *rdataset, dns_dbversion_t *version)
|
||||
{
|
||||
rbtdb_version_t *rbtversion = (rbtdb_version_t *)version;
|
||||
dns_rbtdb_t *rbtdb = (dns_rbtdb_t *)db;
|
||||
dns_rbtnode_t *node;
|
||||
rdatasetheader_t *header;
|
||||
|
||||
REQUIRE(VALID_RBTDB(rbtdb));
|
||||
REQUIRE(rdataset != NULL);
|
||||
REQUIRE(rbtdb->future_version == rbtversion);
|
||||
REQUIRE(rbtversion->writer);
|
||||
|
||||
node = rdataset->private2;
|
||||
header = rdataset->private3;
|
||||
header--;
|
||||
|
||||
RBTDB_LOCK(&rbtdb->lock, isc_rwlocktype_read);
|
||||
NODE_LOCK(&rbtdb->node_locks[node->locknum].lock,
|
||||
isc_rwlocktype_write);
|
||||
/*
|
||||
* Delete from heap and save to re-signed list so that it can
|
||||
* be restored if we backout of this change.
|
||||
*/
|
||||
new_reference(rbtdb, node);
|
||||
isc_heap_delete(rbtdb->heaps[node->locknum], header->heap_index);
|
||||
header->heap_index = 0;
|
||||
ISC_LIST_APPEND(rbtversion->resigned_list, header, lru_link);
|
||||
|
||||
NODE_UNLOCK(&rbtdb->node_locks[node->locknum].lock,
|
||||
isc_rwlocktype_write);
|
||||
RBTDB_UNLOCK(&rbtdb->lock, isc_rwlocktype_read);
|
||||
}
|
||||
|
||||
static dns_dbmethods_t zone_methods = {
|
||||
attach,
|
||||
detach,
|
||||
@ -6065,6 +6307,10 @@ static dns_dbmethods_t zone_methods = {
|
||||
settask,
|
||||
getoriginnode,
|
||||
NULL,
|
||||
setsigningtime,
|
||||
getsigningtime,
|
||||
resigned,
|
||||
isdnssec,
|
||||
};
|
||||
|
||||
static dns_dbmethods_t cache_methods = {
|
||||
@ -6096,7 +6342,11 @@ static dns_dbmethods_t cache_methods = {
|
||||
overmem,
|
||||
settask,
|
||||
getoriginnode,
|
||||
NULL
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
isdnssec
|
||||
};
|
||||
|
||||
isc_result_t
|
||||
@ -6168,6 +6418,9 @@ dns_rbtdb_create
|
||||
}
|
||||
for (i = 0; i < (int)rbtdb->node_lock_count; i++)
|
||||
ISC_LIST_INIT(rbtdb->rdatasets[i]);
|
||||
} else {
|
||||
rbtdb->rdatasets = NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
* Create the heaps.
|
||||
@ -6180,17 +6433,18 @@ dns_rbtdb_create
|
||||
}
|
||||
for (i = 0; i < (int)rbtdb->node_lock_count; i++)
|
||||
rbtdb->heaps[i] = NULL;
|
||||
|
||||
for (i = 0; i < (int)rbtdb->node_lock_count; i++) {
|
||||
result = isc_heap_create(mctx, ttl_sooner,
|
||||
ttl_set_index, 0,
|
||||
if (IS_CACHE(rbtdb))
|
||||
result = isc_heap_create(mctx, ttl_sooner, set_index,
|
||||
0, &rbtdb->heaps[i]);
|
||||
else
|
||||
result = isc_heap_create(mctx, resign_sooner,
|
||||
set_index, 0,
|
||||
&rbtdb->heaps[i]);
|
||||
if (result != ISC_R_SUCCESS)
|
||||
goto cleanup_heaps;
|
||||
}
|
||||
} else {
|
||||
rbtdb->rdatasets = NULL;
|
||||
rbtdb->heaps = NULL;
|
||||
}
|
||||
|
||||
rbtdb->deadnodes = isc_mem_get(mctx, rbtdb->node_lock_count *
|
||||
sizeof(rbtnodelist_t));
|
||||
@ -6297,7 +6551,7 @@ dns_rbtdb_create
|
||||
return (result);
|
||||
}
|
||||
rbtdb->attributes = 0;
|
||||
rbtdb->secure = ISC_FALSE;
|
||||
rbtdb->secure = dns_db_insecure;
|
||||
rbtdb->overmem = ISC_FALSE;
|
||||
rbtdb->task = NULL;
|
||||
|
||||
@ -6446,7 +6700,9 @@ rdataset_current(dns_rdataset_t *rdataset, dns_rdata_t *rdata) {
|
||||
#if DNS_RDATASET_FIXED
|
||||
unsigned int offset;
|
||||
#endif
|
||||
unsigned int length;
|
||||
isc_region_t r;
|
||||
unsigned int flags = 0;
|
||||
|
||||
REQUIRE(raw != NULL);
|
||||
|
||||
@ -6462,15 +6718,25 @@ rdataset_current(dns_rdataset_t *rdataset, dns_rdata_t *rdata) {
|
||||
raw += offset;
|
||||
}
|
||||
#endif
|
||||
r.length = raw[0] * 256 + raw[1];
|
||||
|
||||
length = raw[0] * 256 + raw[1];
|
||||
#if DNS_RDATASET_FIXED
|
||||
raw += 4;
|
||||
#else
|
||||
raw += 2;
|
||||
#endif
|
||||
if (rdataset->type == dns_rdatatype_rrsig) {
|
||||
flags = ((*raw & DNS_RDATASLAB_WARNMASK)
|
||||
>> DNS_RDATASLAB_WARNSHIFT)
|
||||
<< DNS_RDATA_WARNSHIFT;
|
||||
if (*raw & DNS_RDATASLAB_OFFLINE)
|
||||
flags |= DNS_RDATA_OFFLINE;
|
||||
length--;
|
||||
raw++;
|
||||
}
|
||||
r.length = length;
|
||||
r.base = raw;
|
||||
dns_rdata_fromregion(rdata, rdataset->rdclass, rdataset->type, &r);
|
||||
rdata->flags |= flags;
|
||||
}
|
||||
|
||||
static void
|
||||
@ -7539,6 +7805,8 @@ static void
|
||||
update_header(dns_rbtdb_t *rbtdb, rdatasetheader_t *header,
|
||||
isc_stdtime_t now)
|
||||
{
|
||||
INSIST(IS_CACHE(rbtdb));
|
||||
|
||||
/* To be checked: can we really assume this? XXXMLG */
|
||||
INSIST(ISC_LINK_LINKED(header, lru_link));
|
||||
|
||||
|
@ -15,7 +15,7 @@
|
||||
* PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
/* $Id: rdata.c,v 1.196 2007/06/19 23:47:16 tbox Exp $ */
|
||||
/* $Id: rdata.c,v 1.197 2008/04/01 01:37:25 marka Exp $ */
|
||||
|
||||
/*! \file */
|
||||
|
||||
@ -269,7 +269,7 @@ dns_rdata_init(dns_rdata_t *rdata) {
|
||||
/* ISC_LIST_INIT(rdata->list); */
|
||||
}
|
||||
|
||||
#if 0
|
||||
#if 1
|
||||
#define DNS_RDATA_INITIALIZED(rdata) \
|
||||
((rdata)->data == NULL && (rdata)->length == 0 && \
|
||||
(rdata)->rdclass == 0 && (rdata)->type == 0 && (rdata)->flags == 0 && \
|
||||
@ -282,8 +282,9 @@ dns_rdata_init(dns_rdata_t *rdata) {
|
||||
#define DNS_RDATA_INITIALIZED(rdata) ISC_TRUE
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#define DNS_RDATA_VALIDFLAGS(rdata) \
|
||||
(((rdata)->flags & ~DNS_RDATA_UPDATE) == 0)
|
||||
(((rdata)->flags & ~(DNS_RDATA_UPDATE|DNS_RDATA_OFFLINE)) == 0)
|
||||
|
||||
void
|
||||
dns_rdata_reset(dns_rdata_t *rdata) {
|
||||
|
@ -15,7 +15,7 @@
|
||||
* PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
/* $Id: rdataset.c,v 1.79 2007/06/19 23:47:16 tbox Exp $ */
|
||||
/* $Id: rdataset.c,v 1.80 2008/04/01 01:37:25 marka Exp $ */
|
||||
|
||||
/*! \file */
|
||||
|
||||
@ -59,6 +59,7 @@ dns_rdataset_init(dns_rdataset_t *rdataset) {
|
||||
rdataset->privateuint4 = 0;
|
||||
rdataset->private5 = NULL;
|
||||
rdataset->private6 = NULL;
|
||||
rdataset->resign = 0;
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -15,7 +15,7 @@
|
||||
* PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
/* $Id: rdataslab.c,v 1.43 2007/06/18 23:47:41 tbox Exp $ */
|
||||
/* $Id: rdataslab.c,v 1.44 2008/04/01 01:37:25 marka Exp $ */
|
||||
|
||||
/*! \file */
|
||||
|
||||
@ -47,6 +47,7 @@
|
||||
* data records
|
||||
* data length (2 bytes)
|
||||
* order (2 bytes)
|
||||
* meta data (1 byte for RRSIG's)
|
||||
* data (data length bytes)
|
||||
*
|
||||
* If DNS_RDATASET_FIXED is defined to be zero (0) the format of a
|
||||
@ -141,6 +142,7 @@ dns_rdataslab_fromrdataset(dns_rdataset_t *rdataset, isc_mem_t *mctx,
|
||||
#if DNS_RDATASET_FIXED
|
||||
unsigned int *offsettable;
|
||||
#endif
|
||||
unsigned int length;
|
||||
|
||||
buflen = reservelen + 2;
|
||||
|
||||
@ -169,6 +171,8 @@ dns_rdataslab_fromrdataset(dns_rdataset_t *rdataset, isc_mem_t *mctx,
|
||||
#if DNS_RDATASET_FIXED
|
||||
x[i].order = i;
|
||||
#endif
|
||||
if (x[i].rdata.flags & DNS_RDATA_OFFLINE)
|
||||
fprintf(stderr, "OFFLINE\n");
|
||||
result = dns_rdataset_next(rdataset);
|
||||
}
|
||||
if (result != ISC_R_NOMORE)
|
||||
@ -209,12 +213,18 @@ dns_rdataslab_fromrdataset(dns_rdataset_t *rdataset, isc_mem_t *mctx,
|
||||
x[i].order = x[i-1].order;
|
||||
#endif
|
||||
nitems--;
|
||||
} else
|
||||
} else {
|
||||
#if DNS_RDATASET_FIXED
|
||||
buflen += (8 + x[i-1].rdata.length);
|
||||
#else
|
||||
buflen += (2 + x[i-1].rdata.length);
|
||||
#endif
|
||||
/*
|
||||
* Provide space to store the per RR meta data.
|
||||
*/
|
||||
if (rdataset->type == dns_rdatatype_rrsig)
|
||||
buflen++;
|
||||
}
|
||||
}
|
||||
/*
|
||||
* Don't forget the last item!
|
||||
@ -224,6 +234,11 @@ dns_rdataslab_fromrdataset(dns_rdataset_t *rdataset, isc_mem_t *mctx,
|
||||
#else
|
||||
buflen += (2 + x[i-1].rdata.length);
|
||||
#endif
|
||||
/*
|
||||
* Provide space to store the per RR meta data.
|
||||
*/
|
||||
if (rdataset->type == dns_rdatatype_rrsig)
|
||||
buflen++;
|
||||
|
||||
/*
|
||||
* Ensure that singleton types are actually singletons.
|
||||
@ -280,11 +295,26 @@ dns_rdataslab_fromrdataset(dns_rdataset_t *rdataset, isc_mem_t *mctx,
|
||||
#if DNS_RDATASET_FIXED
|
||||
offsettable[x[i].order] = rawbuf - offsetbase;
|
||||
#endif
|
||||
*rawbuf++ = (x[i].rdata.length & 0xff00) >> 8;
|
||||
*rawbuf++ = (x[i].rdata.length & 0x00ff);
|
||||
length = x[i].rdata.length;
|
||||
if (rdataset->type == dns_rdatatype_rrsig)
|
||||
length++;
|
||||
*rawbuf++ = (length & 0xff00) >> 8;
|
||||
*rawbuf++ = (length & 0x00ff);
|
||||
#if DNS_RDATASET_FIXED
|
||||
rawbuf += 2; /* filled in later */
|
||||
#endif
|
||||
/*
|
||||
* Store the per RR meta data.
|
||||
*/
|
||||
if (rdataset->type == dns_rdatatype_rrsig) {
|
||||
*rawbuf = ((x[i].rdata.flags & DNS_RDATA_WARNMASK)
|
||||
>> DNS_RDATA_WARNSHIFT)
|
||||
<< DNS_RDATASLAB_WARNSHIFT;
|
||||
*rawbuf++ |= (x[i].rdata.flags & DNS_RDATA_OFFLINE) ?
|
||||
DNS_RDATASLAB_OFFLINE : 0;
|
||||
if (x[i].rdata.flags & DNS_RDATA_OFFLINE)
|
||||
fprintf(stderr, "set DNS_RDATASLAB_OFFLINE\n");
|
||||
}
|
||||
memcpy(rawbuf, x[i].rdata.data, x[i].rdata.length);
|
||||
rawbuf += x[i].rdata.length;
|
||||
}
|
||||
@ -360,17 +390,30 @@ static void
|
||||
rdataset_current(dns_rdataset_t *rdataset, dns_rdata_t *rdata) {
|
||||
unsigned char *raw = rdataset->private5;
|
||||
isc_region_t r;
|
||||
unsigned int length;
|
||||
unsigned int flags = 0;
|
||||
|
||||
REQUIRE(raw != NULL);
|
||||
|
||||
r.length = raw[0] * 256 + raw[1];
|
||||
length = raw[0] * 256 + raw[1];
|
||||
#if DNS_RDATASET_FIXED
|
||||
raw += 4;
|
||||
#else
|
||||
raw += 2;
|
||||
#endif
|
||||
if (rdataset->type == dns_rdatatype_rrsig) {
|
||||
flags = ((*raw & DNS_RDATASLAB_WARNMASK)
|
||||
>> DNS_RDATASLAB_WARNSHIFT)
|
||||
<< DNS_RDATA_WARNSHIFT;
|
||||
if (*raw & DNS_RDATASLAB_OFFLINE)
|
||||
flags |= DNS_RDATA_OFFLINE;
|
||||
length--;
|
||||
raw++;
|
||||
}
|
||||
r.length = length;
|
||||
r.base = raw;
|
||||
dns_rdata_fromregion(rdata, rdataset->rdclass, rdataset->type, &r);
|
||||
rdata->flags |= flags;
|
||||
}
|
||||
|
||||
static void
|
||||
@ -474,15 +517,29 @@ rdata_from_slab(unsigned char **current,
|
||||
{
|
||||
unsigned char *tcurrent = *current;
|
||||
isc_region_t region;
|
||||
unsigned int length;
|
||||
isc_boolean_t offline = ISC_FALSE;
|
||||
|
||||
region.length = *tcurrent++ * 256;
|
||||
region.length += *tcurrent++;
|
||||
length = *tcurrent++ * 256;
|
||||
length += *tcurrent++;
|
||||
|
||||
if (type == dns_rdatatype_rrsig) {
|
||||
if ((*tcurrent & DNS_RDATASLAB_OFFLINE) != 0)
|
||||
offline = ISC_TRUE;
|
||||
length--;
|
||||
tcurrent++;
|
||||
}
|
||||
region.length = length;
|
||||
#if DNS_RDATASET_FIXED
|
||||
tcurrent += 2;
|
||||
#endif
|
||||
region.base = tcurrent;
|
||||
tcurrent += region.length;
|
||||
dns_rdata_fromregion(rdata, rdclass, type, ®ion);
|
||||
if (offline) {
|
||||
rdata->flags |= DNS_RDATA_OFFLINE;
|
||||
fprintf(stderr, "rdata_from_slab: DNS_RDATA_OFFLINE\n");
|
||||
}
|
||||
*current = tcurrent;
|
||||
}
|
||||
|
||||
@ -528,9 +585,8 @@ dns_rdataslab_merge(unsigned char *oslab, unsigned char *nslab,
|
||||
dns_rdataclass_t rdclass, dns_rdatatype_t type,
|
||||
unsigned int flags, unsigned char **tslabp)
|
||||
{
|
||||
unsigned char *ocurrent, *ostart, *ncurrent, *tstart, *tcurrent;
|
||||
unsigned char *ocurrent, *ostart, *ncurrent, *tstart, *tcurrent, *data;
|
||||
unsigned int ocount, ncount, count, olength, tlength, tcount, length;
|
||||
isc_region_t nregion;
|
||||
dns_rdata_t ordata = DNS_RDATA_INIT;
|
||||
dns_rdata_t nrdata = DNS_RDATA_INIT;
|
||||
isc_boolean_t added_something = ISC_FALSE;
|
||||
@ -603,29 +659,24 @@ dns_rdataslab_merge(unsigned char *oslab, unsigned char *nslab,
|
||||
* the old slab.
|
||||
*/
|
||||
do {
|
||||
nregion.length = *ncurrent++ * 256;
|
||||
nregion.length += *ncurrent++;
|
||||
#if DNS_RDATASET_FIXED
|
||||
ncurrent += 2; /* Skip order. */
|
||||
#endif
|
||||
nregion.base = ncurrent;
|
||||
dns_rdata_init(&nrdata);
|
||||
dns_rdata_fromregion(&nrdata, rdclass, type, &nregion);
|
||||
rdata_from_slab(&ncurrent, rdclass, type, &nrdata);
|
||||
if (!rdata_in_slab(oslab, reservelen, rdclass, type, &nrdata))
|
||||
{
|
||||
/*
|
||||
* This rdata isn't in the old slab.
|
||||
*/
|
||||
#if DNS_RDATASET_FIXED
|
||||
tlength += nregion.length + 8;
|
||||
tlength += nrdata.length + 8;
|
||||
#else
|
||||
tlength += nregion.length + 2;
|
||||
tlength += nrdata.length + 2;
|
||||
#endif
|
||||
if (type == dns_rdatatype_rrsig)
|
||||
tlength++;
|
||||
tcount++;
|
||||
nncount++;
|
||||
added_something = ISC_TRUE;
|
||||
}
|
||||
ncurrent += nregion.length;
|
||||
ncount--;
|
||||
} while (ncount > 0);
|
||||
ncount = nncount;
|
||||
@ -726,12 +777,17 @@ dns_rdataslab_merge(unsigned char *oslab, unsigned char *nslab,
|
||||
offsettable[oorder] = tcurrent - offsetbase;
|
||||
#endif
|
||||
length = ordata.length;
|
||||
data = ordata.data;
|
||||
if (type == dns_rdatatype_rrsig) {
|
||||
length++;
|
||||
data--;
|
||||
}
|
||||
*tcurrent++ = (length & 0xff00) >> 8;
|
||||
*tcurrent++ = (length & 0x00ff);
|
||||
#if DNS_RDATASET_FIXED
|
||||
tcurrent += 2; /* fill in later */
|
||||
#endif
|
||||
memcpy(tcurrent, ordata.data, length);
|
||||
memcpy(tcurrent, data, length);
|
||||
tcurrent += length;
|
||||
oadded++;
|
||||
if (oadded < ocount) {
|
||||
@ -748,12 +804,17 @@ dns_rdataslab_merge(unsigned char *oslab, unsigned char *nslab,
|
||||
offsettable[ocount + norder] = tcurrent - offsetbase;
|
||||
#endif
|
||||
length = nrdata.length;
|
||||
data = nrdata.data;
|
||||
if (type == dns_rdatatype_rrsig) {
|
||||
length++;
|
||||
data--;
|
||||
}
|
||||
*tcurrent++ = (length & 0xff00) >> 8;
|
||||
*tcurrent++ = (length & 0x00ff);
|
||||
#if DNS_RDATASET_FIXED
|
||||
tcurrent += 2; /* fill in later */
|
||||
#endif
|
||||
memcpy(tcurrent, nrdata.data, length);
|
||||
memcpy(tcurrent, data, length);
|
||||
tcurrent += length;
|
||||
nadded++;
|
||||
if (nadded < ncount) {
|
||||
|
@ -15,7 +15,7 @@
|
||||
* PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
/* $Id: rootns.c,v 1.34 2008/02/05 23:47:08 tbox Exp $ */
|
||||
/* $Id: rootns.c,v 1.35 2008/04/01 01:37:25 marka Exp $ */
|
||||
|
||||
/*! \file */
|
||||
|
||||
@ -97,6 +97,7 @@ in_rootns(dns_rdataset_t *rootns, dns_name_t *name) {
|
||||
if (dns_name_compare(name, &ns.name) == 0)
|
||||
return (ISC_R_SUCCESS);
|
||||
result = dns_rdataset_next(rootns);
|
||||
dns_rdata_reset(&rdata);
|
||||
}
|
||||
if (result == ISC_R_NOMORE)
|
||||
result = ISC_R_NOTFOUND;
|
||||
@ -338,6 +339,7 @@ check_address_records(dns_view_t *view, dns_db_t *hints, dns_db_t *db,
|
||||
(rresult == ISC_R_SUCCESS || rresult == DNS_R_GLUE)) {
|
||||
result = dns_rdataset_first(&rootrrset);
|
||||
while (result == ISC_R_SUCCESS) {
|
||||
dns_rdata_reset(&rdata);
|
||||
dns_rdataset_current(&rootrrset, &rdata);
|
||||
if (!inrrset(&hintrrset, &rdata))
|
||||
report(view, name, ISC_TRUE, &rdata);
|
||||
@ -345,6 +347,7 @@ check_address_records(dns_view_t *view, dns_db_t *hints, dns_db_t *db,
|
||||
}
|
||||
result = dns_rdataset_first(&hintrrset);
|
||||
while (result == ISC_R_SUCCESS) {
|
||||
dns_rdata_reset(&rdata);
|
||||
dns_rdataset_current(&hintrrset, &rdata);
|
||||
if (!inrrset(&rootrrset, &rdata))
|
||||
report(view, name, ISC_FALSE, &rdata);
|
||||
@ -355,6 +358,7 @@ check_address_records(dns_view_t *view, dns_db_t *hints, dns_db_t *db,
|
||||
(rresult == ISC_R_SUCCESS || rresult == DNS_R_GLUE)) {
|
||||
result = dns_rdataset_first(&rootrrset);
|
||||
while (result == ISC_R_SUCCESS) {
|
||||
dns_rdata_reset(&rdata);
|
||||
dns_rdataset_current(&rootrrset, &rdata);
|
||||
report(view, name, ISC_TRUE, &rdata);
|
||||
result = dns_rdataset_next(&rootrrset);
|
||||
@ -377,6 +381,7 @@ check_address_records(dns_view_t *view, dns_db_t *hints, dns_db_t *db,
|
||||
(rresult == ISC_R_SUCCESS || rresult == DNS_R_GLUE)) {
|
||||
result = dns_rdataset_first(&rootrrset);
|
||||
while (result == ISC_R_SUCCESS) {
|
||||
dns_rdata_reset(&rdata);
|
||||
dns_rdataset_current(&rootrrset, &rdata);
|
||||
if (!inrrset(&hintrrset, &rdata))
|
||||
report(view, name, ISC_TRUE, &rdata);
|
||||
@ -385,6 +390,7 @@ check_address_records(dns_view_t *view, dns_db_t *hints, dns_db_t *db,
|
||||
}
|
||||
result = dns_rdataset_first(&hintrrset);
|
||||
while (result == ISC_R_SUCCESS) {
|
||||
dns_rdata_reset(&rdata);
|
||||
dns_rdataset_current(&hintrrset, &rdata);
|
||||
if (!inrrset(&rootrrset, &rdata))
|
||||
report(view, name, ISC_FALSE, &rdata);
|
||||
@ -396,6 +402,7 @@ check_address_records(dns_view_t *view, dns_db_t *hints, dns_db_t *db,
|
||||
(rresult == ISC_R_SUCCESS || rresult == DNS_R_GLUE)) {
|
||||
result = dns_rdataset_first(&rootrrset);
|
||||
while (result == ISC_R_SUCCESS) {
|
||||
dns_rdata_reset(&rdata);
|
||||
dns_rdataset_current(&rootrrset, &rdata);
|
||||
report(view, name, ISC_TRUE, &rdata);
|
||||
dns_rdata_reset(&rdata);
|
||||
|
@ -15,7 +15,7 @@
|
||||
* PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
/* $Id: sdb.c,v 1.62 2008/01/18 23:46:58 tbox Exp $ */
|
||||
/* $Id: sdb.c,v 1.63 2008/04/01 01:37:25 marka Exp $ */
|
||||
|
||||
/*! \file */
|
||||
|
||||
@ -1247,6 +1247,10 @@ static dns_dbmethods_t sdb_methods = {
|
||||
overmem,
|
||||
settask,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL
|
||||
};
|
||||
|
||||
|
@ -50,7 +50,7 @@
|
||||
* USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
/* $Id: sdlz.c,v 1.14 2007/08/27 03:32:27 marka Exp $ */
|
||||
/* $Id: sdlz.c,v 1.15 2008/04/01 01:37:25 marka Exp $ */
|
||||
|
||||
/*! \file */
|
||||
|
||||
@ -1051,6 +1051,10 @@ static dns_dbmethods_t sdlzdb_methods = {
|
||||
overmem,
|
||||
settask,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL
|
||||
};
|
||||
|
||||
|
@ -16,7 +16,7 @@
|
||||
*/
|
||||
|
||||
/*
|
||||
* $Id: tsig.c,v 1.133 2008/01/18 23:46:58 tbox Exp $
|
||||
* $Id: tsig.c,v 1.134 2008/04/01 01:37:25 marka Exp $
|
||||
*/
|
||||
/*! \file */
|
||||
#include <config.h>
|
||||
@ -445,7 +445,7 @@ cleanup_ring(dns_tsig_keyring_t *ring)
|
||||
dns_rbtnodechain_current(&chain, &foundname, origin, &node);
|
||||
tkey = node->data;
|
||||
if (tkey != NULL) {
|
||||
tsig_log(tkey, 2, "tsig expire: generated=%d, refs=%d, expire=%d)", tkey->generated, isc_refcount_current(&tkey->refs), now - tkey->expire);
|
||||
tsig_log(tkey, 2, "tsig expire: generated=%d, refs=%d, expire=%d", tkey->generated, isc_refcount_current(&tkey->refs), now - tkey->expire);
|
||||
if (tkey->generated
|
||||
&& isc_refcount_current(&tkey->refs) == 1
|
||||
&& tkey->inception != tkey->expire
|
||||
|
1594
lib/dns/zone.c
1594
lib/dns/zone.c
File diff suppressed because it is too large
Load Diff
158
lib/isc/mem.c
158
lib/isc/mem.c
@ -15,7 +15,7 @@
|
||||
* PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
/* $Id: mem.c,v 1.143 2008/03/31 23:47:11 tbox Exp $ */
|
||||
/* $Id: mem.c,v 1.144 2008/04/01 01:37:25 marka Exp $ */
|
||||
|
||||
/*! \file */
|
||||
|
||||
@ -112,7 +112,7 @@ typedef ISC_LIST(debuglink_t) debuglist_t;
|
||||
|
||||
static ISC_LIST(isc_mem_t) contexts;
|
||||
static isc_once_t once = ISC_ONCE_INIT;
|
||||
static isc_mutex_t lock;
|
||||
static isc_mutex_t contextlock;
|
||||
|
||||
/*%
|
||||
* Total size of lost memory due to a bug of external library.
|
||||
@ -124,7 +124,7 @@ struct isc_mem {
|
||||
unsigned int magic;
|
||||
isc_ondestroy_t ondestroy;
|
||||
unsigned int flags;
|
||||
isc_mutex_t lock;
|
||||
isc_mutex_t memlock;
|
||||
isc_memalloc_t memalloc;
|
||||
isc_memfree_t memfree;
|
||||
void * arg;
|
||||
@ -702,7 +702,7 @@ default_memfree(void *arg, void *ptr) {
|
||||
|
||||
static void
|
||||
initialize_action(void) {
|
||||
RUNTIME_CHECK(isc_mutex_init(&lock) == ISC_R_SUCCESS);
|
||||
RUNTIME_CHECK(isc_mutex_init(&contextlock) == ISC_R_SUCCESS);
|
||||
ISC_LIST_INIT(contexts);
|
||||
totallost = 0;
|
||||
}
|
||||
@ -742,7 +742,7 @@ isc_mem_createx2(size_t init_max_size, size_t target_size,
|
||||
return (ISC_R_NOMEMORY);
|
||||
|
||||
if ((flags & ISC_MEMFLAG_NOLOCK) == 0) {
|
||||
result = isc_mutex_init(&ctx->lock);
|
||||
result = isc_mutex_init(&ctx->memlock);
|
||||
if (result != ISC_R_SUCCESS) {
|
||||
(memfree)(arg, ctx);
|
||||
return (result);
|
||||
@ -827,9 +827,9 @@ isc_mem_createx2(size_t init_max_size, size_t target_size,
|
||||
|
||||
ctx->memalloc_failures = 0;
|
||||
|
||||
LOCK(&lock);
|
||||
LOCK(&contextlock);
|
||||
ISC_LIST_INITANDAPPEND(contexts, ctx, link);
|
||||
UNLOCK(&lock);
|
||||
UNLOCK(&contextlock);
|
||||
|
||||
*ctxp = ctx;
|
||||
return (ISC_R_SUCCESS);
|
||||
@ -845,7 +845,7 @@ isc_mem_createx2(size_t init_max_size, size_t target_size,
|
||||
(ctx->memfree)(ctx->arg, ctx->debuglist);
|
||||
#endif /* ISC_MEM_TRACKLINES */
|
||||
if ((ctx->flags & ISC_MEMFLAG_NOLOCK) == 0)
|
||||
DESTROYLOCK(&ctx->lock);
|
||||
DESTROYLOCK(&ctx->memlock);
|
||||
(memfree)(arg, ctx);
|
||||
}
|
||||
|
||||
@ -877,10 +877,10 @@ destroy(isc_mem_t *ctx) {
|
||||
|
||||
ctx->magic = 0;
|
||||
|
||||
LOCK(&lock);
|
||||
LOCK(&contextlock);
|
||||
ISC_LIST_UNLINK(contexts, ctx, link);
|
||||
totallost += ctx->inuse;
|
||||
UNLOCK(&lock);
|
||||
UNLOCK(&contextlock);
|
||||
|
||||
INSIST(ISC_LIST_EMPTY(ctx->pools));
|
||||
|
||||
@ -932,7 +932,7 @@ destroy(isc_mem_t *ctx) {
|
||||
ondest = ctx->ondestroy;
|
||||
|
||||
if ((ctx->flags & ISC_MEMFLAG_NOLOCK) == 0)
|
||||
DESTROYLOCK(&ctx->lock);
|
||||
DESTROYLOCK(&ctx->memlock);
|
||||
(ctx->memfree)(ctx->arg, ctx);
|
||||
|
||||
isc_ondestroy_notify(&ondest, ctx);
|
||||
@ -943,9 +943,9 @@ isc_mem_attach(isc_mem_t *source, isc_mem_t **targetp) {
|
||||
REQUIRE(VALID_CONTEXT(source));
|
||||
REQUIRE(targetp != NULL && *targetp == NULL);
|
||||
|
||||
MCTXLOCK(source, &source->lock);
|
||||
MCTXLOCK(source, &source->memlock);
|
||||
source->references++;
|
||||
MCTXUNLOCK(source, &source->lock);
|
||||
MCTXUNLOCK(source, &source->memlock);
|
||||
|
||||
*targetp = source;
|
||||
}
|
||||
@ -959,12 +959,12 @@ isc_mem_detach(isc_mem_t **ctxp) {
|
||||
ctx = *ctxp;
|
||||
REQUIRE(VALID_CONTEXT(ctx));
|
||||
|
||||
MCTXLOCK(ctx, &ctx->lock);
|
||||
MCTXLOCK(ctx, &ctx->memlock);
|
||||
INSIST(ctx->references > 0);
|
||||
ctx->references--;
|
||||
if (ctx->references == 0)
|
||||
want_destroy = ISC_TRUE;
|
||||
MCTXUNLOCK(ctx, &ctx->lock);
|
||||
MCTXUNLOCK(ctx, &ctx->memlock);
|
||||
|
||||
if (want_destroy)
|
||||
destroy(ctx);
|
||||
@ -1010,11 +1010,11 @@ isc__mem_putanddetach(isc_mem_t **ctxp, void *ptr, size_t size FLARG) {
|
||||
}
|
||||
isc__mem_free(ctx, ptr FLARG_PASS);
|
||||
|
||||
MCTXLOCK(ctx, &ctx->lock);
|
||||
MCTXLOCK(ctx, &ctx->memlock);
|
||||
ctx->references--;
|
||||
if (ctx->references == 0)
|
||||
want_destroy = ISC_TRUE;
|
||||
MCTXUNLOCK(ctx, &ctx->lock);
|
||||
MCTXUNLOCK(ctx, &ctx->memlock);
|
||||
if (want_destroy)
|
||||
destroy(ctx);
|
||||
|
||||
@ -1022,11 +1022,11 @@ isc__mem_putanddetach(isc_mem_t **ctxp, void *ptr, size_t size FLARG) {
|
||||
}
|
||||
|
||||
if ((ctx->flags & ISC_MEMFLAG_INTERNAL) != 0) {
|
||||
MCTXLOCK(ctx, &ctx->lock);
|
||||
MCTXLOCK(ctx, &ctx->memlock);
|
||||
mem_putunlocked(ctx, ptr, size);
|
||||
} else {
|
||||
mem_put(ctx, ptr, size);
|
||||
MCTXLOCK(ctx, &ctx->lock);
|
||||
MCTXLOCK(ctx, &ctx->memlock);
|
||||
mem_putstats(ctx, ptr, size);
|
||||
}
|
||||
|
||||
@ -1036,7 +1036,7 @@ isc__mem_putanddetach(isc_mem_t **ctxp, void *ptr, size_t size FLARG) {
|
||||
if (ctx->references == 0)
|
||||
want_destroy = ISC_TRUE;
|
||||
|
||||
MCTXUNLOCK(ctx, &ctx->lock);
|
||||
MCTXUNLOCK(ctx, &ctx->memlock);
|
||||
|
||||
if (want_destroy)
|
||||
destroy(ctx);
|
||||
@ -1055,14 +1055,14 @@ isc_mem_destroy(isc_mem_t **ctxp) {
|
||||
ctx = *ctxp;
|
||||
REQUIRE(VALID_CONTEXT(ctx));
|
||||
|
||||
MCTXLOCK(ctx, &ctx->lock);
|
||||
MCTXLOCK(ctx, &ctx->memlock);
|
||||
#if ISC_MEM_TRACKLINES
|
||||
if (ctx->references != 1)
|
||||
print_active(ctx, stderr);
|
||||
#endif
|
||||
REQUIRE(ctx->references == 1);
|
||||
ctx->references--;
|
||||
MCTXUNLOCK(ctx, &ctx->lock);
|
||||
MCTXUNLOCK(ctx, &ctx->memlock);
|
||||
|
||||
destroy(ctx);
|
||||
|
||||
@ -1073,9 +1073,9 @@ isc_result_t
|
||||
isc_mem_ondestroy(isc_mem_t *ctx, isc_task_t *task, isc_event_t **event) {
|
||||
isc_result_t res;
|
||||
|
||||
MCTXLOCK(ctx, &ctx->lock);
|
||||
MCTXLOCK(ctx, &ctx->memlock);
|
||||
res = isc_ondestroy_register(&ctx->ondestroy, task, event);
|
||||
MCTXUNLOCK(ctx, &ctx->lock);
|
||||
MCTXUNLOCK(ctx, &ctx->memlock);
|
||||
|
||||
return (res);
|
||||
}
|
||||
@ -1092,11 +1092,11 @@ isc__mem_get(isc_mem_t *ctx, size_t size FLARG) {
|
||||
return (isc__mem_allocate(ctx, size FLARG_PASS));
|
||||
|
||||
if ((ctx->flags & ISC_MEMFLAG_INTERNAL) != 0) {
|
||||
MCTXLOCK(ctx, &ctx->lock);
|
||||
MCTXLOCK(ctx, &ctx->memlock);
|
||||
ptr = mem_getunlocked(ctx, size);
|
||||
} else {
|
||||
ptr = mem_get(ctx, size);
|
||||
MCTXLOCK(ctx, &ctx->lock);
|
||||
MCTXLOCK(ctx, &ctx->memlock);
|
||||
if (ptr != NULL)
|
||||
mem_getstats(ctx, size);
|
||||
}
|
||||
@ -1113,7 +1113,7 @@ isc__mem_get(isc_mem_t *ctx, size_t size FLARG) {
|
||||
fprintf(stderr, "maxinuse = %lu\n",
|
||||
(unsigned long)ctx->inuse);
|
||||
}
|
||||
MCTXUNLOCK(ctx, &ctx->lock);
|
||||
MCTXUNLOCK(ctx, &ctx->memlock);
|
||||
|
||||
if (call_water)
|
||||
(ctx->water)(ctx->water_arg, ISC_MEM_HIWATER);
|
||||
@ -1144,11 +1144,11 @@ isc__mem_put(isc_mem_t *ctx, void *ptr, size_t size FLARG)
|
||||
}
|
||||
|
||||
if ((ctx->flags & ISC_MEMFLAG_INTERNAL) != 0) {
|
||||
MCTXLOCK(ctx, &ctx->lock);
|
||||
MCTXLOCK(ctx, &ctx->memlock);
|
||||
mem_putunlocked(ctx, ptr, size);
|
||||
} else {
|
||||
mem_put(ctx, ptr, size);
|
||||
MCTXLOCK(ctx, &ctx->lock);
|
||||
MCTXLOCK(ctx, &ctx->memlock);
|
||||
mem_putstats(ctx, ptr, size);
|
||||
}
|
||||
|
||||
@ -1164,7 +1164,7 @@ isc__mem_put(isc_mem_t *ctx, void *ptr, size_t size FLARG)
|
||||
if (ctx->water != NULL)
|
||||
call_water = ISC_TRUE;
|
||||
}
|
||||
MCTXUNLOCK(ctx, &ctx->lock);
|
||||
MCTXUNLOCK(ctx, &ctx->memlock);
|
||||
|
||||
if (call_water)
|
||||
(ctx->water)(ctx->water_arg, ISC_MEM_LOWATER);
|
||||
@ -1174,12 +1174,12 @@ void
|
||||
isc_mem_waterack(isc_mem_t *ctx, int flag) {
|
||||
REQUIRE(VALID_CONTEXT(ctx));
|
||||
|
||||
MCTXLOCK(ctx, &ctx->lock);
|
||||
MCTXLOCK(ctx, &ctx->memlock);
|
||||
if (flag == ISC_MEM_LOWATER)
|
||||
ctx->hi_called = ISC_FALSE;
|
||||
else if (flag == ISC_MEM_HIWATER)
|
||||
ctx->hi_called = ISC_TRUE;
|
||||
MCTXUNLOCK(ctx, &ctx->lock);
|
||||
MCTXUNLOCK(ctx, &ctx->memlock);
|
||||
}
|
||||
|
||||
#if ISC_MEM_TRACKLINES
|
||||
@ -1233,7 +1233,7 @@ isc_mem_stats(isc_mem_t *ctx, FILE *out) {
|
||||
const isc_mempool_t *pool;
|
||||
|
||||
REQUIRE(VALID_CONTEXT(ctx));
|
||||
MCTXLOCK(ctx, &ctx->lock);
|
||||
MCTXLOCK(ctx, &ctx->memlock);
|
||||
|
||||
for (i = 0; i <= ctx->max_size; i++) {
|
||||
s = &ctx->stats[i];
|
||||
@ -1254,7 +1254,7 @@ isc_mem_stats(isc_mem_t *ctx, FILE *out) {
|
||||
* Note that since a pool can be locked now, these stats might be
|
||||
* somewhat off if the pool is in active use at the time the stats
|
||||
* are dumped. The link fields are protected by the isc_mem_t's
|
||||
* lock, however, so walking this list and extracting integers from
|
||||
* contextlock, however, so walking this list and extracting integers from
|
||||
* stats fields is always safe.
|
||||
*/
|
||||
pool = ISC_LIST_HEAD(ctx->pools);
|
||||
@ -1294,7 +1294,7 @@ isc_mem_stats(isc_mem_t *ctx, FILE *out) {
|
||||
print_active(ctx, out);
|
||||
#endif
|
||||
|
||||
MCTXUNLOCK(ctx, &ctx->lock);
|
||||
MCTXUNLOCK(ctx, &ctx->memlock);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -1333,11 +1333,11 @@ isc__mem_allocate(isc_mem_t *ctx, size_t size FLARG) {
|
||||
REQUIRE(VALID_CONTEXT(ctx));
|
||||
|
||||
if ((ctx->flags & ISC_MEMFLAG_INTERNAL) != 0) {
|
||||
MCTXLOCK(ctx, &ctx->lock);
|
||||
MCTXLOCK(ctx, &ctx->memlock);
|
||||
si = isc__mem_allocateunlocked(ctx, size);
|
||||
} else {
|
||||
si = isc__mem_allocateunlocked(ctx, size);
|
||||
MCTXLOCK(ctx, &ctx->lock);
|
||||
MCTXLOCK(ctx, &ctx->memlock);
|
||||
if (si != NULL)
|
||||
mem_getstats(ctx, si[-1].u.size);
|
||||
}
|
||||
@ -1357,7 +1357,7 @@ isc__mem_allocate(isc_mem_t *ctx, size_t size FLARG) {
|
||||
fprintf(stderr, "maxinuse = %lu\n",
|
||||
(unsigned long)ctx->inuse);
|
||||
}
|
||||
MCTXUNLOCK(ctx, &ctx->lock);
|
||||
MCTXUNLOCK(ctx, &ctx->memlock);
|
||||
|
||||
if (call_water)
|
||||
(ctx->water)(ctx->water_arg, ISC_MEM_HIWATER);
|
||||
@ -1384,11 +1384,11 @@ isc__mem_free(isc_mem_t *ctx, void *ptr FLARG) {
|
||||
}
|
||||
|
||||
if ((ctx->flags & ISC_MEMFLAG_INTERNAL) != 0) {
|
||||
MCTXLOCK(ctx, &ctx->lock);
|
||||
MCTXLOCK(ctx, &ctx->memlock);
|
||||
mem_putunlocked(ctx, si, size);
|
||||
} else {
|
||||
mem_put(ctx, si, size);
|
||||
MCTXLOCK(ctx, &ctx->lock);
|
||||
MCTXLOCK(ctx, &ctx->memlock);
|
||||
mem_putstats(ctx, si, size);
|
||||
}
|
||||
|
||||
@ -1406,7 +1406,7 @@ isc__mem_free(isc_mem_t *ctx, void *ptr FLARG) {
|
||||
if (ctx->water != NULL)
|
||||
call_water = ISC_TRUE;
|
||||
}
|
||||
MCTXUNLOCK(ctx, &ctx->lock);
|
||||
MCTXUNLOCK(ctx, &ctx->memlock);
|
||||
|
||||
if (call_water)
|
||||
(ctx->water)(ctx->water_arg, ISC_MEM_LOWATER);
|
||||
@ -1438,11 +1438,11 @@ isc__mem_strdup(isc_mem_t *mctx, const char *s FLARG) {
|
||||
void
|
||||
isc_mem_setdestroycheck(isc_mem_t *ctx, isc_boolean_t flag) {
|
||||
REQUIRE(VALID_CONTEXT(ctx));
|
||||
MCTXLOCK(ctx, &ctx->lock);
|
||||
MCTXLOCK(ctx, &ctx->memlock);
|
||||
|
||||
ctx->checkfree = flag;
|
||||
|
||||
MCTXUNLOCK(ctx, &ctx->lock);
|
||||
MCTXUNLOCK(ctx, &ctx->memlock);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -1452,11 +1452,11 @@ isc_mem_setdestroycheck(isc_mem_t *ctx, isc_boolean_t flag) {
|
||||
void
|
||||
isc_mem_setquota(isc_mem_t *ctx, size_t quota) {
|
||||
REQUIRE(VALID_CONTEXT(ctx));
|
||||
MCTXLOCK(ctx, &ctx->lock);
|
||||
MCTXLOCK(ctx, &ctx->memlock);
|
||||
|
||||
ctx->quota = quota;
|
||||
|
||||
MCTXUNLOCK(ctx, &ctx->lock);
|
||||
MCTXUNLOCK(ctx, &ctx->memlock);
|
||||
}
|
||||
|
||||
size_t
|
||||
@ -1464,11 +1464,11 @@ isc_mem_getquota(isc_mem_t *ctx) {
|
||||
size_t quota;
|
||||
|
||||
REQUIRE(VALID_CONTEXT(ctx));
|
||||
MCTXLOCK(ctx, &ctx->lock);
|
||||
MCTXLOCK(ctx, &ctx->memlock);
|
||||
|
||||
quota = ctx->quota;
|
||||
|
||||
MCTXUNLOCK(ctx, &ctx->lock);
|
||||
MCTXUNLOCK(ctx, &ctx->memlock);
|
||||
|
||||
return (quota);
|
||||
}
|
||||
@ -1478,11 +1478,11 @@ isc_mem_inuse(isc_mem_t *ctx) {
|
||||
size_t inuse;
|
||||
|
||||
REQUIRE(VALID_CONTEXT(ctx));
|
||||
MCTXLOCK(ctx, &ctx->lock);
|
||||
MCTXLOCK(ctx, &ctx->memlock);
|
||||
|
||||
inuse = ctx->inuse;
|
||||
|
||||
MCTXUNLOCK(ctx, &ctx->lock);
|
||||
MCTXUNLOCK(ctx, &ctx->memlock);
|
||||
|
||||
return (inuse);
|
||||
}
|
||||
@ -1498,7 +1498,7 @@ isc_mem_setwater(isc_mem_t *ctx, isc_mem_water_t water, void *water_arg,
|
||||
REQUIRE(VALID_CONTEXT(ctx));
|
||||
REQUIRE(hiwater >= lowater);
|
||||
|
||||
MCTXLOCK(ctx, &ctx->lock);
|
||||
MCTXLOCK(ctx, &ctx->memlock);
|
||||
oldwater = ctx->water;
|
||||
oldwater_arg = ctx->water_arg;
|
||||
if (water == NULL) {
|
||||
@ -1519,7 +1519,7 @@ isc_mem_setwater(isc_mem_t *ctx, isc_mem_water_t water, void *water_arg,
|
||||
ctx->lo_water = lowater;
|
||||
ctx->hi_called = ISC_FALSE;
|
||||
}
|
||||
MCTXUNLOCK(ctx, &ctx->lock);
|
||||
MCTXUNLOCK(ctx, &ctx->memlock);
|
||||
|
||||
if (callwater && oldwater != NULL)
|
||||
(oldwater)(oldwater_arg, ISC_MEM_LOWATER);
|
||||
@ -1529,11 +1529,11 @@ void
|
||||
isc_mem_setname(isc_mem_t *ctx, const char *name, void *tag) {
|
||||
REQUIRE(VALID_CONTEXT(ctx));
|
||||
|
||||
LOCK(&ctx->lock);
|
||||
LOCK(&ctx->memlock);
|
||||
memset(ctx->name, 0, sizeof(ctx->name));
|
||||
strncpy(ctx->name, name, sizeof(ctx->name) - 1);
|
||||
ctx->tag = tag;
|
||||
UNLOCK(&ctx->lock);
|
||||
UNLOCK(&ctx->memlock);
|
||||
}
|
||||
|
||||
const char *
|
||||
@ -1587,10 +1587,10 @@ isc_mempool_create(isc_mem_t *mctx, size_t size, isc_mempool_t **mpctxp) {
|
||||
|
||||
*mpctxp = mpctx;
|
||||
|
||||
MCTXLOCK(mctx, &mctx->lock);
|
||||
MCTXLOCK(mctx, &mctx->memlock);
|
||||
ISC_LIST_INITANDAPPEND(mctx->pools, mpctx, link);
|
||||
mctx->poolcnt++;
|
||||
MCTXUNLOCK(mctx, &mctx->lock);
|
||||
MCTXUNLOCK(mctx, &mctx->memlock);
|
||||
|
||||
return (ISC_R_SUCCESS);
|
||||
}
|
||||
@ -1643,7 +1643,7 @@ isc_mempool_destroy(isc_mempool_t **mpctxp) {
|
||||
/*
|
||||
* Return any items on the free list
|
||||
*/
|
||||
MCTXLOCK(mctx, &mctx->lock);
|
||||
MCTXLOCK(mctx, &mctx->memlock);
|
||||
while (mpctx->items != NULL) {
|
||||
INSIST(mpctx->freecount > 0);
|
||||
mpctx->freecount--;
|
||||
@ -1657,15 +1657,15 @@ isc_mempool_destroy(isc_mempool_t **mpctxp) {
|
||||
mem_putstats(mctx, item, mpctx->size);
|
||||
}
|
||||
}
|
||||
MCTXUNLOCK(mctx, &mctx->lock);
|
||||
MCTXUNLOCK(mctx, &mctx->memlock);
|
||||
|
||||
/*
|
||||
* Remove our linked list entry from the memory context.
|
||||
*/
|
||||
MCTXLOCK(mctx, &mctx->lock);
|
||||
MCTXLOCK(mctx, &mctx->memlock);
|
||||
ISC_LIST_UNLINK(mctx->pools, mpctx, link);
|
||||
mctx->poolcnt--;
|
||||
MCTXUNLOCK(mctx, &mctx->lock);
|
||||
MCTXUNLOCK(mctx, &mctx->memlock);
|
||||
|
||||
mpctx->magic = 0;
|
||||
|
||||
@ -1724,7 +1724,7 @@ isc__mempool_get(isc_mempool_t *mpctx FLARG) {
|
||||
* We need to dip into the well. Lock the memory context here and
|
||||
* fill up our free list.
|
||||
*/
|
||||
MCTXLOCK(mctx, &mctx->lock);
|
||||
MCTXLOCK(mctx, &mctx->memlock);
|
||||
for (i = 0; i < mpctx->fillcount; i++) {
|
||||
if ((mctx->flags & ISC_MEMFLAG_INTERNAL) != 0) {
|
||||
item = mem_getunlocked(mctx, mpctx->size);
|
||||
@ -1739,7 +1739,7 @@ isc__mempool_get(isc_mempool_t *mpctx FLARG) {
|
||||
mpctx->items = item;
|
||||
mpctx->freecount++;
|
||||
}
|
||||
MCTXUNLOCK(mctx, &mctx->lock);
|
||||
MCTXUNLOCK(mctx, &mctx->memlock);
|
||||
|
||||
/*
|
||||
* If we didn't get any items, return NULL.
|
||||
@ -1759,9 +1759,9 @@ isc__mempool_get(isc_mempool_t *mpctx FLARG) {
|
||||
|
||||
#if ISC_MEM_TRACKLINES
|
||||
if (item != NULL) {
|
||||
MCTXLOCK(mctx, &mctx->lock);
|
||||
MCTXLOCK(mctx, &mctx->memlock);
|
||||
ADD_TRACE(mctx, item, mpctx->size, file, line);
|
||||
MCTXUNLOCK(mctx, &mctx->lock);
|
||||
MCTXUNLOCK(mctx, &mctx->memlock);
|
||||
}
|
||||
#endif /* ISC_MEM_TRACKLINES */
|
||||
|
||||
@ -1785,9 +1785,9 @@ isc__mempool_put(isc_mempool_t *mpctx, void *mem FLARG) {
|
||||
mpctx->allocated--;
|
||||
|
||||
#if ISC_MEM_TRACKLINES
|
||||
MCTXLOCK(mctx, &mctx->lock);
|
||||
MCTXLOCK(mctx, &mctx->memlock);
|
||||
DELETE_TRACE(mctx, mem, mpctx->size, file, line);
|
||||
MCTXUNLOCK(mctx, &mctx->lock);
|
||||
MCTXUNLOCK(mctx, &mctx->memlock);
|
||||
#endif /* ISC_MEM_TRACKLINES */
|
||||
|
||||
/*
|
||||
@ -1795,14 +1795,14 @@ isc__mempool_put(isc_mempool_t *mpctx, void *mem FLARG) {
|
||||
*/
|
||||
if (mpctx->freecount >= mpctx->freemax) {
|
||||
if ((mctx->flags & ISC_MEMFLAG_INTERNAL) != 0) {
|
||||
MCTXLOCK(mctx, &mctx->lock);
|
||||
MCTXLOCK(mctx, &mctx->memlock);
|
||||
mem_putunlocked(mctx, mem, mpctx->size);
|
||||
MCTXUNLOCK(mctx, &mctx->lock);
|
||||
MCTXUNLOCK(mctx, &mctx->memlock);
|
||||
} else {
|
||||
mem_put(mctx, mem, mpctx->size);
|
||||
MCTXLOCK(mctx, &mctx->lock);
|
||||
MCTXLOCK(mctx, &mctx->memlock);
|
||||
mem_putstats(mctx, mem, mpctx->size);
|
||||
MCTXUNLOCK(mctx, &mctx->lock);
|
||||
MCTXUNLOCK(mctx, &mctx->memlock);
|
||||
}
|
||||
if (mpctx->lock != NULL)
|
||||
UNLOCK(mpctx->lock);
|
||||
@ -1975,14 +1975,14 @@ isc_mem_printallactive(FILE *file) {
|
||||
|
||||
RUNTIME_CHECK(isc_once_do(&once, initialize_action) == ISC_R_SUCCESS);
|
||||
|
||||
LOCK(&lock);
|
||||
LOCK(&contextlock);
|
||||
for (ctx = ISC_LIST_HEAD(contexts);
|
||||
ctx != NULL;
|
||||
ctx = ISC_LIST_NEXT(ctx, link)) {
|
||||
fprintf(file, "context: %p\n", ctx);
|
||||
print_active(ctx, file);
|
||||
}
|
||||
UNLOCK(&lock);
|
||||
UNLOCK(&contextlock);
|
||||
#endif
|
||||
}
|
||||
|
||||
@ -1991,7 +1991,7 @@ isc_mem_checkdestroyed(FILE *file) {
|
||||
|
||||
RUNTIME_CHECK(isc_once_do(&once, initialize_action) == ISC_R_SUCCESS);
|
||||
|
||||
LOCK(&lock);
|
||||
LOCK(&contextlock);
|
||||
if (!ISC_LIST_EMPTY(contexts)) {
|
||||
#if ISC_MEM_TRACKLINES
|
||||
isc_mem_t *ctx;
|
||||
@ -2006,7 +2006,7 @@ isc_mem_checkdestroyed(FILE *file) {
|
||||
#endif
|
||||
INSIST(0);
|
||||
}
|
||||
UNLOCK(&lock);
|
||||
UNLOCK(&contextlock);
|
||||
}
|
||||
|
||||
unsigned int
|
||||
@ -2014,9 +2014,9 @@ isc_mem_references(isc_mem_t *ctx) {
|
||||
unsigned int references;
|
||||
REQUIRE(VALID_CONTEXT(ctx));
|
||||
|
||||
MCTXLOCK(ctx, &ctx->lock);
|
||||
MCTXLOCK(ctx, &ctx->memlock);
|
||||
references = ctx->references;
|
||||
MCTXUNLOCK(ctx, &ctx->lock);
|
||||
MCTXUNLOCK(ctx, &ctx->memlock);
|
||||
|
||||
return (references);
|
||||
}
|
||||
@ -2047,7 +2047,7 @@ renderctx(isc_mem_t *ctx, summarystat_t *summary, xmlTextWriterPtr writer) {
|
||||
}
|
||||
|
||||
REQUIRE(VALID_CONTEXT(ctx));
|
||||
MCTXLOCK(ctx, &ctx->lock);
|
||||
MCTXLOCK(ctx, &ctx->memlock);
|
||||
|
||||
summary->contextsize += sizeof(*ctx) +
|
||||
(ctx->max_size + 1) * sizeof(struct stats) +
|
||||
@ -2110,7 +2110,7 @@ renderctx(isc_mem_t *ctx, summarystat_t *summary, xmlTextWriterPtr writer) {
|
||||
(isc_uint64_t)ctx->lo_water);
|
||||
xmlTextWriterEndElement(writer); /* lowater */
|
||||
|
||||
MCTXUNLOCK(ctx, &ctx->lock);
|
||||
MCTXUNLOCK(ctx, &ctx->memlock);
|
||||
|
||||
xmlTextWriterEndElement(writer); /* context */
|
||||
}
|
||||
@ -2127,14 +2127,14 @@ isc_mem_renderxml(xmlTextWriterPtr writer) {
|
||||
|
||||
RUNTIME_CHECK(isc_once_do(&once, initialize_action) == ISC_R_SUCCESS);
|
||||
|
||||
LOCK(&lock);
|
||||
LOCK(&contextlock);
|
||||
lost = totallost;
|
||||
for (ctx = ISC_LIST_HEAD(contexts);
|
||||
ctx != NULL;
|
||||
ctx = ISC_LIST_NEXT(ctx, link)) {
|
||||
renderctx(ctx, &summary, writer);
|
||||
}
|
||||
UNLOCK(&lock);
|
||||
UNLOCK(&contextlock);
|
||||
|
||||
xmlTextWriterEndElement(writer); /* contexts */
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user