2
0
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:
Mark Andrews 2008-04-01 01:37:25 +00:00
parent 28b3569d62
commit a76b380643
29 changed files with 2781 additions and 304 deletions

View File

@ -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. 2348. [func] Use the EVP interface to OpenSSL. Add PKCS#11 support.
Documentation is in the new README.pkcs11 file. Documentation is in the new README.pkcs11 file.
[RT #16844] [RT #16844]

View File

@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE. * 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 */ /*! \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, result = dns_db_find(db, name, version, type, client->query.dboptions,
client->now, &node, fname, rdataset, client->now, &node, fname, rdataset,
sigrdataset); 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; goto found;
}
if (dns_rdataset_isassociated(rdataset)) if (dns_rdataset_isassociated(rdataset))
dns_rdataset_disassociate(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; eresult = DNS_R_SERVFAIL;
goto cleanup; goto cleanup;
} }
if (WANTDNSSEC(client)) { if (WANTDNSSEC(client) && dns_db_issecure(db)) {
sigrdataset = query_newrdataset(client); sigrdataset = query_newrdataset(client);
if (sigrdataset == NULL) { if (sigrdataset == NULL) {
eresult = DNS_R_SERVFAIL; 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; eresult = DNS_R_SERVFAIL;
goto cleanup; goto cleanup;
} }
if (WANTDNSSEC(client)) { if (WANTDNSSEC(client) && dns_db_issecure(db)) {
sigrdataset = query_newrdataset(client); sigrdataset = query_newrdataset(client);
if (sigrdataset == NULL) { if (sigrdataset == NULL) {
CTRACE("query_addns: query_newrdataset failed"); 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); QUERY_ERROR(DNS_R_SERVFAIL);
goto cleanup; goto cleanup;
} }
if (WANTDNSSEC(client)) { if (WANTDNSSEC(client) && (!is_zone || dns_db_issecure(db))) {
sigrdataset = query_newrdataset(client); sigrdataset = query_newrdataset(client);
if (sigrdataset == NULL) { if (sigrdataset == NULL) {
QUERY_ERROR(DNS_R_SERVFAIL); 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); result = dns_rdatasetiter_first(rdsiter);
while (result == ISC_R_SUCCESS) { while (result == ISC_R_SUCCESS) {
dns_rdatasetiter_current(rdsiter, rdataset); 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) { rdataset->type == qtype) && rdataset->type != 0) {
query_addrrset(client, query_addrrset(client,
fname != NULL ? &fname : &tname, fname != NULL ? &fname : &tname,

View File

@ -15,12 +15,13 @@
* PERFORMANCE OF THIS SOFTWARE. * 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 <config.h>
#include <isc/netaddr.h> #include <isc/netaddr.h>
#include <isc/print.h> #include <isc/print.h>
#include <isc/serial.h>
#include <isc/string.h> #include <isc/string.h>
#include <isc/taskpool.h> #include <isc/taskpool.h>
#include <isc/util.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 * RFC2136 does not mention NSEC or DNAME, but multiple NSECs or DNAMEs
* make little sense, so we replace those, too. * 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 static isc_boolean_t
replaces_p(dns_rdata_t *update_rr, dns_rdata_t *db_rr) { 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) if (db_rr->type != update_rr->type)
return (ISC_FALSE); return (ISC_FALSE);
if (db_rr->type == dns_rdatatype_cname) 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); return (ISC_TRUE);
if (db_rr->type == dns_rdatatype_nsec) if (db_rr->type == dns_rdatatype_nsec)
return (ISC_TRUE); 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) { if (db_rr->type == dns_rdatatype_wks) {
/* /*
* Compare the address and protocol fields only. These * 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; dns_dbiterator_t *dbit = NULL;
isc_boolean_t has_nsec; isc_boolean_t has_nsec;
unsigned int wraps = 0; unsigned int wraps = 0;
isc_boolean_t secure = dns_db_issecure(db);
CHECK(dns_db_createiterator(db, ISC_FALSE, &dbit)); 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. * we must pause the iterator first.
*/ */
CHECK(dns_dbiterator_pause(dbit)); CHECK(dns_dbiterator_pause(dbit));
CHECK(rrset_exists(db, ver, newname, if (secure) {
dns_rdatatype_nsec, 0, &has_nsec)); 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); } while (! has_nsec);
failure: failure:
if (dbit != NULL) if (dbit != NULL)
@ -1541,6 +1585,35 @@ next_active(ns_client_t *client, dns_zone_t *zone, dns_db_t *db,
return (result); 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". * Add a NSEC record for "name", recording the change in "diff".
* The existing NSEC is removed. * 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)); CHECK(dns_db_findnode(db, name, ISC_FALSE, &node));
dns_rdata_init(&rdata); dns_rdata_init(&rdata);
CHECK(dns_nsec_buildrdata(db, ver, node, target, buffer, &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, &region);
dns_name_fromregion(&next, &region);
isc_region_consume(&region, 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); 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. */ /* Update the database and journal with the RRSIG. */
/* XXX inefficient - will cause dataset merging */ /* 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)); rdataset.ttl, &sig_rdata));
dns_rdata_reset(&sig_rdata); dns_rdata_reset(&sig_rdata);
added_sig = ISC_TRUE; added_sig = ISC_TRUE;
@ -1735,6 +1826,84 @@ add_sigs(ns_client_t *client, dns_zone_t *zone, dns_db_t *db,
return (result); 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 RRSIG and NSEC records affected by an update. The original
* update, including the SOA serial update but exluding the RRSIG & NSEC * 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 static isc_result_t
update_signatures(ns_client_t *client, dns_zone_t *zone, dns_db_t *db, update_signatures(ns_client_t *client, dns_zone_t *zone, dns_db_t *db,
dns_dbversion_t *oldver, dns_dbversion_t *newver, 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; isc_result_t result;
dns_difftuple_t *t; 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) & check_ksk = ISC_TF((dns_zone_getoptions(zone) &
DNS_ZONEOPT_UPDATECHECKKSK) != 0); 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); 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. * Get the NSEC's TTL from the SOA MINIMUM field.
@ -1845,10 +2034,17 @@ update_signatures(ns_client_t *client, dns_zone_t *zone, dns_db_t *db,
* Delete all old RRSIGs covering this type, since they * Delete all old RRSIGs covering this type, since they
* are all invalid when the signed RRset has changed. * are all invalid when the signed RRset has changed.
* We may not be able to recreate all of them - tough. * We may not be able to recreate all of them - tough.
* Special case changes to the zone's DNSKEY records
* to support offline KSKs.
*/ */
CHECK(delete_if(true_p, db, newver, name, fprintf(stderr, "delete signatures %u\n", type);
dns_rdatatype_rrsig, type, if (type == dns_rdatatype_dnskey)
NULL, &sig_diff)); 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));
/* /*
* If this RRset still exists after the update, * If this RRset still exists after the update,
@ -2349,6 +2545,52 @@ check_mx(ns_client_t *client, dns_zone_t *zone,
return (ok ? ISC_R_SUCCESS : DNS_R_REFUSED); 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 static void
update_action(isc_task_t *task, isc_event_t *event) { update_action(isc_task_t *task, isc_event_t *event) {
update_event_t *uev = (update_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_fixedname_t tmpnamefixed;
dns_name_t *tmpname = NULL; dns_name_t *tmpname = NULL;
unsigned int options; unsigned int options;
isc_boolean_t deleted_zsk;
dns_difftuple_t *tuple;
dns_rdata_dnskey_t dnskey;
INSIST(event->ev_type == DNS_EVENT_UPDATE); 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 * "Unlike traditional dynamic update, the client
* is forbidden from updating NSEC records." * is forbidden from updating NSEC records."
*/ */
if (dns_db_issecure(db)) { if (dns_db_isdnssec(db)) {
if (rdata.type == dns_rdatatype_nsec) { if (rdata.type == dns_rdatatype_nsec) {
FAILC(DNS_R_REFUSED, FAILC(DNS_R_REFUSED,
"explicit NSEC updates are not allowed " "explicit NSEC updates are not allowed "
"in secure zones"); "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, FAILC(DNS_R_REFUSED,
"explicit RRSIG updates are currently " "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)) { if (! ISC_LIST_EMPTY(diff.tuples)) {
char *journalfile; char *journalfile;
dns_journal_t *journal; dns_journal_t *journal;
isc_boolean_t has_dnskey;
/* /*
* Increment the SOA serial, but only if it was not * 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)); 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, result = update_signatures(client, zone, db, oldver,
ver, &diff, ver, &diff, interval,
dns_zone_getsigvalidityinterval(zone)); &deleted_zsk);
if (result != ISC_R_SUCCESS) { if (result != ISC_R_SUCCESS) {
update_log(client, zone, update_log(client, zone,
ISC_LOG_ERROR, ISC_LOG_ERROR,
@ -2905,6 +3160,7 @@ update_action(isc_task_t *task, isc_event_t *event) {
*/ */
update_log(client, zone, LOGLEVEL_DEBUG, update_log(client, zone, LOGLEVEL_DEBUG,
"committing update transaction"); "committing update transaction");
dns_db_closeversion(db, &ver, ISC_TRUE); 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. * Notify slaves of the change we just made.
*/ */
dns_zone_notify(zone); 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 { } else {
update_log(client, zone, LOGLEVEL_DEBUG, "redundant request"); update_log(client, zone, LOGLEVEL_DEBUG, "redundant request");
dns_db_closeversion(db, &ver, ISC_TRUE); dns_db_closeversion(db, &ver, ISC_TRUE);

View File

@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE. * 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 */ /*! \file */
@ -1032,7 +1032,7 @@ parse_rdata(char **cmdlinep, dns_rdataclass_t rdataclass,
check_result(result, "isc_lex_openbuffer"); check_result(result, "isc_lex_openbuffer");
result = isc_buffer_allocate(mctx, &buf, MAXWIRE); result = isc_buffer_allocate(mctx, &buf, MAXWIRE);
check_result(result, "isc_buffer_allocate"); 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, dns_rootname, 0, mctx, buf,
&callbacks); &callbacks);
isc_lex_destroy(&lex); isc_lex_destroy(&lex);

View File

@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE. * 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 */ /*! \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 && if (tresult != ISC_R_SUCCESS &&
result == ISC_R_SUCCESS) result == ISC_R_SUCCESS)
result = tresult; result = tresult;
goto trust_anchor;
} }
/* /*
* XXXMPA to be removed when multiple lookaside * 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) if (result == ISC_R_SUCCESS)
result = ISC_R_FAILURE; result = ISC_R_FAILURE;
} }
trust_anchor:
dlv = cfg_obj_asstring(cfg_tuple_get(obj, dlv = cfg_obj_asstring(cfg_tuple_get(obj,
"trust-anchor")); "trust-anchor"));
isc_buffer_init(&b, dlv, strlen(dlv)); isc_buffer_init(&b, dlv, strlen(dlv));

View File

@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE. * 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 */ /*! \file */
@ -228,6 +228,21 @@ dns_db_isstub(dns_db_t *db) {
return (ISC_FALSE); 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 isc_boolean_t
dns_db_issecure(dns_db_t *db) { 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); 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));
}

View File

@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE. * 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 */ /*! \file */
@ -35,6 +35,7 @@
#include <dns/rdataclass.h> #include <dns/rdataclass.h>
#include <dns/rdatalist.h> #include <dns/rdatalist.h>
#include <dns/rdataset.h> #include <dns/rdataset.h>
#include <dns/rdatastruct.h>
#include <dns/rdatatype.h> #include <dns/rdatatype.h>
#include <dns/result.h> #include <dns/result.h>
@ -192,6 +193,52 @@ dns_diff_appendminimal(dns_diff_t *diff, dns_difftuple_t **tuplep)
ENSURE(*tuplep == NULL); 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 static isc_result_t
diff_apply(dns_diff_t *diff, dns_db_t *db, dns_dbversion_t *ver, diff_apply(dns_diff_t *diff, dns_db_t *db, dns_dbversion_t *ver,
isc_boolean_t warn) 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_diffop_t op;
dns_rdatalist_t rdl; dns_rdatalist_t rdl;
dns_rdataset_t rds; dns_rdataset_t rds;
dns_rdataset_t ardataset;
dns_rdataset_t *modified = NULL;
isc_boolean_t offline;
op = t->op; op = t->op;
type = t->rdata.type; 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_LIST_INIT(rdl.rdata);
ISC_LINK_INIT(&rdl, link); ISC_LINK_INIT(&rdl, link);
offline = ISC_FALSE;
while (t != NULL && while (t != NULL &&
dns_name_equal(&t->name, name) && dns_name_equal(&t->name, name) &&
t->op == op && t->op == op &&
@ -276,6 +327,10 @@ diff_apply(dns_diff_t *diff, dns_db_t *db, dns_dbversion_t *ver,
namebuf, typebuf, classbuf, namebuf, typebuf, classbuf,
(unsigned long) t->ttl, (unsigned long) t->ttl,
(unsigned long) rdl.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); ISC_LIST_APPEND(rdl.rdata, &t->rdata, link);
t = ISC_LIST_NEXT(t, 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); dns_rdataset_init(&rds);
CHECK(dns_rdatalist_tordataset(&rdl, &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; rds.trust = dns_trust_ultimate;
/* /*
* Merge the rdataset into the database. * 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, result = dns_db_addrdataset(db, node, ver,
0, &rds, 0, &rds,
DNS_DBADD_MERGE| DNS_DBADD_MERGE|
DNS_DBADD_EXACT| DNS_DBADD_EXACT|
DNS_DBADD_EXACTTTL, DNS_DBADD_EXACTTTL,
NULL); modified);
} else if (op == DNS_DIFFOP_DEL) { break;
case DNS_DIFFOP_DEL:
case DNS_DIFFOP_DELRESIGN:
result = dns_db_subtractrdataset(db, node, ver, result = dns_db_subtractrdataset(db, node, ver,
&rds, &rds,
DNS_DBSUB_EXACT, DNS_DBSUB_EXACT,
NULL); modified);
} else { break;
default:
INSIST(0); 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 * This will not happen when executing a
* dynamic update, because that code will * 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_write(DIFF_COMMON_LOGARGS,
ISC_LOG_WARNING, ISC_LOG_WARNING,
"update with no effect"); "update with no effect");
} else if (result == ISC_R_SUCCESS || } else if (result == DNS_R_NXRRSET) {
result == DNS_R_NXRRSET) {
/* /*
* OK. * OK.
*/ */
} else { } else {
if (modified != NULL &&
dns_rdataset_isassociated(modified))
dns_rdataset_disassociate(modified);
CHECK(result); 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); dns_db_detachnode(db, &node);
} }
@ -485,6 +570,7 @@ dns_diff_print(dns_diff_t *diff, FILE *file) {
dns_difftuple_t *t; dns_difftuple_t *t;
char *mem = NULL; char *mem = NULL;
unsigned int size = 2048; unsigned int size = 2048;
const char *op = NULL;
REQUIRE(DNS_DIFF_VALID(diff)); REQUIRE(DNS_DIFF_VALID(diff));
@ -536,15 +622,20 @@ dns_diff_print(dns_diff_t *diff, FILE *file) {
buf.used--; buf.used--;
isc_buffer_usedregion(&buf, &r); 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) if (file != NULL)
fprintf(file, "%s %.*s\n", fprintf(file, "%s %.*s\n", op, (int) r.length,
t->op == DNS_DIFFOP_ADD ? "add" : "del", (char *) r.base);
(int) r.length, (char *) r.base);
else else
isc_log_write(DIFF_COMMON_LOGARGS, ISC_LOG_DEBUG(7), isc_log_write(DIFF_COMMON_LOGARGS, ISC_LOG_DEBUG(7),
"%s %.*s", "%s %.*s", op, (int) r.length,
t->op == DNS_DIFFOP_ADD ? "add" : "del", (char *) r.base);
(int) r.length, (char *) r.base);
} }
result = ISC_R_SUCCESS; result = ISC_R_SUCCESS;
cleanup: cleanup:

View File

@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE. * 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 #ifndef DNS_DB_H
#define DNS_DB_H 1 #define DNS_DB_H 1
@ -147,7 +147,16 @@ typedef struct dns_dbmethods {
void (*settask)(dns_db_t *db, isc_task_t *); void (*settask)(dns_db_t *db, isc_task_t *);
isc_result_t (*getoriginnode)(dns_db_t *db, dns_dbnode_t **nodep); isc_result_t (*getoriginnode)(dns_db_t *db, dns_dbnode_t **nodep);
void (*transfernode)(dns_db_t *db, dns_dbnode_t **sourcep, void (*transfernode)(dns_db_t *db, dns_dbnode_t **sourcep,
dns_dbnode_t **targetp); 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; } dns_dbmethods_t;
typedef isc_result_t typedef isc_result_t
@ -357,6 +366,20 @@ dns_db_issecure(dns_db_t *db);
* \li #ISC_FALSE 'db' is not secure. * \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_name_t *
dns_db_origin(dns_db_t *db); dns_db_origin(dns_db_t *db);
/*%< /*%<
@ -628,7 +651,7 @@ dns_db_findnode(dns_db_t *db, dns_name_t *name, isc_boolean_t create,
* *
* \li #ISC_R_SUCCESS * \li #ISC_R_SUCCESS
* \li #ISC_R_NOTFOUND If !create and name not found. * \li #ISC_R_NOTFOUND If !create and name not found.
* \li #ISC_R_NOMEMORY Can only happen if create is ISC_TRUE. * \li #ISC_R_NOMEMORY Can only happen if create is ISC_TRUE.
* *
* \li Other results are possible, depending upon the database * \li Other results are possible, depending upon the database
* implementation used. * implementation used.
@ -887,7 +910,7 @@ dns_db_detachnode(dns_db_t *db, dns_dbnode_t **nodep);
void void
dns_db_transfernode(dns_db_t *db, dns_dbnode_t **sourcep, dns_db_transfernode(dns_db_t *db, dns_dbnode_t **sourcep,
dns_dbnode_t **targetp); dns_dbnode_t **targetp);
/*%< /*%<
* Transfer a node between pointer. * Transfer a node between pointer.
* *
@ -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. * \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 ISC_LANG_ENDDECLS
#endif /* DNS_DB_H */ #endif /* DNS_DB_H */

View File

@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE. * 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 #ifndef DNS_DIFF_H
#define DNS_DIFF_H 1 #define DNS_DIFF_H 1
@ -59,12 +59,16 @@
* individual RRs of a "RRset exists (value dependent)" * individual RRs of a "RRset exists (value dependent)"
* prerequisite set. In this case, op==DNS_DIFFOP_EXISTS, * prerequisite set. In this case, op==DNS_DIFFOP_EXISTS,
* and the TTL is ignored. * and the TTL is ignored.
*
* DNS_DIFFOP_*RESIGN will cause the 'resign' attribute to be recomputed.
*/ */
typedef enum { typedef enum {
DNS_DIFFOP_ADD, /*%< Add an RR. */ DNS_DIFFOP_ADD = 0, /*%< Add an RR. */
DNS_DIFFOP_DEL, /*%< Delete an RR. */ DNS_DIFFOP_DEL = 1, /*%< Delete an RR. */
DNS_DIFFOP_EXISTS /*%< Assert RR existence. */ DNS_DIFFOP_EXISTS = 2, /*%< Assert RR existence. */
DNS_DIFFOP_ADDRESIGN = 4, /*%< ADD + RESIGN. */
DNS_DIFFOP_DELRESIGN = 5, /*%< DEL + RESIGN. */
} dns_diffop_t; } dns_diffop_t;
typedef struct dns_difftuple dns_difftuple_t; typedef struct dns_difftuple dns_difftuple_t;
@ -73,7 +77,7 @@ typedef struct dns_difftuple dns_difftuple_t;
#define DNS_DIFFTUPLE_VALID(t) ISC_MAGIC_VALID(t, DNS_DIFFTUPLE_MAGIC) #define DNS_DIFFTUPLE_VALID(t) ISC_MAGIC_VALID(t, DNS_DIFFTUPLE_MAGIC)
struct dns_difftuple { struct dns_difftuple {
unsigned int magic; unsigned int magic;
isc_mem_t *mctx; isc_mem_t *mctx;
dns_diffop_t op; dns_diffop_t op;
dns_name_t name; dns_name_t name;

View File

@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE. * 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 #ifndef DNS_JOURNAL_H
#define DNS_JOURNAL_H 1 #define DNS_JOURNAL_H 1
@ -41,6 +41,11 @@
#include <dns/rdata.h> #include <dns/rdata.h>
#include <dns/types.h> #include <dns/types.h>
/***
*** Defines.
***/
#define DNS_JOURNALOPT_RESIGN 0x00000001
/*** /***
*** Types *** Types
***/ ***/
@ -225,17 +230,18 @@ dns_journal_current_rr(dns_journal_t *j, dns_name_t **name, isc_uint32_t *ttl,
*/ */
isc_result_t 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 * Roll forward (play back) the journal file "filename" into the
* database "db". This should be called when the server starts * database "db". This should be called when the server starts
* after a shutdown or crash. * after a shutdown or crash.
* *
* Requires: * Requires:
*\li 'mctx' is a valid memory context. *\li 'mctx' is a valid memory context.
*\li 'db' is a valid database which does not have a version *\li 'db' is a valid database which does not have a version
* open for writing. * 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: * Returns:
*\li DNS_R_NOJOURNAL when journal does not exist. *\li DNS_R_NOJOURNAL when journal does not exist.
@ -264,7 +270,7 @@ dns_db_diff(isc_mem_t *mctx,
isc_result_t isc_result_t
dns_journal_compact(isc_mem_t *mctx, char *filename, isc_uint32_t serial, dns_journal_compact(isc_mem_t *mctx, char *filename, isc_uint32_t serial,
isc_uint32_t target_size); isc_uint32_t target_size);
/*%< /*%<
* Attempt to compact the journal if it is greater that 'target_size'. * Attempt to compact the journal if it is greater that 'target_size'.
* Changes from 'serial' onwards will be preserved. If the journal * Changes from 'serial' onwards will be preserved. If the journal

View File

@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE. * 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 #ifndef DNS_MASTER_H
#define DNS_MASTER_H 1 #define DNS_MASTER_H 1
@ -55,6 +55,8 @@
#define DNS_MASTER_CHECKMX 0x00000800 #define DNS_MASTER_CHECKMX 0x00000800
#define DNS_MASTER_CHECKMXFAIL 0x00001000 #define DNS_MASTER_CHECKMXFAIL 0x00001000
#define DNS_MASTER_RESIGN 0x00002000
ISC_LANG_BEGINDECLS ISC_LANG_BEGINDECLS
/* /*

View File

@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE. * 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 #ifndef DNS_MASTERDUMP_H
#define DNS_MASTERDUMP_H 1 #define DNS_MASTERDUMP_H 1
@ -91,12 +91,15 @@ typedef struct dns_master_style dns_master_style_t;
/*% Print negative caching entries. */ /*% Print negative caching entries. */
#define DNS_STYLEFLAG_NCACHE 0x00800000U #define DNS_STYLEFLAG_NCACHE 0x00800000U
/*% Never print the TTL */ /*% Never print the TTL. */
#define DNS_STYLEFLAG_NO_TTL 0x01000000U #define DNS_STYLEFLAG_NO_TTL 0x01000000U
/*% Never print the CLASS */ /*% Never print the CLASS. */
#define DNS_STYLEFLAG_NO_CLASS 0x02000000U #define DNS_STYLEFLAG_NO_CLASS 0x02000000U
/*% Report re-signing time. */
#define DNS_STYLEFLAG_RESIGN 0x04000000U
ISC_LANG_BEGINDECLS ISC_LANG_BEGINDECLS
/*** /***

View File

@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE. * 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 #ifndef DNS_RDATA_H
#define DNS_RDATA_H 1 #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_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 * Flags affecting rdata formatting style. Flags 0xFFFF0000

View File

@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE. * 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 #ifndef DNS_RDATASET_H
#define DNS_RDATASET_H 1 #define DNS_RDATASET_H 1
@ -140,6 +140,11 @@ struct dns_rdataset {
* increment the counter. * increment the counter.
*/ */
isc_uint32_t count; 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 * These are for use by the rdataset implementation, and MUST NOT
@ -152,6 +157,7 @@ struct dns_rdataset {
void * private5; void * private5;
void * private6; void * private6;
/*@}*/ /*@}*/
}; };
/*! /*!
@ -184,6 +190,7 @@ struct dns_rdataset {
#define DNS_RDATASETATTR_CHECKNAMES 0x00008000 /*%< Used by resolver. */ #define DNS_RDATASETATTR_CHECKNAMES 0x00008000 /*%< Used by resolver. */
#define DNS_RDATASETATTR_REQUIREDGLUE 0x00010000 #define DNS_RDATASETATTR_REQUIREDGLUE 0x00010000
#define DNS_RDATASETATTR_LOADORDER 0x00020000 #define DNS_RDATASETATTR_LOADORDER 0x00020000
#define DNS_RDATASETATTR_RESIGN 0x00040000
/*% /*%
* _OMITDNSSEC: * _OMITDNSSEC:

View File

@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE. * 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 #ifndef DNS_RDATASLAB_H
#define DNS_RDATASLAB_H 1 #define DNS_RDATASLAB_H 1
@ -57,6 +57,13 @@ ISC_LANG_BEGINDECLS
#define DNS_RDATASLAB_FORCE 0x1 #define DNS_RDATASLAB_FORCE 0x1
#define DNS_RDATASLAB_EXACT 0x2 #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 *** Functions
***/ ***/

View File

@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE. * 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 #ifndef DNS_ZONE_H
#define DNS_ZONE_H 1 #define DNS_ZONE_H 1
@ -879,12 +879,16 @@ isc_boolean_t
dns_zone_getupdatedisabled(dns_zone_t *zone); dns_zone_getupdatedisabled(dns_zone_t *zone);
/*%< /*%<
* Return update disabled. * Return update disabled.
* Transient unless called when running in isc_task_exclusive() mode.
*/ */
void void
dns_zone_setupdatedisabled(dns_zone_t *zone, isc_boolean_t state); dns_zone_setupdatedisabled(dns_zone_t *zone, isc_boolean_t state);
/*%< /*%<
* Set update disabled. * 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 isc_boolean_t
@ -1636,6 +1640,9 @@ dns_zone_setisself(dns_zone_t *zone, dns_isselffunc_t isself, void *arg);
* delivered to 'myview'. * delivered to 'myview'.
*/ */
isc_result_t
dns_zone_signwithkey(dns_zone_t *zone, dns_secalg_t algorithm, uint16_t keyid);
#ifdef HAVE_LIBXML2 #ifdef HAVE_LIBXML2
isc_result_t isc_result_t

View File

@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE. * 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> #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 *a = *ap;
dns_difftuple_t const *b = *bp; dns_difftuple_t const *b = *bp;
int r; 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) if (r != 0)
return (r); return (r);
@ -1191,7 +1218,7 @@ dns_journal_destroy(dns_journal_t **journalp) {
/* XXX Share code with incoming IXFR? */ /* XXX Share code with incoming IXFR? */
static isc_result_t 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 source; /* Transaction data from disk */
isc_buffer_t target; /* Ditto after _fromwire check */ isc_buffer_t target; /* Ditto after _fromwire check */
isc_uint32_t db_serial; /* Database SOA serial */ 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; dns_diff_t diff;
unsigned int n_soa = 0; unsigned int n_soa = 0;
unsigned int n_put = 0; unsigned int n_put = 0;
dns_diffop_t op;
REQUIRE(DNS_JOURNAL_VALID(j)); REQUIRE(DNS_JOURNAL_VALID(j));
REQUIRE(DNS_DB_VALID(db)); REQUIRE(DNS_DB_VALID(db));
@ -1273,9 +1301,14 @@ roll_forward(dns_journal_t *j, dns_db_t *db) {
"initial SOA", j->filename); "initial SOA", j->filename);
FAIL(ISC_R_UNEXPECTED); FAIL(ISC_R_UNEXPECTED);
} }
CHECK(dns_difftuple_create(diff.mctx, n_soa == 1 ? if ((options & DNS_JOURNALOPT_RESIGN) != 0)
DNS_DIFFOP_DEL : DNS_DIFFOP_ADD, op = (n_soa == 1) ? DNS_DIFFOP_DELRESIGN :
name, ttl, rdata, &tuple)); 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); dns_diff_append(&diff, &tuple);
if (++n_put > 100) { if (++n_put > 100) {
@ -1317,7 +1350,9 @@ roll_forward(dns_journal_t *j, dns_db_t *db) {
} }
isc_result_t 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; dns_journal_t *j;
isc_result_t result; 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)) if (JOURNAL_EMPTY(&j->header))
result = DNS_R_UPTODATE; result = DNS_R_UPTODATE;
else else
result = roll_forward(j, db); result = roll_forward(j, db, options);
dns_journal_destroy(&j); dns_journal_destroy(&j);

View File

@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE. * 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 */ /*! \file */
@ -1738,8 +1738,7 @@ load_text(dns_loadctx_t *lctx) {
char namebuf[DNS_NAME_FORMATSIZE]; char namebuf[DNS_NAME_FORMATSIZE];
dns_name_format(ictx->current, namebuf, dns_name_format(ictx->current, namebuf,
sizeof(namebuf)); sizeof(namebuf));
(*callbacks->error)(callbacks, (*callbacks->error)(callbacks, "%s:%lu: SOA "
"%s:%lu: SOA "
"record not at top of zone (%s)", "record not at top of zone (%s)",
source, line, namebuf); source, line, namebuf);
result = DNS_R_NOTZONETOP; result = DNS_R_NOTZONETOP;
@ -2700,6 +2699,29 @@ grow_rdata(int new_len, dns_rdata_t *old, int old_len,
return (new); 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. * Convert each element from a rdatalist_t to rdataset then call commit.
* Unlink each element as we go. * 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) RUNTIME_CHECK(dns_rdatalist_tordataset(this, &dataset)
== ISC_R_SUCCESS); == ISC_R_SUCCESS);
dataset.trust = dns_trust_ultimate; 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, result = ((*callbacks->add)(callbacks->add_private, owner,
&dataset)); &dataset));
if (result == ISC_R_NOMEMORY) { if (result == ISC_R_NOMEMORY) {
(*error)(callbacks, "dns_master_load: %s", (*error)(callbacks, "dns_master_load: %s",
dns_result_totext(result)); dns_result_totext(result));
} else if (result != ISC_R_SUCCESS) { } else if (result != ISC_R_SUCCESS) {
dns_name_format(owner, namebuf, dns_name_format(owner, namebuf, sizeof(namebuf));
sizeof(namebuf));
if (source != NULL) { if (source != NULL) {
(*error)(callbacks, "%s: %s:%lu: %s: %s", (*error)(callbacks, "%s: %s:%lu: %s: %s",
"dns_master_load", source, line, "dns_master_load", source, line,

View File

@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE. * 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 */ /*! \file */
@ -108,7 +108,8 @@ dns_master_style_default = {
LIBDNS_EXTERNAL_DATA const dns_master_style_t LIBDNS_EXTERNAL_DATA const dns_master_style_t
dns_master_style_full = { dns_master_style_full = {
DNS_STYLEFLAG_COMMENT, DNS_STYLEFLAG_COMMENT |
DNS_STYLEFLAG_RESIGN,
46, 46, 46, 64, 120, 8 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) if ((ctx->style.flags & DNS_STYLEFLAG_OMIT_OWNER) != 0)
name = NULL; 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); dns_rdataset_disassociate(rds);
} }
@ -1077,7 +1087,7 @@ dns_dumpctx_version(dns_dumpctx_t *dctx) {
dns_db_t * dns_db_t *
dns_dumpctx_db(dns_dumpctx_t *dctx) { dns_dumpctx_db(dns_dumpctx_t *dctx) {
REQUIRE(DNS_DCTX_VALID(dctx)); REQUIRE(DNS_DCTX_VALID(dctx));
return (dctx->db); return (dctx->db);
} }
@ -1703,10 +1713,10 @@ dns_master_dumpnode(isc_mem_t *mctx, dns_db_t *db, dns_dbversion_t *version,
isc_result_t isc_result_t
dns_master_stylecreate(dns_master_style_t **stylep, unsigned int flags, dns_master_stylecreate(dns_master_style_t **stylep, unsigned int flags,
unsigned int ttl_column, unsigned int class_column, unsigned int ttl_column, unsigned int class_column,
unsigned int type_column, unsigned int rdata_column, unsigned int type_column, unsigned int rdata_column,
unsigned int line_length, unsigned int tab_width, unsigned int line_length, unsigned int tab_width,
isc_mem_t *mctx) isc_mem_t *mctx)
{ {
dns_master_style_t *style; dns_master_style_t *style;

View File

@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE. * 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 */ /*! \file */
@ -25,15 +25,16 @@
#include <config.h> #include <config.h>
#include <isc/heap.h>
#include <isc/event.h> #include <isc/event.h>
#include <isc/heap.h>
#include <isc/mem.h> #include <isc/mem.h>
#include <isc/mutex.h>
#include <isc/platform.h> #include <isc/platform.h>
#include <isc/print.h> #include <isc/print.h>
#include <isc/mutex.h>
#include <isc/random.h> #include <isc/random.h>
#include <isc/refcount.h> #include <isc/refcount.h>
#include <isc/rwlock.h> #include <isc/rwlock.h>
#include <isc/serial.h>
#include <isc/string.h> #include <isc/string.h>
#include <isc/task.h> #include <isc/task.h>
#include <isc/time.h> #include <isc/time.h>
@ -47,6 +48,7 @@
#include <dns/lib.h> #include <dns/lib.h>
#include <dns/log.h> #include <dns/log.h>
#include <dns/masterdump.h> #include <dns/masterdump.h>
#include <dns/nsec.h>
#include <dns/rbt.h> #include <dns/rbt.h>
#include <dns/rdata.h> #include <dns/rdata.h>
#include <dns/rdataset.h> #include <dns/rdataset.h>
@ -261,6 +263,7 @@ typedef struct rdatasetheader {
/*%< /*%<
* Used for TTL-based cache cleaning. * Used for TTL-based cache cleaning.
*/ */
isc_stdtime_t resign;
} rdatasetheader_t; } rdatasetheader_t;
typedef ISC_LIST(rdatasetheader_t) rdatasetheaderlist_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_IGNORE 0x0004
#define RDATASET_ATTR_RETAIN 0x0008 #define RDATASET_ATTR_RETAIN 0x0008
#define RDATASET_ATTR_NXDOMAIN 0x0010 #define RDATASET_ATTR_NXDOMAIN 0x0010
#define RDATASET_ATTR_RESIGN 0x0020
#define RDATASET_ATTR_CACHE 0x1000 /* for debug */ #define RDATASET_ATTR_CACHE 0x1000 /* for debug */
#define RDATASET_ATTR_CANCELED 0x2000 /* for debug */ #define RDATASET_ATTR_CANCELED 0x2000 /* for debug */
@ -307,6 +311,8 @@ struct acachectl {
(((header)->attributes & RDATASET_ATTR_RETAIN) != 0) (((header)->attributes & RDATASET_ATTR_RETAIN) != 0)
#define NXDOMAIN(header) \ #define NXDOMAIN(header) \
(((header)->attributes & RDATASET_ATTR_NXDOMAIN) != 0) (((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_NODE_LOCK_COUNT 7 /*%< Should be prime. */
#define DEFAULT_CACHE_NODE_LOCK_COUNT 1009 /*%< 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 writer;
isc_boolean_t commit_ok; isc_boolean_t commit_ok;
rbtdb_changedlist_t changed_list; rbtdb_changedlist_t changed_list;
rdatasetheaderlist_t resigned_list;
ISC_LINK(struct rbtdb_version) link; ISC_LINK(struct rbtdb_version) link;
} rbtdb_version_t; } rbtdb_version_t;
@ -372,6 +379,12 @@ struct cachestat {
}; };
#endif #endif
typedef enum {
dns_db_insecure,
dns_db_partial,
dns_db_secure
} dns_db_secure_t;
typedef struct { typedef struct {
/* Unlocked. */ /* Unlocked. */
dns_db_t common; dns_db_t common;
@ -419,7 +432,7 @@ typedef struct {
/* Locked by tree_lock. */ /* Locked by tree_lock. */
dns_rbt_t * tree; dns_rbt_t * tree;
isc_boolean_t secure; dns_db_secure_t secure;
/* Unlocked */ /* Unlocked */
unsigned int quantum; unsigned int quantum;
@ -498,6 +511,8 @@ static void update_header(dns_rbtdb_t *rbtdb, rdatasetheader_t *header,
isc_stdtime_t now); isc_stdtime_t now);
static void check_stale_cache(dns_rbtdb_t *rbtdb, dns_rbtnode_t *rbtnode, static void check_stale_cache(dns_rbtdb_t *rbtdb, dns_rbtnode_t *rbtnode,
isc_stdtime_t now, isc_boolean_t tree_locked); 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 = { static dns_rdatasetmethods_t rdataset_methods = {
rdataset_disassociate, rdataset_disassociate,
@ -653,6 +668,9 @@ set_ttl(dns_rbtdb_t *rbtdb, rdatasetheader_t *header, dns_ttl_t newttl) {
oldttl = header->rdh_ttl; oldttl = header->rdh_ttl;
header->rdh_ttl = newttl; header->rdh_ttl = newttl;
if (!IS_CACHE(rbtdb))
return;
/* /*
* It's possible the rbtdb is not a cache. If this is the case, * 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, * 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. * element. It returns ISC_TRUE if v1 happens "sooner" than v2.
*/ */
static isc_boolean_t static isc_boolean_t
@ -685,11 +703,21 @@ ttl_sooner(void *v1, void *v2) {
return (ISC_FALSE); 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. * This function sets the heap index into the header.
*/ */
static void static void
ttl_set_index(void *what, unsigned int index) { set_index(void *what, unsigned int index) {
rdatasetheader_t *h = what; rdatasetheader_t *h = what;
h->heap_index = index; 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) { if (rbtdb->rdatasets != NULL) {
for (i = 0; i < rbtdb->node_lock_count; i++) 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)); rbtdb->node_lock_count * sizeof(rbtnodelist_t));
} }
/* /*
* Clean up TTL heap cache objects. * Clean up heap objects.
*/ */
if (rbtdb->heaps != NULL) { if (rbtdb->heaps != NULL) {
for (i = 0; i < rbtdb->node_lock_count; i++) 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->writer = writer;
version->commit_ok = ISC_FALSE; version->commit_ok = ISC_FALSE;
ISC_LIST_INIT(version->changed_list); ISC_LIST_INIT(version->changed_list);
ISC_LIST_INIT(version->resigned_list);
ISC_LINK_INIT(version, link); ISC_LINK_INIT(version, link);
return (version); return (version);
@ -1165,6 +1194,7 @@ static inline void
free_rdataset(dns_rbtdb_t *rbtdb, isc_mem_t *mctx, rdatasetheader_t *rdataset) free_rdataset(dns_rbtdb_t *rbtdb, isc_mem_t *mctx, rdatasetheader_t *rdataset)
{ {
unsigned int size; unsigned int size;
int idx;
#ifdef LRU_DEBUG #ifdef LRU_DEBUG
/* /*
@ -1229,15 +1259,12 @@ free_rdataset(dns_rbtdb_t *rbtdb, isc_mem_t *mctx, rdatasetheader_t *rdataset)
} }
#endif #endif
if (IS_CACHE(rbtdb) && ISC_LINK_LINKED(rdataset, lru_link)) { idx = rdataset->node->locknum;
int idx = rdataset->node->locknum; if (ISC_LINK_LINKED(rdataset, lru_link))
ISC_LIST_UNLINK(rbtdb->rdatasets[idx], rdataset, lru_link); ISC_LIST_UNLINK(rbtdb->rdatasets[idx], rdataset, lru_link);
if (rdataset->heap_index != 0) { if (rdataset->heap_index != 0)
isc_heap_delete(rbtdb->heaps[idx], isc_heap_delete(rbtdb->heaps[idx], rdataset->heap_index);
rdataset->heap_index); rdataset->heap_index = 0;
}
rdataset->heap_index = 0;
}
if (rdataset->noqname != NULL) if (rdataset->noqname != NULL)
free_noqname(mctx, &rdataset->noqname); 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) { iszonesecure(dns_db_t *db, dns_dbnode_t *origin) {
dns_rdataset_t keyset; dns_rdataset_t keyset;
dns_rdataset_t nsecset, signsecset; dns_rdataset_t nsecset, signsecset;
dns_rdata_t rdata = DNS_RDATA_INIT;
isc_boolean_t haszonekey = ISC_FALSE; isc_boolean_t haszonekey = ISC_FALSE;
isc_boolean_t hasnsec = ISC_FALSE; isc_boolean_t hasnsec = ISC_FALSE;
isc_boolean_t hasoptbit = ISC_FALSE;
isc_result_t result; isc_result_t result;
dns_rdataset_init(&keyset); dns_rdataset_init(&keyset);
@ -1728,7 +1757,7 @@ iszonesecure(dns_db_t *db, dns_dbnode_t *origin) {
dns_rdataset_disassociate(&keyset); dns_rdataset_disassociate(&keyset);
} }
if (!haszonekey) if (!haszonekey)
return (ISC_FALSE); return (dns_db_insecure);
dns_rdataset_init(&nsecset); dns_rdataset_init(&nsecset);
dns_rdataset_init(&signsecset); dns_rdataset_init(&signsecset);
@ -1737,11 +1766,20 @@ iszonesecure(dns_db_t *db, dns_dbnode_t *origin) {
if (result == ISC_R_SUCCESS) { if (result == ISC_R_SUCCESS) {
if (dns_rdataset_isassociated(&signsecset)) { if (dns_rdataset_isassociated(&signsecset)) {
hasnsec = ISC_TRUE; 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(&signsecset);
} }
dns_rdataset_disassociate(&nsecset); dns_rdataset_disassociate(&nsecset);
} }
return (hasnsec);
if (hasnsec && hasoptbit)
return (dns_db_partial);
return (hasnsec ? dns_db_secure : dns_db_insecure);
} }
static void 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; rbtdb_version_t *version, *cleanup_version, *least_greater;
isc_boolean_t rollback = ISC_FALSE; isc_boolean_t rollback = ISC_FALSE;
rbtdb_changedlist_t cleanup_list; rbtdb_changedlist_t cleanup_list;
rdatasetheaderlist_t resigned_list;
rbtdb_changed_t *changed, *next_changed; rbtdb_changed_t *changed, *next_changed;
rbtdb_serial_t serial, least_serial; rbtdb_serial_t serial, least_serial;
dns_rbtnode_t *rbtnode; dns_rbtnode_t *rbtnode;
unsigned int refs; unsigned int refs;
rdatasetheader_t *header;
isc_boolean_t writer; isc_boolean_t writer;
REQUIRE(VALID_RBTDB(rbtdb)); REQUIRE(VALID_RBTDB(rbtdb));
@ -1761,6 +1801,7 @@ closeversion(dns_db_t *db, dns_dbversion_t **versionp, isc_boolean_t commit) {
cleanup_version = NULL; cleanup_version = NULL;
ISC_LIST_INIT(cleanup_list); ISC_LIST_INIT(cleanup_list);
ISC_LIST_INIT(resigned_list);
isc_refcount_decrement(&version->references, &refs); isc_refcount_decrement(&version->references, &refs);
if (refs > 0) { /* typical and easy case first */ 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); INSIST(cur_ref == 1);
PREPEND(rbtdb->open_versions, PREPEND(rbtdb->open_versions,
rbtdb->current_version, link); rbtdb->current_version, link);
resigned_list = version->resigned_list;
ISC_LIST_INIT(version->resigned_list);
} else { } else {
/* /*
* We're rolling back this transaction. * We're rolling back this transaction.
*/ */
cleanup_list = version->changed_list; cleanup_list = version->changed_list;
ISC_LIST_INIT(version->changed_list); ISC_LIST_INIT(version->changed_list);
resigned_list = version->resigned_list;
ISC_LIST_INIT(version->resigned_list);
rollback = ISC_TRUE; rollback = ISC_TRUE;
cleanup_version = version; cleanup_version = version;
rbtdb->future_version = NULL; rbtdb->future_version = NULL;
@ -1916,6 +1961,25 @@ closeversion(dns_db_t *db, dns_dbversion_t **versionp, isc_boolean_t commit) {
sizeof(*cleanup_version)); 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)) { if (!EMPTY(cleanup_list)) {
/* /*
* We acquire a tree write lock here in order to make sure * 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; rdataset->private6 = header->noqname;
if (rdataset->private6 != NULL) if (rdataset->private6 != NULL)
rdataset->attributes |= DNS_RDATASETATTR_NOQNAME; 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 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 * If we're here, then the name does not exist, is not
* beneath a zonecut, and there's no matching wildcard. * 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) (search.options & DNS_DBFIND_FORCENSEC) != 0)
{ {
result = find_closest_nsec(&search, nodep, foundname, result = find_closest_nsec(&search, nodep, foundname,
rdataset, sigrdataset, rdataset, sigrdataset,
search.rbtdb->secure); ISC_TRUE);
if (result == ISC_R_SUCCESS) if (result == ISC_R_SUCCESS)
result = active ? DNS_R_EMPTYNAME : result = active ? DNS_R_EMPTYNAME :
DNS_R_NXDOMAIN; 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. * The desired type doesn't exist.
*/ */
result = DNS_R_NXRRSET; result = DNS_R_NXRRSET;
if (search.rbtdb->secure && if (search.rbtdb->secure == dns_db_secure &&
(nsecheader == NULL || nsecsig == NULL)) { (nsecheader == NULL || nsecsig == NULL)) {
/* /*
* The zone is secure but there's no NSEC, * 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); NODE_UNLOCK(lock, isc_rwlocktype_read);
result = find_closest_nsec(&search, nodep, foundname, result = find_closest_nsec(&search, nodep, foundname,
rdataset, sigrdataset, rdataset, sigrdataset,
search.rbtdb->secure); search.rbtdb->secure ==
dns_db_secure);
if (result == ISC_R_SUCCESS) if (result == ISC_R_SUCCESS)
result = DNS_R_EMPTYWILD; result = DNS_R_EMPTYWILD;
goto tree_exit; 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); new_reference(search.rbtdb, node);
*nodep = node; *nodep = node;
} }
if (search.rbtdb->secure || if (search.rbtdb->secure == dns_db_secure ||
(search.options & DNS_DBFIND_FORCENSEC) != 0) (search.options & DNS_DBFIND_FORCENSEC) != 0)
{ {
bind_rdataset(search.rbtdb, node, nsecheader, bind_rdataset(search.rbtdb, node, nsecheader,
@ -4545,11 +4618,13 @@ printnode(dns_db_t *db, dns_dbnode_t *node, FILE *out) {
first = ISC_FALSE; first = ISC_FALSE;
fprintf(out, fprintf(out,
"\tserial = %lu, ttl = %u, " "\tserial = %lu, ttl = %u, "
"trust = %u, attributes = %u\n", "trust = %u, attributes = %u, "
"resign = %u\n",
(unsigned long)current->serial, (unsigned long)current->serial,
current->rdh_ttl, current->rdh_ttl,
current->trust, current->trust,
current->attributes); current->attributes,
current->resign);
current = current->down; current = current->down;
} while (current != NULL); } while (current != NULL);
} }
@ -4941,6 +5016,16 @@ cachestat_update(dns_rbtdb_t *rbtdb, rdatasetheader_t *header) {
} }
#endif #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 static isc_result_t
add(dns_rbtdb_t *rbtdb, dns_rbtnode_t *rbtnode, rbtdb_version_t *rbtversion, add(dns_rbtdb_t *rbtdb, dns_rbtnode_t *rbtnode, rbtdb_version_t *rbtversion,
rdatasetheader_t *newheader, unsigned int options, isc_boolean_t loading, 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; dns_rdatatype_t rdtype, covers;
rbtdb_rdatatype_t negtype; rbtdb_rdatatype_t negtype;
dns_trust_t trust; dns_trust_t trust;
int idx;
/* /*
* Add an rdatasetheader_t to a node. * 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, free_rdataset(rbtdb, rbtdb->common.mctx,
newheader); newheader);
newheader = (rdatasetheader_t *)merged; newheader = (rdatasetheader_t *)merged;
if (loading && RESIGN(newheader) &&
RESIGN(header) &&
header->resign < newheader->resign)
newheader->resign = header->resign;
} else { } else {
free_rdataset(rbtdb, rbtdb->common.mctx, free_rdataset(rbtdb, rbtdb->common.mctx,
newheader); newheader);
@ -5250,12 +5340,10 @@ add(dns_rbtdb_t *rbtdb, dns_rbtnode_t *rbtnode, rbtdb_version_t *rbtversion,
set_ttl(rbtdb, header, 0); set_ttl(rbtdb, header, 0);
header->attributes |= RDATASET_ATTR_STALE; header->attributes |= RDATASET_ATTR_STALE;
} }
idx = newheader->node->locknum;
if (IS_CACHE(rbtdb)) { if (IS_CACHE(rbtdb)) {
int idx = newheader->node->locknum;
ISC_LIST_PREPEND(rbtdb->rdatasets[idx], ISC_LIST_PREPEND(rbtdb->rdatasets[idx],
newheader, lru_link); newheader, lru_link);
/* /*
* XXXMLG We don't check the return value * XXXMLG We don't check the return value
* here. If it fails, we will not do TTL * here. If it fails, we will not do TTL
@ -5264,16 +5352,17 @@ add(dns_rbtdb_t *rbtdb, dns_rbtnode_t *rbtnode, rbtdb_version_t *rbtversion,
* will not leak... for long. * will not leak... for long.
*/ */
isc_heap_insert(rbtdb->heaps[idx], newheader); isc_heap_insert(rbtdb->heaps[idx], newheader);
}
#ifdef LRU_DEBUG #ifdef LRU_DEBUG
cachestat_update(rbtdb, newheader); cachestat_update(rbtdb, newheader);
#endif #endif
} } else if (RESIGN(newheader))
} else { resign_insert(rbtdb, idx, newheader);
/* }
* No non-IGNORED rdatasets of the given type exist at } else {
* this node. /*
*/ * No non-IGNORED rdatasets of the given type exist at
* this node.
*/
/* /*
* If we're trying to delete the type, don't bother. * If we're trying to delete the type, don't bother.
@ -5313,15 +5402,17 @@ add(dns_rbtdb_t *rbtdb, dns_rbtnode_t *rbtnode, rbtdb_version_t *rbtversion,
newheader->down = NULL; newheader->down = NULL;
rbtnode->data = newheader; rbtnode->data = newheader;
} }
idx = newheader->node->locknum;
if (IS_CACHE(rbtdb)) { if (IS_CACHE(rbtdb)) {
int idx = newheader->node->locknum;
ISC_LIST_PREPEND(rbtdb->rdatasets[idx], ISC_LIST_PREPEND(rbtdb->rdatasets[idx],
newheader, lru_link); newheader, lru_link);
isc_heap_insert(rbtdb->heaps[idx], newheader); isc_heap_insert(rbtdb->heaps[idx], newheader);
}
#ifdef LRU_DEBUG #ifdef LRU_DEBUG
cachestat_update(rbtdb, newheader); cachestat_update(rbtdb, newheader);
#endif #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) { if (rbtversion != NULL) {
newheader->serial = rbtversion->serial; newheader->serial = rbtversion->serial;
now = 0; now = 0;
if ((rdataset->attributes & DNS_RDATASETATTR_RESIGN) != 0) {
newheader->attributes |= RDATASET_ATTR_RESIGN;
newheader->resign = rdataset->resign;
} else
newheader->resign = 0;
} else { } else {
newheader->serial = 1; newheader->serial = 1;
newheader->resign = 0;
if ((rdataset->attributes & DNS_RDATASETATTR_NXDOMAIN) != 0) if ((rdataset->attributes & DNS_RDATASETATTR_NXDOMAIN) != 0)
newheader->attributes |= RDATASET_ATTR_NXDOMAIN; newheader->attributes |= RDATASET_ATTR_NXDOMAIN;
if ((rdataset->attributes & DNS_RDATASETATTR_NOQNAME) != 0) { 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->additional_glue = NULL;
newheader->last_used = 0; newheader->last_used = 0;
newheader->node = rbtnode; 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, NODE_LOCK(&rbtdb->node_locks[rbtnode->locknum].lock,
isc_rwlocktype_write); 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) { if (result == ISC_R_SUCCESS) {
free_rdataset(rbtdb, rbtdb->common.mctx, newheader); free_rdataset(rbtdb, rbtdb->common.mctx, newheader);
newheader = (rdatasetheader_t *)subresult; newheader = (rdatasetheader_t *)subresult;
init_rdataset(rbtdb, newheader);
/* /*
* We have to set the serial since the rdataslab * We have to set the serial since the rdataslab
* subtraction routine copies the reserved portion of * 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->count = init_count++;
newheader->additional_auth = NULL; newheader->additional_auth = NULL;
newheader->additional_glue = NULL; newheader->additional_glue = NULL;
/* won't be used, but initialize anyway */
newheader->last_used = 0; newheader->last_used = 0;
newheader->node = node; 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, result = add(rbtdb, node, rbtdb->current_version, newheader,
DNS_DBADD_MERGE, ISC_TRUE, NULL, 0); DNS_DBADD_MERGE, ISC_TRUE, NULL, 0);
@ -5966,12 +6073,28 @@ issecure(dns_db_t *db) {
REQUIRE(VALID_RBTDB(rbtdb)); REQUIRE(VALID_RBTDB(rbtdb));
RWLOCK(&rbtdb->tree_lock, isc_rwlocktype_read); 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); RWUNLOCK(&rbtdb->tree_lock, isc_rwlocktype_read);
return (secure); 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 static unsigned int
nodecount(dns_db_t *db) { nodecount(dns_db_t *db) {
dns_rbtdb_t *rbtdb; dns_rbtdb_t *rbtdb;
@ -6035,6 +6158,125 @@ getoriginnode(dns_db_t *db, dns_dbnode_t **nodep) {
return (result); 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 = { static dns_dbmethods_t zone_methods = {
attach, attach,
detach, detach,
@ -6065,6 +6307,10 @@ static dns_dbmethods_t zone_methods = {
settask, settask,
getoriginnode, getoriginnode,
NULL, NULL,
setsigningtime,
getsigningtime,
resigned,
isdnssec,
}; };
static dns_dbmethods_t cache_methods = { static dns_dbmethods_t cache_methods = {
@ -6096,7 +6342,11 @@ static dns_dbmethods_t cache_methods = {
overmem, overmem,
settask, settask,
getoriginnode, getoriginnode,
NULL NULL,
NULL,
NULL,
NULL,
isdnssec
}; };
isc_result_t isc_result_t
@ -6168,28 +6418,32 @@ dns_rbtdb_create
} }
for (i = 0; i < (int)rbtdb->node_lock_count; i++) for (i = 0; i < (int)rbtdb->node_lock_count; i++)
ISC_LIST_INIT(rbtdb->rdatasets[i]); ISC_LIST_INIT(rbtdb->rdatasets[i]);
/*
* Create the heaps.
*/
rbtdb->heaps = isc_mem_get(mctx, rbtdb->node_lock_count *
sizeof(isc_heap_t *));
if (rbtdb->heaps == NULL) {
result = ISC_R_NOMEMORY;
goto cleanup_rdatasets;
}
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,
&rbtdb->heaps[i]);
if (result != ISC_R_SUCCESS)
goto cleanup_heaps;
}
} else { } else {
rbtdb->rdatasets = NULL; rbtdb->rdatasets = NULL;
rbtdb->heaps = NULL; }
/*
* Create the heaps.
*/
rbtdb->heaps = isc_mem_get(mctx, rbtdb->node_lock_count *
sizeof(isc_heap_t *));
if (rbtdb->heaps == NULL) {
result = ISC_R_NOMEMORY;
goto cleanup_rdatasets;
}
for (i = 0; i < (int)rbtdb->node_lock_count; i++)
rbtdb->heaps[i] = NULL;
for (i = 0; i < (int)rbtdb->node_lock_count; i++) {
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;
} }
rbtdb->deadnodes = isc_mem_get(mctx, rbtdb->node_lock_count * rbtdb->deadnodes = isc_mem_get(mctx, rbtdb->node_lock_count *
@ -6297,7 +6551,7 @@ dns_rbtdb_create
return (result); return (result);
} }
rbtdb->attributes = 0; rbtdb->attributes = 0;
rbtdb->secure = ISC_FALSE; rbtdb->secure = dns_db_insecure;
rbtdb->overmem = ISC_FALSE; rbtdb->overmem = ISC_FALSE;
rbtdb->task = NULL; rbtdb->task = NULL;
@ -6446,7 +6700,9 @@ rdataset_current(dns_rdataset_t *rdataset, dns_rdata_t *rdata) {
#if DNS_RDATASET_FIXED #if DNS_RDATASET_FIXED
unsigned int offset; unsigned int offset;
#endif #endif
unsigned int length;
isc_region_t r; isc_region_t r;
unsigned int flags = 0;
REQUIRE(raw != NULL); REQUIRE(raw != NULL);
@ -6462,15 +6718,25 @@ rdataset_current(dns_rdataset_t *rdataset, dns_rdata_t *rdata) {
raw += offset; raw += offset;
} }
#endif #endif
r.length = raw[0] * 256 + raw[1]; length = raw[0] * 256 + raw[1];
#if DNS_RDATASET_FIXED #if DNS_RDATASET_FIXED
raw += 4; raw += 4;
#else #else
raw += 2; raw += 2;
#endif #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; r.base = raw;
dns_rdata_fromregion(rdata, rdataset->rdclass, rdataset->type, &r); dns_rdata_fromregion(rdata, rdataset->rdclass, rdataset->type, &r);
rdata->flags |= flags;
} }
static void static void
@ -7539,6 +7805,8 @@ static void
update_header(dns_rbtdb_t *rbtdb, rdatasetheader_t *header, update_header(dns_rbtdb_t *rbtdb, rdatasetheader_t *header,
isc_stdtime_t now) isc_stdtime_t now)
{ {
INSIST(IS_CACHE(rbtdb));
/* To be checked: can we really assume this? XXXMLG */ /* To be checked: can we really assume this? XXXMLG */
INSIST(ISC_LINK_LINKED(header, lru_link)); INSIST(ISC_LINK_LINKED(header, lru_link));

View File

@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE. * 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 */ /*! \file */
@ -269,7 +269,7 @@ dns_rdata_init(dns_rdata_t *rdata) {
/* ISC_LIST_INIT(rdata->list); */ /* ISC_LIST_INIT(rdata->list); */
} }
#if 0 #if 1
#define DNS_RDATA_INITIALIZED(rdata) \ #define DNS_RDATA_INITIALIZED(rdata) \
((rdata)->data == NULL && (rdata)->length == 0 && \ ((rdata)->data == NULL && (rdata)->length == 0 && \
(rdata)->rdclass == 0 && (rdata)->type == 0 && (rdata)->flags == 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 #define DNS_RDATA_INITIALIZED(rdata) ISC_TRUE
#endif #endif
#endif #endif
#define DNS_RDATA_VALIDFLAGS(rdata) \ #define DNS_RDATA_VALIDFLAGS(rdata) \
(((rdata)->flags & ~DNS_RDATA_UPDATE) == 0) (((rdata)->flags & ~(DNS_RDATA_UPDATE|DNS_RDATA_OFFLINE)) == 0)
void void
dns_rdata_reset(dns_rdata_t *rdata) { dns_rdata_reset(dns_rdata_t *rdata) {

View File

@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE. * 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 */ /*! \file */
@ -59,6 +59,7 @@ dns_rdataset_init(dns_rdataset_t *rdataset) {
rdataset->privateuint4 = 0; rdataset->privateuint4 = 0;
rdataset->private5 = NULL; rdataset->private5 = NULL;
rdataset->private6 = NULL; rdataset->private6 = NULL;
rdataset->resign = 0;
} }
void void
@ -620,7 +621,7 @@ dns_rdataset_addnoqname(dns_rdataset_t *rdataset, dns_name_t *name) {
isc_result_t isc_result_t
dns_rdataset_getnoqname(dns_rdataset_t *rdataset, dns_name_t *name, dns_rdataset_getnoqname(dns_rdataset_t *rdataset, dns_name_t *name,
dns_rdataset_t *nsec, dns_rdataset_t *nsecsig) dns_rdataset_t *nsec, dns_rdataset_t *nsecsig)
{ {
REQUIRE(DNS_RDATASET_VALID(rdataset)); REQUIRE(DNS_RDATASET_VALID(rdataset));
REQUIRE(rdataset->methods != NULL); REQUIRE(rdataset->methods != NULL);

View File

@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE. * 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 */ /*! \file */
@ -47,6 +47,7 @@
* data records * data records
* data length (2 bytes) * data length (2 bytes)
* order (2 bytes) * order (2 bytes)
* meta data (1 byte for RRSIG's)
* data (data length bytes) * data (data length bytes)
* *
* If DNS_RDATASET_FIXED is defined to be zero (0) the format of a * 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 #if DNS_RDATASET_FIXED
unsigned int *offsettable; unsigned int *offsettable;
#endif #endif
unsigned int length;
buflen = reservelen + 2; buflen = reservelen + 2;
@ -169,6 +171,8 @@ dns_rdataslab_fromrdataset(dns_rdataset_t *rdataset, isc_mem_t *mctx,
#if DNS_RDATASET_FIXED #if DNS_RDATASET_FIXED
x[i].order = i; x[i].order = i;
#endif #endif
if (x[i].rdata.flags & DNS_RDATA_OFFLINE)
fprintf(stderr, "OFFLINE\n");
result = dns_rdataset_next(rdataset); result = dns_rdataset_next(rdataset);
} }
if (result != ISC_R_NOMORE) 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; x[i].order = x[i-1].order;
#endif #endif
nitems--; nitems--;
} else } else {
#if DNS_RDATASET_FIXED #if DNS_RDATASET_FIXED
buflen += (8 + x[i-1].rdata.length); buflen += (8 + x[i-1].rdata.length);
#else #else
buflen += (2 + x[i-1].rdata.length); buflen += (2 + x[i-1].rdata.length);
#endif #endif
/*
* Provide space to store the per RR meta data.
*/
if (rdataset->type == dns_rdatatype_rrsig)
buflen++;
}
} }
/* /*
* Don't forget the last item! * Don't forget the last item!
@ -224,6 +234,11 @@ dns_rdataslab_fromrdataset(dns_rdataset_t *rdataset, isc_mem_t *mctx,
#else #else
buflen += (2 + x[i-1].rdata.length); buflen += (2 + x[i-1].rdata.length);
#endif #endif
/*
* Provide space to store the per RR meta data.
*/
if (rdataset->type == dns_rdatatype_rrsig)
buflen++;
/* /*
* Ensure that singleton types are actually singletons. * 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 #if DNS_RDATASET_FIXED
offsettable[x[i].order] = rawbuf - offsetbase; offsettable[x[i].order] = rawbuf - offsetbase;
#endif #endif
*rawbuf++ = (x[i].rdata.length & 0xff00) >> 8; length = x[i].rdata.length;
*rawbuf++ = (x[i].rdata.length & 0x00ff); if (rdataset->type == dns_rdatatype_rrsig)
length++;
*rawbuf++ = (length & 0xff00) >> 8;
*rawbuf++ = (length & 0x00ff);
#if DNS_RDATASET_FIXED #if DNS_RDATASET_FIXED
rawbuf += 2; /* filled in later */ rawbuf += 2; /* filled in later */
#endif #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); memcpy(rawbuf, x[i].rdata.data, x[i].rdata.length);
rawbuf += 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) { rdataset_current(dns_rdataset_t *rdataset, dns_rdata_t *rdata) {
unsigned char *raw = rdataset->private5; unsigned char *raw = rdataset->private5;
isc_region_t r; isc_region_t r;
unsigned int length;
unsigned int flags = 0;
REQUIRE(raw != NULL); REQUIRE(raw != NULL);
r.length = raw[0] * 256 + raw[1]; length = raw[0] * 256 + raw[1];
#if DNS_RDATASET_FIXED #if DNS_RDATASET_FIXED
raw += 4; raw += 4;
#else #else
raw += 2; raw += 2;
#endif #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; r.base = raw;
dns_rdata_fromregion(rdata, rdataset->rdclass, rdataset->type, &r); dns_rdata_fromregion(rdata, rdataset->rdclass, rdataset->type, &r);
rdata->flags |= flags;
} }
static void static void
@ -474,15 +517,29 @@ rdata_from_slab(unsigned char **current,
{ {
unsigned char *tcurrent = *current; unsigned char *tcurrent = *current;
isc_region_t region; isc_region_t region;
unsigned int length;
isc_boolean_t offline = ISC_FALSE;
region.length = *tcurrent++ * 256; length = *tcurrent++ * 256;
region.length += *tcurrent++; 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 #if DNS_RDATASET_FIXED
tcurrent += 2; tcurrent += 2;
#endif #endif
region.base = tcurrent; region.base = tcurrent;
tcurrent += region.length; tcurrent += region.length;
dns_rdata_fromregion(rdata, rdclass, type, &region); dns_rdata_fromregion(rdata, rdclass, type, &region);
if (offline) {
rdata->flags |= DNS_RDATA_OFFLINE;
fprintf(stderr, "rdata_from_slab: DNS_RDATA_OFFLINE\n");
}
*current = tcurrent; *current = tcurrent;
} }
@ -528,9 +585,8 @@ dns_rdataslab_merge(unsigned char *oslab, unsigned char *nslab,
dns_rdataclass_t rdclass, dns_rdatatype_t type, dns_rdataclass_t rdclass, dns_rdatatype_t type,
unsigned int flags, unsigned char **tslabp) 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; unsigned int ocount, ncount, count, olength, tlength, tcount, length;
isc_region_t nregion;
dns_rdata_t ordata = DNS_RDATA_INIT; dns_rdata_t ordata = DNS_RDATA_INIT;
dns_rdata_t nrdata = DNS_RDATA_INIT; dns_rdata_t nrdata = DNS_RDATA_INIT;
isc_boolean_t added_something = ISC_FALSE; isc_boolean_t added_something = ISC_FALSE;
@ -603,29 +659,24 @@ dns_rdataslab_merge(unsigned char *oslab, unsigned char *nslab,
* the old slab. * the old slab.
*/ */
do { 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_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)) if (!rdata_in_slab(oslab, reservelen, rdclass, type, &nrdata))
{ {
/* /*
* This rdata isn't in the old slab. * This rdata isn't in the old slab.
*/ */
#if DNS_RDATASET_FIXED #if DNS_RDATASET_FIXED
tlength += nregion.length + 8; tlength += nrdata.length + 8;
#else #else
tlength += nregion.length + 2; tlength += nrdata.length + 2;
#endif #endif
if (type == dns_rdatatype_rrsig)
tlength++;
tcount++; tcount++;
nncount++; nncount++;
added_something = ISC_TRUE; added_something = ISC_TRUE;
} }
ncurrent += nregion.length;
ncount--; ncount--;
} while (ncount > 0); } while (ncount > 0);
ncount = nncount; ncount = nncount;
@ -726,12 +777,17 @@ dns_rdataslab_merge(unsigned char *oslab, unsigned char *nslab,
offsettable[oorder] = tcurrent - offsetbase; offsettable[oorder] = tcurrent - offsetbase;
#endif #endif
length = ordata.length; length = ordata.length;
data = ordata.data;
if (type == dns_rdatatype_rrsig) {
length++;
data--;
}
*tcurrent++ = (length & 0xff00) >> 8; *tcurrent++ = (length & 0xff00) >> 8;
*tcurrent++ = (length & 0x00ff); *tcurrent++ = (length & 0x00ff);
#if DNS_RDATASET_FIXED #if DNS_RDATASET_FIXED
tcurrent += 2; /* fill in later */ tcurrent += 2; /* fill in later */
#endif #endif
memcpy(tcurrent, ordata.data, length); memcpy(tcurrent, data, length);
tcurrent += length; tcurrent += length;
oadded++; oadded++;
if (oadded < ocount) { if (oadded < ocount) {
@ -748,12 +804,17 @@ dns_rdataslab_merge(unsigned char *oslab, unsigned char *nslab,
offsettable[ocount + norder] = tcurrent - offsetbase; offsettable[ocount + norder] = tcurrent - offsetbase;
#endif #endif
length = nrdata.length; length = nrdata.length;
data = nrdata.data;
if (type == dns_rdatatype_rrsig) {
length++;
data--;
}
*tcurrent++ = (length & 0xff00) >> 8; *tcurrent++ = (length & 0xff00) >> 8;
*tcurrent++ = (length & 0x00ff); *tcurrent++ = (length & 0x00ff);
#if DNS_RDATASET_FIXED #if DNS_RDATASET_FIXED
tcurrent += 2; /* fill in later */ tcurrent += 2; /* fill in later */
#endif #endif
memcpy(tcurrent, nrdata.data, length); memcpy(tcurrent, data, length);
tcurrent += length; tcurrent += length;
nadded++; nadded++;
if (nadded < ncount) { if (nadded < ncount) {

View File

@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE. * 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 */ /*! \file */
@ -97,6 +97,7 @@ in_rootns(dns_rdataset_t *rootns, dns_name_t *name) {
if (dns_name_compare(name, &ns.name) == 0) if (dns_name_compare(name, &ns.name) == 0)
return (ISC_R_SUCCESS); return (ISC_R_SUCCESS);
result = dns_rdataset_next(rootns); result = dns_rdataset_next(rootns);
dns_rdata_reset(&rdata);
} }
if (result == ISC_R_NOMORE) if (result == ISC_R_NOMORE)
result = ISC_R_NOTFOUND; 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)) { (rresult == ISC_R_SUCCESS || rresult == DNS_R_GLUE)) {
result = dns_rdataset_first(&rootrrset); result = dns_rdataset_first(&rootrrset);
while (result == ISC_R_SUCCESS) { while (result == ISC_R_SUCCESS) {
dns_rdata_reset(&rdata);
dns_rdataset_current(&rootrrset, &rdata); dns_rdataset_current(&rootrrset, &rdata);
if (!inrrset(&hintrrset, &rdata)) if (!inrrset(&hintrrset, &rdata))
report(view, name, ISC_TRUE, &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); result = dns_rdataset_first(&hintrrset);
while (result == ISC_R_SUCCESS) { while (result == ISC_R_SUCCESS) {
dns_rdata_reset(&rdata);
dns_rdataset_current(&hintrrset, &rdata); dns_rdataset_current(&hintrrset, &rdata);
if (!inrrset(&rootrrset, &rdata)) if (!inrrset(&rootrrset, &rdata))
report(view, name, ISC_FALSE, &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)) { (rresult == ISC_R_SUCCESS || rresult == DNS_R_GLUE)) {
result = dns_rdataset_first(&rootrrset); result = dns_rdataset_first(&rootrrset);
while (result == ISC_R_SUCCESS) { while (result == ISC_R_SUCCESS) {
dns_rdata_reset(&rdata);
dns_rdataset_current(&rootrrset, &rdata); dns_rdataset_current(&rootrrset, &rdata);
report(view, name, ISC_TRUE, &rdata); report(view, name, ISC_TRUE, &rdata);
result = dns_rdataset_next(&rootrrset); 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)) { (rresult == ISC_R_SUCCESS || rresult == DNS_R_GLUE)) {
result = dns_rdataset_first(&rootrrset); result = dns_rdataset_first(&rootrrset);
while (result == ISC_R_SUCCESS) { while (result == ISC_R_SUCCESS) {
dns_rdata_reset(&rdata);
dns_rdataset_current(&rootrrset, &rdata); dns_rdataset_current(&rootrrset, &rdata);
if (!inrrset(&hintrrset, &rdata)) if (!inrrset(&hintrrset, &rdata))
report(view, name, ISC_TRUE, &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); result = dns_rdataset_first(&hintrrset);
while (result == ISC_R_SUCCESS) { while (result == ISC_R_SUCCESS) {
dns_rdata_reset(&rdata);
dns_rdataset_current(&hintrrset, &rdata); dns_rdataset_current(&hintrrset, &rdata);
if (!inrrset(&rootrrset, &rdata)) if (!inrrset(&rootrrset, &rdata))
report(view, name, ISC_FALSE, &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)) { (rresult == ISC_R_SUCCESS || rresult == DNS_R_GLUE)) {
result = dns_rdataset_first(&rootrrset); result = dns_rdataset_first(&rootrrset);
while (result == ISC_R_SUCCESS) { while (result == ISC_R_SUCCESS) {
dns_rdata_reset(&rdata);
dns_rdataset_current(&rootrrset, &rdata); dns_rdataset_current(&rootrrset, &rdata);
report(view, name, ISC_TRUE, &rdata); report(view, name, ISC_TRUE, &rdata);
dns_rdata_reset(&rdata); dns_rdata_reset(&rdata);

View File

@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE. * 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 */ /*! \file */
@ -1247,6 +1247,10 @@ static dns_dbmethods_t sdb_methods = {
overmem, overmem,
settask, settask,
NULL, NULL,
NULL,
NULL,
NULL,
NULL,
NULL NULL
}; };

View File

@ -50,7 +50,7 @@
* USE OR PERFORMANCE OF THIS SOFTWARE. * 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 */ /*! \file */
@ -1051,6 +1051,10 @@ static dns_dbmethods_t sdlzdb_methods = {
overmem, overmem,
settask, settask,
NULL, NULL,
NULL,
NULL,
NULL,
NULL,
NULL NULL
}; };

View File

@ -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 */ /*! \file */
#include <config.h> #include <config.h>
@ -445,7 +445,7 @@ cleanup_ring(dns_tsig_keyring_t *ring)
dns_rbtnodechain_current(&chain, &foundname, origin, &node); dns_rbtnodechain_current(&chain, &foundname, origin, &node);
tkey = node->data; tkey = node->data;
if (tkey != NULL) { 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 if (tkey->generated
&& isc_refcount_current(&tkey->refs) == 1 && isc_refcount_current(&tkey->refs) == 1
&& tkey->inception != tkey->expire && tkey->inception != tkey->expire

File diff suppressed because it is too large Load Diff

View File

@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE. * 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 */ /*! \file */
@ -112,7 +112,7 @@ typedef ISC_LIST(debuglink_t) debuglist_t;
static ISC_LIST(isc_mem_t) contexts; static ISC_LIST(isc_mem_t) contexts;
static isc_once_t once = ISC_ONCE_INIT; 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. * Total size of lost memory due to a bug of external library.
@ -124,7 +124,7 @@ struct isc_mem {
unsigned int magic; unsigned int magic;
isc_ondestroy_t ondestroy; isc_ondestroy_t ondestroy;
unsigned int flags; unsigned int flags;
isc_mutex_t lock; isc_mutex_t memlock;
isc_memalloc_t memalloc; isc_memalloc_t memalloc;
isc_memfree_t memfree; isc_memfree_t memfree;
void * arg; void * arg;
@ -702,7 +702,7 @@ default_memfree(void *arg, void *ptr) {
static void static void
initialize_action(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); ISC_LIST_INIT(contexts);
totallost = 0; totallost = 0;
} }
@ -742,7 +742,7 @@ isc_mem_createx2(size_t init_max_size, size_t target_size,
return (ISC_R_NOMEMORY); return (ISC_R_NOMEMORY);
if ((flags & ISC_MEMFLAG_NOLOCK) == 0) { if ((flags & ISC_MEMFLAG_NOLOCK) == 0) {
result = isc_mutex_init(&ctx->lock); result = isc_mutex_init(&ctx->memlock);
if (result != ISC_R_SUCCESS) { if (result != ISC_R_SUCCESS) {
(memfree)(arg, ctx); (memfree)(arg, ctx);
return (result); return (result);
@ -827,9 +827,9 @@ isc_mem_createx2(size_t init_max_size, size_t target_size,
ctx->memalloc_failures = 0; ctx->memalloc_failures = 0;
LOCK(&lock); LOCK(&contextlock);
ISC_LIST_INITANDAPPEND(contexts, ctx, link); ISC_LIST_INITANDAPPEND(contexts, ctx, link);
UNLOCK(&lock); UNLOCK(&contextlock);
*ctxp = ctx; *ctxp = ctx;
return (ISC_R_SUCCESS); 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); (ctx->memfree)(ctx->arg, ctx->debuglist);
#endif /* ISC_MEM_TRACKLINES */ #endif /* ISC_MEM_TRACKLINES */
if ((ctx->flags & ISC_MEMFLAG_NOLOCK) == 0) if ((ctx->flags & ISC_MEMFLAG_NOLOCK) == 0)
DESTROYLOCK(&ctx->lock); DESTROYLOCK(&ctx->memlock);
(memfree)(arg, ctx); (memfree)(arg, ctx);
} }
@ -877,10 +877,10 @@ destroy(isc_mem_t *ctx) {
ctx->magic = 0; ctx->magic = 0;
LOCK(&lock); LOCK(&contextlock);
ISC_LIST_UNLINK(contexts, ctx, link); ISC_LIST_UNLINK(contexts, ctx, link);
totallost += ctx->inuse; totallost += ctx->inuse;
UNLOCK(&lock); UNLOCK(&contextlock);
INSIST(ISC_LIST_EMPTY(ctx->pools)); INSIST(ISC_LIST_EMPTY(ctx->pools));
@ -932,7 +932,7 @@ destroy(isc_mem_t *ctx) {
ondest = ctx->ondestroy; ondest = ctx->ondestroy;
if ((ctx->flags & ISC_MEMFLAG_NOLOCK) == 0) if ((ctx->flags & ISC_MEMFLAG_NOLOCK) == 0)
DESTROYLOCK(&ctx->lock); DESTROYLOCK(&ctx->memlock);
(ctx->memfree)(ctx->arg, ctx); (ctx->memfree)(ctx->arg, ctx);
isc_ondestroy_notify(&ondest, 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(VALID_CONTEXT(source));
REQUIRE(targetp != NULL && *targetp == NULL); REQUIRE(targetp != NULL && *targetp == NULL);
MCTXLOCK(source, &source->lock); MCTXLOCK(source, &source->memlock);
source->references++; source->references++;
MCTXUNLOCK(source, &source->lock); MCTXUNLOCK(source, &source->memlock);
*targetp = source; *targetp = source;
} }
@ -959,12 +959,12 @@ isc_mem_detach(isc_mem_t **ctxp) {
ctx = *ctxp; ctx = *ctxp;
REQUIRE(VALID_CONTEXT(ctx)); REQUIRE(VALID_CONTEXT(ctx));
MCTXLOCK(ctx, &ctx->lock); MCTXLOCK(ctx, &ctx->memlock);
INSIST(ctx->references > 0); INSIST(ctx->references > 0);
ctx->references--; ctx->references--;
if (ctx->references == 0) if (ctx->references == 0)
want_destroy = ISC_TRUE; want_destroy = ISC_TRUE;
MCTXUNLOCK(ctx, &ctx->lock); MCTXUNLOCK(ctx, &ctx->memlock);
if (want_destroy) if (want_destroy)
destroy(ctx); 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); isc__mem_free(ctx, ptr FLARG_PASS);
MCTXLOCK(ctx, &ctx->lock); MCTXLOCK(ctx, &ctx->memlock);
ctx->references--; ctx->references--;
if (ctx->references == 0) if (ctx->references == 0)
want_destroy = ISC_TRUE; want_destroy = ISC_TRUE;
MCTXUNLOCK(ctx, &ctx->lock); MCTXUNLOCK(ctx, &ctx->memlock);
if (want_destroy) if (want_destroy)
destroy(ctx); 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) { if ((ctx->flags & ISC_MEMFLAG_INTERNAL) != 0) {
MCTXLOCK(ctx, &ctx->lock); MCTXLOCK(ctx, &ctx->memlock);
mem_putunlocked(ctx, ptr, size); mem_putunlocked(ctx, ptr, size);
} else { } else {
mem_put(ctx, ptr, size); mem_put(ctx, ptr, size);
MCTXLOCK(ctx, &ctx->lock); MCTXLOCK(ctx, &ctx->memlock);
mem_putstats(ctx, ptr, size); 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) if (ctx->references == 0)
want_destroy = ISC_TRUE; want_destroy = ISC_TRUE;
MCTXUNLOCK(ctx, &ctx->lock); MCTXUNLOCK(ctx, &ctx->memlock);
if (want_destroy) if (want_destroy)
destroy(ctx); destroy(ctx);
@ -1055,14 +1055,14 @@ isc_mem_destroy(isc_mem_t **ctxp) {
ctx = *ctxp; ctx = *ctxp;
REQUIRE(VALID_CONTEXT(ctx)); REQUIRE(VALID_CONTEXT(ctx));
MCTXLOCK(ctx, &ctx->lock); MCTXLOCK(ctx, &ctx->memlock);
#if ISC_MEM_TRACKLINES #if ISC_MEM_TRACKLINES
if (ctx->references != 1) if (ctx->references != 1)
print_active(ctx, stderr); print_active(ctx, stderr);
#endif #endif
REQUIRE(ctx->references == 1); REQUIRE(ctx->references == 1);
ctx->references--; ctx->references--;
MCTXUNLOCK(ctx, &ctx->lock); MCTXUNLOCK(ctx, &ctx->memlock);
destroy(ctx); 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_mem_ondestroy(isc_mem_t *ctx, isc_task_t *task, isc_event_t **event) {
isc_result_t res; isc_result_t res;
MCTXLOCK(ctx, &ctx->lock); MCTXLOCK(ctx, &ctx->memlock);
res = isc_ondestroy_register(&ctx->ondestroy, task, event); res = isc_ondestroy_register(&ctx->ondestroy, task, event);
MCTXUNLOCK(ctx, &ctx->lock); MCTXUNLOCK(ctx, &ctx->memlock);
return (res); 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)); return (isc__mem_allocate(ctx, size FLARG_PASS));
if ((ctx->flags & ISC_MEMFLAG_INTERNAL) != 0) { if ((ctx->flags & ISC_MEMFLAG_INTERNAL) != 0) {
MCTXLOCK(ctx, &ctx->lock); MCTXLOCK(ctx, &ctx->memlock);
ptr = mem_getunlocked(ctx, size); ptr = mem_getunlocked(ctx, size);
} else { } else {
ptr = mem_get(ctx, size); ptr = mem_get(ctx, size);
MCTXLOCK(ctx, &ctx->lock); MCTXLOCK(ctx, &ctx->memlock);
if (ptr != NULL) if (ptr != NULL)
mem_getstats(ctx, size); mem_getstats(ctx, size);
} }
@ -1113,7 +1113,7 @@ isc__mem_get(isc_mem_t *ctx, size_t size FLARG) {
fprintf(stderr, "maxinuse = %lu\n", fprintf(stderr, "maxinuse = %lu\n",
(unsigned long)ctx->inuse); (unsigned long)ctx->inuse);
} }
MCTXUNLOCK(ctx, &ctx->lock); MCTXUNLOCK(ctx, &ctx->memlock);
if (call_water) if (call_water)
(ctx->water)(ctx->water_arg, ISC_MEM_HIWATER); (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) { if ((ctx->flags & ISC_MEMFLAG_INTERNAL) != 0) {
MCTXLOCK(ctx, &ctx->lock); MCTXLOCK(ctx, &ctx->memlock);
mem_putunlocked(ctx, ptr, size); mem_putunlocked(ctx, ptr, size);
} else { } else {
mem_put(ctx, ptr, size); mem_put(ctx, ptr, size);
MCTXLOCK(ctx, &ctx->lock); MCTXLOCK(ctx, &ctx->memlock);
mem_putstats(ctx, ptr, size); 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) if (ctx->water != NULL)
call_water = ISC_TRUE; call_water = ISC_TRUE;
} }
MCTXUNLOCK(ctx, &ctx->lock); MCTXUNLOCK(ctx, &ctx->memlock);
if (call_water) if (call_water)
(ctx->water)(ctx->water_arg, ISC_MEM_LOWATER); (ctx->water)(ctx->water_arg, ISC_MEM_LOWATER);
@ -1174,12 +1174,12 @@ void
isc_mem_waterack(isc_mem_t *ctx, int flag) { isc_mem_waterack(isc_mem_t *ctx, int flag) {
REQUIRE(VALID_CONTEXT(ctx)); REQUIRE(VALID_CONTEXT(ctx));
MCTXLOCK(ctx, &ctx->lock); MCTXLOCK(ctx, &ctx->memlock);
if (flag == ISC_MEM_LOWATER) if (flag == ISC_MEM_LOWATER)
ctx->hi_called = ISC_FALSE; ctx->hi_called = ISC_FALSE;
else if (flag == ISC_MEM_HIWATER) else if (flag == ISC_MEM_HIWATER)
ctx->hi_called = ISC_TRUE; ctx->hi_called = ISC_TRUE;
MCTXUNLOCK(ctx, &ctx->lock); MCTXUNLOCK(ctx, &ctx->memlock);
} }
#if ISC_MEM_TRACKLINES #if ISC_MEM_TRACKLINES
@ -1233,7 +1233,7 @@ isc_mem_stats(isc_mem_t *ctx, FILE *out) {
const isc_mempool_t *pool; const isc_mempool_t *pool;
REQUIRE(VALID_CONTEXT(ctx)); REQUIRE(VALID_CONTEXT(ctx));
MCTXLOCK(ctx, &ctx->lock); MCTXLOCK(ctx, &ctx->memlock);
for (i = 0; i <= ctx->max_size; i++) { for (i = 0; i <= ctx->max_size; i++) {
s = &ctx->stats[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 * 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 * 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 * 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. * stats fields is always safe.
*/ */
pool = ISC_LIST_HEAD(ctx->pools); pool = ISC_LIST_HEAD(ctx->pools);
@ -1294,7 +1294,7 @@ isc_mem_stats(isc_mem_t *ctx, FILE *out) {
print_active(ctx, out); print_active(ctx, out);
#endif #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)); REQUIRE(VALID_CONTEXT(ctx));
if ((ctx->flags & ISC_MEMFLAG_INTERNAL) != 0) { if ((ctx->flags & ISC_MEMFLAG_INTERNAL) != 0) {
MCTXLOCK(ctx, &ctx->lock); MCTXLOCK(ctx, &ctx->memlock);
si = isc__mem_allocateunlocked(ctx, size); si = isc__mem_allocateunlocked(ctx, size);
} else { } else {
si = isc__mem_allocateunlocked(ctx, size); si = isc__mem_allocateunlocked(ctx, size);
MCTXLOCK(ctx, &ctx->lock); MCTXLOCK(ctx, &ctx->memlock);
if (si != NULL) if (si != NULL)
mem_getstats(ctx, si[-1].u.size); 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", fprintf(stderr, "maxinuse = %lu\n",
(unsigned long)ctx->inuse); (unsigned long)ctx->inuse);
} }
MCTXUNLOCK(ctx, &ctx->lock); MCTXUNLOCK(ctx, &ctx->memlock);
if (call_water) if (call_water)
(ctx->water)(ctx->water_arg, ISC_MEM_HIWATER); (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) { if ((ctx->flags & ISC_MEMFLAG_INTERNAL) != 0) {
MCTXLOCK(ctx, &ctx->lock); MCTXLOCK(ctx, &ctx->memlock);
mem_putunlocked(ctx, si, size); mem_putunlocked(ctx, si, size);
} else { } else {
mem_put(ctx, si, size); mem_put(ctx, si, size);
MCTXLOCK(ctx, &ctx->lock); MCTXLOCK(ctx, &ctx->memlock);
mem_putstats(ctx, si, size); mem_putstats(ctx, si, size);
} }
@ -1406,7 +1406,7 @@ isc__mem_free(isc_mem_t *ctx, void *ptr FLARG) {
if (ctx->water != NULL) if (ctx->water != NULL)
call_water = ISC_TRUE; call_water = ISC_TRUE;
} }
MCTXUNLOCK(ctx, &ctx->lock); MCTXUNLOCK(ctx, &ctx->memlock);
if (call_water) if (call_water)
(ctx->water)(ctx->water_arg, ISC_MEM_LOWATER); (ctx->water)(ctx->water_arg, ISC_MEM_LOWATER);
@ -1438,11 +1438,11 @@ isc__mem_strdup(isc_mem_t *mctx, const char *s FLARG) {
void void
isc_mem_setdestroycheck(isc_mem_t *ctx, isc_boolean_t flag) { isc_mem_setdestroycheck(isc_mem_t *ctx, isc_boolean_t flag) {
REQUIRE(VALID_CONTEXT(ctx)); REQUIRE(VALID_CONTEXT(ctx));
MCTXLOCK(ctx, &ctx->lock); MCTXLOCK(ctx, &ctx->memlock);
ctx->checkfree = flag; 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 void
isc_mem_setquota(isc_mem_t *ctx, size_t quota) { isc_mem_setquota(isc_mem_t *ctx, size_t quota) {
REQUIRE(VALID_CONTEXT(ctx)); REQUIRE(VALID_CONTEXT(ctx));
MCTXLOCK(ctx, &ctx->lock); MCTXLOCK(ctx, &ctx->memlock);
ctx->quota = quota; ctx->quota = quota;
MCTXUNLOCK(ctx, &ctx->lock); MCTXUNLOCK(ctx, &ctx->memlock);
} }
size_t size_t
@ -1464,11 +1464,11 @@ isc_mem_getquota(isc_mem_t *ctx) {
size_t quota; size_t quota;
REQUIRE(VALID_CONTEXT(ctx)); REQUIRE(VALID_CONTEXT(ctx));
MCTXLOCK(ctx, &ctx->lock); MCTXLOCK(ctx, &ctx->memlock);
quota = ctx->quota; quota = ctx->quota;
MCTXUNLOCK(ctx, &ctx->lock); MCTXUNLOCK(ctx, &ctx->memlock);
return (quota); return (quota);
} }
@ -1478,11 +1478,11 @@ isc_mem_inuse(isc_mem_t *ctx) {
size_t inuse; size_t inuse;
REQUIRE(VALID_CONTEXT(ctx)); REQUIRE(VALID_CONTEXT(ctx));
MCTXLOCK(ctx, &ctx->lock); MCTXLOCK(ctx, &ctx->memlock);
inuse = ctx->inuse; inuse = ctx->inuse;
MCTXUNLOCK(ctx, &ctx->lock); MCTXUNLOCK(ctx, &ctx->memlock);
return (inuse); 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(VALID_CONTEXT(ctx));
REQUIRE(hiwater >= lowater); REQUIRE(hiwater >= lowater);
MCTXLOCK(ctx, &ctx->lock); MCTXLOCK(ctx, &ctx->memlock);
oldwater = ctx->water; oldwater = ctx->water;
oldwater_arg = ctx->water_arg; oldwater_arg = ctx->water_arg;
if (water == NULL) { 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->lo_water = lowater;
ctx->hi_called = ISC_FALSE; ctx->hi_called = ISC_FALSE;
} }
MCTXUNLOCK(ctx, &ctx->lock); MCTXUNLOCK(ctx, &ctx->memlock);
if (callwater && oldwater != NULL) if (callwater && oldwater != NULL)
(oldwater)(oldwater_arg, ISC_MEM_LOWATER); (oldwater)(oldwater_arg, ISC_MEM_LOWATER);
@ -1529,11 +1529,11 @@ void
isc_mem_setname(isc_mem_t *ctx, const char *name, void *tag) { isc_mem_setname(isc_mem_t *ctx, const char *name, void *tag) {
REQUIRE(VALID_CONTEXT(ctx)); REQUIRE(VALID_CONTEXT(ctx));
LOCK(&ctx->lock); LOCK(&ctx->memlock);
memset(ctx->name, 0, sizeof(ctx->name)); memset(ctx->name, 0, sizeof(ctx->name));
strncpy(ctx->name, name, sizeof(ctx->name) - 1); strncpy(ctx->name, name, sizeof(ctx->name) - 1);
ctx->tag = tag; ctx->tag = tag;
UNLOCK(&ctx->lock); UNLOCK(&ctx->memlock);
} }
const char * const char *
@ -1587,10 +1587,10 @@ isc_mempool_create(isc_mem_t *mctx, size_t size, isc_mempool_t **mpctxp) {
*mpctxp = mpctx; *mpctxp = mpctx;
MCTXLOCK(mctx, &mctx->lock); MCTXLOCK(mctx, &mctx->memlock);
ISC_LIST_INITANDAPPEND(mctx->pools, mpctx, link); ISC_LIST_INITANDAPPEND(mctx->pools, mpctx, link);
mctx->poolcnt++; mctx->poolcnt++;
MCTXUNLOCK(mctx, &mctx->lock); MCTXUNLOCK(mctx, &mctx->memlock);
return (ISC_R_SUCCESS); return (ISC_R_SUCCESS);
} }
@ -1643,7 +1643,7 @@ isc_mempool_destroy(isc_mempool_t **mpctxp) {
/* /*
* Return any items on the free list * Return any items on the free list
*/ */
MCTXLOCK(mctx, &mctx->lock); MCTXLOCK(mctx, &mctx->memlock);
while (mpctx->items != NULL) { while (mpctx->items != NULL) {
INSIST(mpctx->freecount > 0); INSIST(mpctx->freecount > 0);
mpctx->freecount--; mpctx->freecount--;
@ -1657,15 +1657,15 @@ isc_mempool_destroy(isc_mempool_t **mpctxp) {
mem_putstats(mctx, item, mpctx->size); mem_putstats(mctx, item, mpctx->size);
} }
} }
MCTXUNLOCK(mctx, &mctx->lock); MCTXUNLOCK(mctx, &mctx->memlock);
/* /*
* Remove our linked list entry from the memory context. * Remove our linked list entry from the memory context.
*/ */
MCTXLOCK(mctx, &mctx->lock); MCTXLOCK(mctx, &mctx->memlock);
ISC_LIST_UNLINK(mctx->pools, mpctx, link); ISC_LIST_UNLINK(mctx->pools, mpctx, link);
mctx->poolcnt--; mctx->poolcnt--;
MCTXUNLOCK(mctx, &mctx->lock); MCTXUNLOCK(mctx, &mctx->memlock);
mpctx->magic = 0; 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 * We need to dip into the well. Lock the memory context here and
* fill up our free list. * fill up our free list.
*/ */
MCTXLOCK(mctx, &mctx->lock); MCTXLOCK(mctx, &mctx->memlock);
for (i = 0; i < mpctx->fillcount; i++) { for (i = 0; i < mpctx->fillcount; i++) {
if ((mctx->flags & ISC_MEMFLAG_INTERNAL) != 0) { if ((mctx->flags & ISC_MEMFLAG_INTERNAL) != 0) {
item = mem_getunlocked(mctx, mpctx->size); item = mem_getunlocked(mctx, mpctx->size);
@ -1739,7 +1739,7 @@ isc__mempool_get(isc_mempool_t *mpctx FLARG) {
mpctx->items = item; mpctx->items = item;
mpctx->freecount++; mpctx->freecount++;
} }
MCTXUNLOCK(mctx, &mctx->lock); MCTXUNLOCK(mctx, &mctx->memlock);
/* /*
* If we didn't get any items, return NULL. * 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 ISC_MEM_TRACKLINES
if (item != NULL) { if (item != NULL) {
MCTXLOCK(mctx, &mctx->lock); MCTXLOCK(mctx, &mctx->memlock);
ADD_TRACE(mctx, item, mpctx->size, file, line); ADD_TRACE(mctx, item, mpctx->size, file, line);
MCTXUNLOCK(mctx, &mctx->lock); MCTXUNLOCK(mctx, &mctx->memlock);
} }
#endif /* ISC_MEM_TRACKLINES */ #endif /* ISC_MEM_TRACKLINES */
@ -1785,9 +1785,9 @@ isc__mempool_put(isc_mempool_t *mpctx, void *mem FLARG) {
mpctx->allocated--; mpctx->allocated--;
#if ISC_MEM_TRACKLINES #if ISC_MEM_TRACKLINES
MCTXLOCK(mctx, &mctx->lock); MCTXLOCK(mctx, &mctx->memlock);
DELETE_TRACE(mctx, mem, mpctx->size, file, line); DELETE_TRACE(mctx, mem, mpctx->size, file, line);
MCTXUNLOCK(mctx, &mctx->lock); MCTXUNLOCK(mctx, &mctx->memlock);
#endif /* ISC_MEM_TRACKLINES */ #endif /* ISC_MEM_TRACKLINES */
/* /*
@ -1795,14 +1795,14 @@ isc__mempool_put(isc_mempool_t *mpctx, void *mem FLARG) {
*/ */
if (mpctx->freecount >= mpctx->freemax) { if (mpctx->freecount >= mpctx->freemax) {
if ((mctx->flags & ISC_MEMFLAG_INTERNAL) != 0) { if ((mctx->flags & ISC_MEMFLAG_INTERNAL) != 0) {
MCTXLOCK(mctx, &mctx->lock); MCTXLOCK(mctx, &mctx->memlock);
mem_putunlocked(mctx, mem, mpctx->size); mem_putunlocked(mctx, mem, mpctx->size);
MCTXUNLOCK(mctx, &mctx->lock); MCTXUNLOCK(mctx, &mctx->memlock);
} else { } else {
mem_put(mctx, mem, mpctx->size); mem_put(mctx, mem, mpctx->size);
MCTXLOCK(mctx, &mctx->lock); MCTXLOCK(mctx, &mctx->memlock);
mem_putstats(mctx, mem, mpctx->size); mem_putstats(mctx, mem, mpctx->size);
MCTXUNLOCK(mctx, &mctx->lock); MCTXUNLOCK(mctx, &mctx->memlock);
} }
if (mpctx->lock != NULL) if (mpctx->lock != NULL)
UNLOCK(mpctx->lock); UNLOCK(mpctx->lock);
@ -1975,14 +1975,14 @@ isc_mem_printallactive(FILE *file) {
RUNTIME_CHECK(isc_once_do(&once, initialize_action) == ISC_R_SUCCESS); RUNTIME_CHECK(isc_once_do(&once, initialize_action) == ISC_R_SUCCESS);
LOCK(&lock); LOCK(&contextlock);
for (ctx = ISC_LIST_HEAD(contexts); for (ctx = ISC_LIST_HEAD(contexts);
ctx != NULL; ctx != NULL;
ctx = ISC_LIST_NEXT(ctx, link)) { ctx = ISC_LIST_NEXT(ctx, link)) {
fprintf(file, "context: %p\n", ctx); fprintf(file, "context: %p\n", ctx);
print_active(ctx, file); print_active(ctx, file);
} }
UNLOCK(&lock); UNLOCK(&contextlock);
#endif #endif
} }
@ -1991,7 +1991,7 @@ isc_mem_checkdestroyed(FILE *file) {
RUNTIME_CHECK(isc_once_do(&once, initialize_action) == ISC_R_SUCCESS); RUNTIME_CHECK(isc_once_do(&once, initialize_action) == ISC_R_SUCCESS);
LOCK(&lock); LOCK(&contextlock);
if (!ISC_LIST_EMPTY(contexts)) { if (!ISC_LIST_EMPTY(contexts)) {
#if ISC_MEM_TRACKLINES #if ISC_MEM_TRACKLINES
isc_mem_t *ctx; isc_mem_t *ctx;
@ -2006,7 +2006,7 @@ isc_mem_checkdestroyed(FILE *file) {
#endif #endif
INSIST(0); INSIST(0);
} }
UNLOCK(&lock); UNLOCK(&contextlock);
} }
unsigned int unsigned int
@ -2014,9 +2014,9 @@ isc_mem_references(isc_mem_t *ctx) {
unsigned int references; unsigned int references;
REQUIRE(VALID_CONTEXT(ctx)); REQUIRE(VALID_CONTEXT(ctx));
MCTXLOCK(ctx, &ctx->lock); MCTXLOCK(ctx, &ctx->memlock);
references = ctx->references; references = ctx->references;
MCTXUNLOCK(ctx, &ctx->lock); MCTXUNLOCK(ctx, &ctx->memlock);
return (references); return (references);
} }
@ -2047,7 +2047,7 @@ renderctx(isc_mem_t *ctx, summarystat_t *summary, xmlTextWriterPtr writer) {
} }
REQUIRE(VALID_CONTEXT(ctx)); REQUIRE(VALID_CONTEXT(ctx));
MCTXLOCK(ctx, &ctx->lock); MCTXLOCK(ctx, &ctx->memlock);
summary->contextsize += sizeof(*ctx) + summary->contextsize += sizeof(*ctx) +
(ctx->max_size + 1) * sizeof(struct stats) + (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); (isc_uint64_t)ctx->lo_water);
xmlTextWriterEndElement(writer); /* lowater */ xmlTextWriterEndElement(writer); /* lowater */
MCTXUNLOCK(ctx, &ctx->lock); MCTXUNLOCK(ctx, &ctx->memlock);
xmlTextWriterEndElement(writer); /* context */ xmlTextWriterEndElement(writer); /* context */
} }
@ -2127,14 +2127,14 @@ isc_mem_renderxml(xmlTextWriterPtr writer) {
RUNTIME_CHECK(isc_once_do(&once, initialize_action) == ISC_R_SUCCESS); RUNTIME_CHECK(isc_once_do(&once, initialize_action) == ISC_R_SUCCESS);
LOCK(&lock); LOCK(&contextlock);
lost = totallost; lost = totallost;
for (ctx = ISC_LIST_HEAD(contexts); for (ctx = ISC_LIST_HEAD(contexts);
ctx != NULL; ctx != NULL;
ctx = ISC_LIST_NEXT(ctx, link)) { ctx = ISC_LIST_NEXT(ctx, link)) {
renderctx(ctx, &summary, writer); renderctx(ctx, &summary, writer);
} }
UNLOCK(&lock); UNLOCK(&contextlock);
xmlTextWriterEndElement(writer); /* contexts */ xmlTextWriterEndElement(writer); /* contexts */