diff options
Diffstat (limited to 'lib/dns/zone.c')
-rw-r--r-- | lib/dns/zone.c | 468 |
1 files changed, 344 insertions, 124 deletions
diff --git a/lib/dns/zone.c b/lib/dns/zone.c index 22db239..c212bf6 100644 --- a/lib/dns/zone.c +++ b/lib/dns/zone.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2004-2012 Internet Systems Consortium, Inc. ("ISC") + * Copyright (C) 2004-2013 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 1999-2003 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any @@ -335,9 +335,9 @@ struct dns_zone { isc_boolean_t added; /*% - * whether a rpz radix was needed when last loaded + * whether this is a response policy zone */ - isc_boolean_t rpz_zone; + isc_boolean_t is_rpz; /*% * Outstanding forwarded UPDATE requests. @@ -345,6 +345,18 @@ struct dns_zone { dns_forwardlist_t forwards; }; +typedef struct { + dns_diff_t *diff; + isc_boolean_t offline; +} zonediff_t; + +#define zonediff_init(z, d) \ + do { \ + zonediff_t *_z = (z); \ + (_z)->diff = (d); \ + (_z)->offline = ISC_FALSE; \ + } while (0) + #define DNS_ZONE_FLAG(z,f) (ISC_TF(((z)->flags & (f)) != 0)) #define DNS_ZONE_SETFLAG(z,f) do { \ INSIST(LOCKED_ZONE(z)); \ @@ -855,7 +867,7 @@ dns_zone_create(dns_zone_t **zonep, isc_mem_t *mctx) { zone->nodes = 100; zone->privatetype = (dns_rdatatype_t)0xffffU; zone->added = ISC_FALSE; - zone->rpz_zone = ISC_FALSE; + zone->is_rpz = ISC_FALSE; ISC_LIST_INIT(zone->forwards); zone->magic = ZONE_MAGIC; @@ -1042,6 +1054,7 @@ dns_zone_setnotifytype(dns_zone_t *zone, dns_notifytype_t notifytype) { isc_result_t dns_zone_getserial2(dns_zone_t *zone, isc_uint32_t *serialp) { isc_result_t result; + unsigned int soacount; REQUIRE(DNS_ZONE_VALID(zone)); REQUIRE(serialp != NULL); @@ -1049,8 +1062,11 @@ dns_zone_getserial2(dns_zone_t *zone, isc_uint32_t *serialp) { LOCK_ZONE(zone); ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read); if (zone->db != NULL) { - result = zone_get_from_db(zone, zone->db, NULL, NULL, serialp, - NULL, NULL, NULL, NULL, NULL); + result = zone_get_from_db(zone, zone->db, NULL, &soacount, + serialp, NULL, NULL, NULL, NULL, + NULL); + if (result == ISC_R_SUCCESS && soacount == 0) + result = ISC_R_FAILURE; } else result = DNS_R_NOTLOADED; ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read); @@ -1390,6 +1406,30 @@ zone_isdynamic(dns_zone_t *zone) { !dns_acl_isnone(zone->update_acl)))); } +/* + * Set the response policy index and information for a zone. + */ +isc_result_t +dns_zone_rpz_enable(dns_zone_t *zone) { + /* + * Only RBTDB zones can be used for response policy zones, + * because only they have the code to load the create the summary data. + * Only zones that are loaded instead of mmap()ed create the + * summary data and so can be policy zones. + */ + if (strcmp(zone->db_argv[0], "rbt") != 0 && + strcmp(zone->db_argv[0], "rbt64") != 0) + return (ISC_R_NOTIMPLEMENTED); + + zone->is_rpz = ISC_TRUE; + + return (ISC_R_SUCCESS); +} + +isc_boolean_t +dns_zone_get_rpz(dns_zone_t *zone) { + return (zone->is_rpz); +} static isc_result_t zone_load(dns_zone_t *zone, unsigned int flags) { @@ -1459,8 +1499,7 @@ zone_load(dns_zone_t *zone, unsigned int flags) { * "rndc reconfig", we are done. */ if (!isc_time_isepoch(&zone->loadtime) && - (flags & DNS_ZONELOADFLAG_NOSTAT) != 0 && - zone->rpz_zone == dns_rpz_needed()) { + (flags & DNS_ZONELOADFLAG_NOSTAT) != 0) { result = ISC_R_SUCCESS; goto cleanup; } @@ -1469,8 +1508,7 @@ zone_load(dns_zone_t *zone, unsigned int flags) { if (result == ISC_R_SUCCESS) { if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADED) && !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_HASINCLUDE) && - isc_time_compare(&filetime, &zone->loadtime) <= 0 && - zone->rpz_zone == dns_rpz_needed()) { + isc_time_compare(&filetime, &zone->loadtime) <= 0) { dns_zone_log(zone, ISC_LOG_DEBUG(1), "skipping load: master file " "older than last load"); @@ -1478,7 +1516,6 @@ zone_load(dns_zone_t *zone, unsigned int flags) { goto cleanup; } loadtime = filetime; - zone->rpz_zone = dns_rpz_needed(); } } @@ -1704,8 +1741,15 @@ zone_startload(dns_db_t *db, dns_zone_t *zone, isc_time_t loadtime) { isc_result_t tresult; unsigned int options; - options = get_master_options(zone); +#ifdef BIND9 + if (zone->is_rpz) { + result = dns_db_rpz_enabled(db, NULL); + if (result != ISC_R_SUCCESS) + return (result); + } +#endif + options = get_master_options(zone); if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_MANYERRORS)) options |= DNS_MASTER_MANYERRORS; @@ -2174,6 +2218,34 @@ zone_check_dup(dns_zone_t *zone, dns_db_t *db) { } static isc_boolean_t +isspf(const dns_rdata_t *rdata) { + char buf[1024]; + const unsigned char *data = rdata->data; + unsigned int rdl = rdata->length, i = 0, tl, len; + + while (rdl > 0U) { + len = tl = *data; + ++data; + --rdl; + INSIST(tl <= rdl); + if (len > sizeof(buf) - i - 1) + len = sizeof(buf) - i - 1; + memcpy(buf + i, data, len); + i += len; + data += tl; + rdl -= tl; + } + + if (i < 6U) + return(ISC_FALSE); + + buf[i] = 0; + if (strncmp(buf, "v=spf1", 6) == 0 && (buf[6] == 0 || buf[6] == ' ')) + return (ISC_TRUE); + return (ISC_FALSE); +} + +static isc_boolean_t integrity_checks(dns_zone_t *zone, dns_db_t *db) { dns_dbiterator_t *dbiterator = NULL; dns_dbnode_t *node = NULL; @@ -2187,7 +2259,7 @@ integrity_checks(dns_zone_t *zone, dns_db_t *db) { dns_name_t *name; dns_name_t *bottom; isc_result_t result; - isc_boolean_t ok = ISC_TRUE; + isc_boolean_t ok = ISC_TRUE, have_spf, have_txt; dns_fixedname_init(&fixed); name = dns_fixedname_name(&fixed); @@ -2265,7 +2337,7 @@ integrity_checks(dns_zone_t *zone, dns_db_t *db) { result = dns_db_findrdataset(db, node, NULL, dns_rdatatype_srv, 0, 0, &rdataset, NULL); if (result != ISC_R_SUCCESS) - goto next; + goto checkspf; result = dns_rdataset_first(&rdataset); while (result == ISC_R_SUCCESS) { dns_rdataset_current(&rdataset, &rdata); @@ -2278,6 +2350,50 @@ integrity_checks(dns_zone_t *zone, dns_db_t *db) { } dns_rdataset_disassociate(&rdataset); + checkspf: + /* + * Check if there is a type TXT spf record without a type SPF + * RRset being present. + */ + if (!DNS_ZONE_OPTION(zone, DNS_ZONEOPT_CHECKSPF)) + goto next; + if (zone->rdclass != dns_rdataclass_in) + goto next; + have_spf = have_txt = ISC_FALSE; + result = dns_db_findrdataset(db, node, NULL, dns_rdatatype_spf, + 0, 0, &rdataset, NULL); + if (result == ISC_R_SUCCESS) { + dns_rdataset_disassociate(&rdataset); + have_spf = ISC_TRUE; + } + result = dns_db_findrdataset(db, node, NULL, dns_rdatatype_txt, + 0, 0, &rdataset, NULL); + if (result != ISC_R_SUCCESS) + goto notxt; + result = dns_rdataset_first(&rdataset); + while (result == ISC_R_SUCCESS) { + dns_rdataset_current(&rdataset, &rdata); + have_txt = isspf(&rdata); + dns_rdata_reset(&rdata); + if (have_txt) + break; + result = dns_rdataset_next(&rdataset); + } + dns_rdataset_disassociate(&rdataset); + + notxt: + if (have_spf != have_txt) { + char namebuf[DNS_NAME_FORMATSIZE]; + const char *found = have_txt ? "TXT" : "SPF"; + const char *need = have_txt ? "SPF" : "TXT"; + + dns_name_format(name, namebuf, sizeof(namebuf)); + dns_zone_log(zone, ISC_LOG_WARNING, "'%s' found SPF/%s " + "record but no SPF/%s record found, add " + "matching type %s record", namebuf, found, + need, need); + } + next: dns_db_detachnode(db, &node); result = dns_dbiterator_next(dbiterator); @@ -2788,6 +2904,8 @@ create_keydata(dns_zone_t *zone, dns_db_t *db, dns_dbversion_t *ver, CHECK(update_one_rr(db, ver, diff, DNS_DIFFOP_ADD, dst_key_name(key), 0, &rdata)); *changed = ISC_TRUE; + /* Refresh new keys from the zone apex as soon as possible. */ + set_refreshkeytimer(zone, &keydata, now); skip: result = dns_keytable_nextkeynode(keytable, keynode, &nextnode); @@ -2797,10 +2915,6 @@ create_keydata(dns_zone_t *zone, dns_db_t *db, dns_dbversion_t *ver, } } - /* Refresh new keys from the zone apex as soon as possible. */ - if (*changed) - set_refreshkeytimer(zone, &keydata, now); - if (keynode != NULL) dns_keytable_detachkeynode(keytable, &keynode); *keynodep = NULL; @@ -2942,7 +3056,8 @@ load_secroots(dns_zone_t *zone, dns_name_t *name, dns_rdataset_t *rdataset) { dns_rdataset_current(rdataset, &rdata); /* Convert rdata to keydata. */ - dns_rdata_tostruct(&rdata, &keydata, NULL); + result = dns_rdata_tostruct(&rdata, &keydata, NULL); + RUNTIME_CHECK(result == ISC_R_SUCCESS); /* Set the key refresh timer. */ set_refreshkeytimer(zone, &keydata, now); @@ -3285,6 +3400,13 @@ sync_keyzone(dns_zone_t *zone, dns_db_t *db) { } failure: + if (result != ISC_R_SUCCESS && + !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADED)) { + dns_zone_log(zone, ISC_LOG_ERROR, + "unable to synchronize managed keys: %s", + dns_result_totext(result)); + isc_time_settoepoch(&zone->refreshkeytime); + } if (keynode != NULL) dns_keytable_detachkeynode(sr, &keynode); if (sr != NULL) @@ -3462,14 +3584,18 @@ zone_postload(dns_zone_t *zone, dns_db_t *db, isc_time_t loadtime, } if (zone->db != NULL) { + unsigned int oldsoacount; + /* * This is checked in zone_replacedb() for slave zones * as they don't reload from disk. */ - result = zone_get_from_db(zone, zone->db, NULL, NULL, - &oldserial, NULL, NULL, NULL, - NULL, NULL); + result = zone_get_from_db(zone, zone->db, NULL, + &oldsoacount, &oldserial, + NULL, NULL, NULL, NULL, + NULL); RUNTIME_CHECK(result == ISC_R_SUCCESS); + RUNTIME_CHECK(soacount > 0U); if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_IXFRFROMDIFFS) && !isc_serial_gt(serial, oldserial)) { isc_uint32_t serialmin, serialmax; @@ -3877,6 +4003,19 @@ zone_load_soa_rr(dns_db_t *db, dns_dbnode_t *node, dns_dbversion_t *version, *expire = soa.expire; if (minimum != NULL) *minimum = soa.minimum; + } else { + if (soacount != NULL) + *soacount = 0; + if (serial != NULL) + *serial = 0; + if (refresh != NULL) + *refresh = 0; + if (retry != NULL) + *retry = 0; + if (expire != NULL) + *expire = 0; + if (minimum != NULL) + *minimum = 0; } result = ISC_R_SUCCESS; @@ -4543,20 +4682,21 @@ find_zone_keys(dns_zone_t *zone, dns_db_t *db, dns_dbversion_t *ver, } static isc_result_t -offline(dns_db_t *db, dns_dbversion_t *ver, dns_diff_t *diff, dns_name_t *name, - dns_ttl_t ttl, dns_rdata_t *rdata) +offline(dns_db_t *db, dns_dbversion_t *ver, zonediff_t *zonediff, + dns_name_t *name, dns_ttl_t ttl, dns_rdata_t *rdata) { isc_result_t result; if ((rdata->flags & DNS_RDATA_OFFLINE) != 0) return (ISC_R_SUCCESS); - result = update_one_rr(db, ver, diff, DNS_DIFFOP_DELRESIGN, + result = update_one_rr(db, ver, zonediff->diff, DNS_DIFFOP_DELRESIGN, name, ttl, rdata); if (result != ISC_R_SUCCESS) return (result); rdata->flags |= DNS_RDATA_OFFLINE; - result = update_one_rr(db, ver, diff, DNS_DIFFOP_ADDRESIGN, + result = update_one_rr(db, ver, zonediff->diff, DNS_DIFFOP_ADDRESIGN, name, ttl, rdata); + zonediff->offline = ISC_TRUE; return (result); } @@ -4631,7 +4771,7 @@ delsig_ok(dns_rdata_rrsig_t *rrsig_ptr, dst_key_t **keys, unsigned int nkeys) { */ static isc_result_t del_sigs(dns_zone_t *zone, dns_db_t *db, dns_dbversion_t *ver, dns_name_t *name, - dns_rdatatype_t type, dns_diff_t *diff, dst_key_t **keys, + dns_rdatatype_t type, zonediff_t *zonediff, dst_key_t **keys, unsigned int nkeys, isc_stdtime_t now, isc_boolean_t incremental) { isc_result_t result; @@ -4677,7 +4817,7 @@ del_sigs(dns_zone_t *zone, dns_db_t *db, dns_dbversion_t *ver, dns_name_t *name, if (type != dns_rdatatype_dnskey) { if (delsig_ok(&rrsig, keys, nkeys)) { - result = update_one_rr(db, ver, diff, + result = update_one_rr(db, ver, zonediff->diff, DNS_DIFFOP_DELRESIGN, name, rdataset.ttl, &rdata); if (incremental) @@ -4695,8 +4835,9 @@ del_sigs(dns_zone_t *zone, dns_db_t *db, dns_dbversion_t *ver, dns_name_t *name, * for the private part. */ if (incremental) { - result = offline(db, ver, diff, name, - rdataset.ttl, &rdata); + result = offline(db, ver, zonediff, + name, rdataset.ttl, + &rdata); changed = ISC_TRUE; if (result != ISC_R_SUCCESS) break; @@ -4756,11 +4897,12 @@ del_sigs(dns_zone_t *zone, dns_db_t *db, dns_dbversion_t *ver, dns_name_t *name, warn = maybe; if (warn == 0 || warn > timeexpire) warn = timeexpire; - result = offline(db, ver, diff, name, - rdataset.ttl, &rdata); + result = offline(db, ver, zonediff, + name, rdataset.ttl, + &rdata); break; } - result = update_one_rr(db, ver, diff, + result = update_one_rr(db, ver, zonediff->diff, DNS_DIFFOP_DELRESIGN, name, rdataset.ttl, &rdata); @@ -4773,7 +4915,7 @@ del_sigs(dns_zone_t *zone, dns_db_t *db, dns_dbversion_t *ver, dns_name_t *name, * delete the RRSIG. */ if (!found) - result = update_one_rr(db, ver, diff, + result = update_one_rr(db, ver, zonediff->diff, DNS_DIFFOP_DELRESIGN, name, rdataset.ttl, &rdata); if (result != ISC_R_SUCCESS) @@ -4903,9 +5045,11 @@ add_sigs(dns_db_t *db, dns_dbversion_t *ver, dns_name_t *name, static void zone_resigninc(dns_zone_t *zone) { + const char *me = "zone_resigninc"; dns_db_t *db = NULL; dns_dbversion_t *version = NULL; - dns_diff_t sig_diff; + dns_diff_t _sig_diff; + zonediff_t zonediff; dns_fixedname_t fixed; dns_name_t *name; dns_rdataset_t rdataset; @@ -4919,10 +5063,13 @@ zone_resigninc(dns_zone_t *zone) { unsigned int nkeys = 0; unsigned int resign; + ENTER; + dns_rdataset_init(&rdataset); dns_fixedname_init(&fixed); - dns_diff_init(zone->mctx, &sig_diff); - sig_diff.resign = zone->sigresigninginterval; + dns_diff_init(zone->mctx, &_sig_diff); + _sig_diff.resign = zone->sigresigninginterval; + zonediff_init(&zonediff, &_sig_diff); /* * Updates are disabled. Pause for 5 minutes. @@ -4992,7 +5139,7 @@ zone_resigninc(dns_zone_t *zone) { resign > stop) break; - result = del_sigs(zone, db, version, name, covers, &sig_diff, + result = del_sigs(zone, db, version, name, covers, &zonediff, zone_keys, nkeys, now, ISC_TRUE); if (result != ISC_R_SUCCESS) { dns_zone_log(zone, ISC_LOG_ERROR, @@ -5001,7 +5148,7 @@ zone_resigninc(dns_zone_t *zone) { break; } - result = add_sigs(db, version, name, covers, &sig_diff, + result = add_sigs(db, version, name, covers, zonediff.diff, zone_keys, nkeys, zone->mctx, inception, expire, check_ksk, keyset_kskonly); if (result != ISC_R_SUCCESS) { @@ -5026,7 +5173,7 @@ zone_resigninc(dns_zone_t *zone) { goto failure; result = del_sigs(zone, db, version, &zone->origin, dns_rdatatype_soa, - &sig_diff, zone_keys, nkeys, now, ISC_TRUE); + &zonediff, zone_keys, nkeys, now, ISC_TRUE); if (result != ISC_R_SUCCESS) { dns_zone_log(zone, ISC_LOG_ERROR, "zone_resigninc:del_sigs -> %s", @@ -5037,11 +5184,17 @@ zone_resigninc(dns_zone_t *zone) { /* * Did we change anything in the zone? */ - if (ISC_LIST_EMPTY(sig_diff.tuples)) + if (ISC_LIST_EMPTY(zonediff.diff->tuples)) { + /* + * Commit the changes if any key has been marked as offline. + */ + if (zonediff.offline) + dns_db_closeversion(db, &version, ISC_TRUE); goto failure; + } /* Increment SOA serial if we have made changes */ - result = increment_soa_serial(db, version, &sig_diff, zone->mctx); + result = increment_soa_serial(db, version, zonediff.diff, zone->mctx); if (result != ISC_R_SUCCESS) { dns_zone_log(zone, ISC_LOG_ERROR, "zone_resigninc:increment_soa_serial -> %s", @@ -5054,8 +5207,8 @@ zone_resigninc(dns_zone_t *zone) { * termination is sensible. */ result = add_sigs(db, version, &zone->origin, dns_rdatatype_soa, - &sig_diff, zone_keys, nkeys, zone->mctx, inception, - soaexpire, check_ksk, keyset_kskonly); + zonediff.diff, zone_keys, nkeys, zone->mctx, + inception, soaexpire, check_ksk, keyset_kskonly); if (result != ISC_R_SUCCESS) { dns_zone_log(zone, ISC_LOG_ERROR, "zone_resigninc:add_sigs -> %s", @@ -5064,13 +5217,13 @@ zone_resigninc(dns_zone_t *zone) { } /* Write changes to journal file. */ - CHECK(zone_journal(zone, &sig_diff, "zone_resigninc")); + CHECK(zone_journal(zone, zonediff.diff, "zone_resigninc")); /* Everything has succeeded. Commit the changes. */ dns_db_closeversion(db, &version, ISC_TRUE); failure: - dns_diff_clear(&sig_diff); + dns_diff_clear(&_sig_diff); for (i = 0; i < nkeys; i++) dst_key_free(&zone_keys[i]); if (version != NULL) { @@ -5740,7 +5893,7 @@ update_sigs(dns_diff_t *diff, dns_db_t *db, dns_dbversion_t *version, dst_key_t *zone_keys[], unsigned int nkeys, dns_zone_t *zone, isc_stdtime_t inception, isc_stdtime_t expire, isc_stdtime_t now, isc_boolean_t check_ksk, isc_boolean_t keyset_kskonly, - dns_diff_t *sig_diff) + zonediff_t *zonediff) { dns_difftuple_t *tuple; isc_result_t result; @@ -5749,7 +5902,7 @@ update_sigs(dns_diff_t *diff, dns_db_t *db, dns_dbversion_t *version, tuple != NULL; tuple = ISC_LIST_HEAD(diff->tuples)) { result = del_sigs(zone, db, version, &tuple->name, - tuple->rdata.type, sig_diff, + tuple->rdata.type, zonediff, zone_keys, nkeys, now, ISC_FALSE); if (result != ISC_R_SUCCESS) { dns_zone_log(zone, ISC_LOG_ERROR, @@ -5758,7 +5911,7 @@ update_sigs(dns_diff_t *diff, dns_db_t *db, dns_dbversion_t *version, return (result); } result = add_sigs(db, version, &tuple->name, - tuple->rdata.type, sig_diff, + tuple->rdata.type, zonediff->diff, zone_keys, nkeys, zone->mctx, inception, expire, check_ksk, keyset_kskonly); if (result != ISC_R_SUCCESS) { @@ -5775,7 +5928,7 @@ update_sigs(dns_diff_t *diff, dns_db_t *db, dns_dbversion_t *version, !dns_name_equal(&tuple->name, &next->name))) next = ISC_LIST_NEXT(next, link); ISC_LIST_UNLINK(diff->tuples, tuple, link); - dns_diff_appendminimal(sig_diff, &tuple); + dns_diff_appendminimal(zonediff->diff, &tuple); INSIST(tuple == NULL); tuple = next; } while (tuple != NULL); @@ -5789,13 +5942,15 @@ update_sigs(dns_diff_t *diff, dns_db_t *db, dns_dbversion_t *version, */ static void zone_nsec3chain(dns_zone_t *zone) { + const char *me = "zone_nsec3chain"; dns_db_t *db = NULL; dns_dbnode_t *node = NULL; dns_dbversion_t *version = NULL; - dns_diff_t sig_diff; + dns_diff_t _sig_diff; dns_diff_t nsec_diff; dns_diff_t nsec3_diff; dns_diff_t param_diff; + zonediff_t zonediff; dns_fixedname_t fixed; dns_fixedname_t nextfixed; dns_name_t *name, *nextname; @@ -5821,6 +5976,8 @@ zone_nsec3chain(dns_zone_t *zone) { isc_boolean_t updatensec = ISC_FALSE; dns_rdatatype_t privatetype = zone->privatetype; + ENTER; + dns_rdataset_init(&rdataset); dns_fixedname_init(&fixed); name = dns_fixedname_name(&fixed); @@ -5829,8 +5986,9 @@ zone_nsec3chain(dns_zone_t *zone) { dns_diff_init(zone->mctx, ¶m_diff); dns_diff_init(zone->mctx, &nsec3_diff); dns_diff_init(zone->mctx, &nsec_diff); - dns_diff_init(zone->mctx, &sig_diff); - sig_diff.resign = zone->sigresigninginterval; + dns_diff_init(zone->mctx, &_sig_diff); + _sig_diff.resign = zone->sigresigninginterval; + zonediff_init(&zonediff, &_sig_diff); ISC_LIST_INIT(cleanup); /* @@ -6028,6 +6186,7 @@ zone_nsec3chain(dns_zone_t *zone) { result = dns_dbiterator_next(nsec3chain->dbiterator); if (result == ISC_R_NOMORE && nsec3chain->delete_nsec) { + dns_dbiterator_pause(nsec3chain->dbiterator); CHECK(fixup_nsec3param(db, version, nsec3chain, ISC_FALSE, privatetype, ¶m_diff)); @@ -6325,6 +6484,7 @@ zone_nsec3chain(dns_zone_t *zone) { if (rebuild_nsec) { if (nsec3chain != NULL) dns_dbiterator_pause(nsec3chain->dbiterator); + result = updatesecure(db, version, &zone->origin, zone->minimum, ISC_TRUE, &nsec_diff); @@ -6336,7 +6496,11 @@ zone_nsec3chain(dns_zone_t *zone) { goto failure; } } + if (rebuild_nsec3) { + if (nsec3chain != NULL) + dns_dbiterator_pause(nsec3chain->dbiterator); + result = dns_nsec3_addnsec3s(db, version, dns_db_origin(db), zone->minimum, ISC_FALSE, @@ -6351,12 +6515,17 @@ zone_nsec3chain(dns_zone_t *zone) { } } + if (nsec3chain != NULL) + dns_dbiterator_pause(nsec3chain->dbiterator); + /* * Add / update signatures for the NSEC3 records. */ + if (nsec3chain != NULL) + dns_dbiterator_pause(nsec3chain->dbiterator); result = update_sigs(&nsec3_diff, db, version, zone_keys, nkeys, zone, inception, expire, now, - check_ksk, keyset_kskonly, &sig_diff); + check_ksk, keyset_kskonly, &zonediff); if (result != ISC_R_SUCCESS) { dns_zone_log(zone, ISC_LOG_ERROR, "zone_nsec3chain:" "update_sigs -> %s", dns_result_totext(result)); @@ -6369,7 +6538,7 @@ zone_nsec3chain(dns_zone_t *zone) { */ result = update_sigs(¶m_diff, db, version, zone_keys, nkeys, zone, inception, expire, now, - check_ksk, keyset_kskonly, &sig_diff); + check_ksk, keyset_kskonly, &zonediff); if (result != ISC_R_SUCCESS) { dns_zone_log(zone, ISC_LOG_ERROR, "zone_nsec3chain:" "update_sigs -> %s", dns_result_totext(result)); @@ -6377,8 +6546,6 @@ zone_nsec3chain(dns_zone_t *zone) { } if (updatensec) { - if (nsec3chain != NULL) - dns_dbiterator_pause(nsec3chain->dbiterator); result = updatesecure(db, version, &zone->origin, zone->minimum, ISC_FALSE, &nsec_diff); if (result != ISC_R_SUCCESS) { @@ -6391,7 +6558,7 @@ zone_nsec3chain(dns_zone_t *zone) { result = update_sigs(&nsec_diff, db, version, zone_keys, nkeys, zone, inception, expire, now, - check_ksk, keyset_kskonly, &sig_diff); + check_ksk, keyset_kskonly, &zonediff); if (result != ISC_R_SUCCESS) { dns_zone_log(zone, ISC_LOG_ERROR, "zone_nsec3chain:" "update_sigs -> %s", dns_result_totext(result)); @@ -6402,18 +6569,23 @@ zone_nsec3chain(dns_zone_t *zone) { * If we made no effective changes to the zone then we can just * cleanup otherwise we need to increment the serial. */ - if (ISC_LIST_HEAD(sig_diff.tuples) == NULL) + if (ISC_LIST_EMPTY(zonediff.diff->tuples)) { + /* + * No need to call dns_db_closeversion() here as it is + * called with commit = ISC_TRUE below. + */ goto done; + } result = del_sigs(zone, db, version, &zone->origin, dns_rdatatype_soa, - &sig_diff, zone_keys, nkeys, now, ISC_FALSE); + &zonediff, zone_keys, nkeys, now, ISC_FALSE); if (result != ISC_R_SUCCESS) { dns_zone_log(zone, ISC_LOG_ERROR, "zone_nsec3chain:" "del_sigs -> %s", dns_result_totext(result)); goto failure; } - result = increment_soa_serial(db, version, &sig_diff, zone->mctx); + result = increment_soa_serial(db, version, zonediff.diff, zone->mctx); if (result != ISC_R_SUCCESS) { dns_zone_log(zone, ISC_LOG_ERROR, "zone_nsec3chain:" "increment_soa_serial -> %s", @@ -6422,8 +6594,8 @@ zone_nsec3chain(dns_zone_t *zone) { } result = add_sigs(db, version, &zone->origin, dns_rdatatype_soa, - &sig_diff, zone_keys, nkeys, zone->mctx, inception, - soaexpire, check_ksk, keyset_kskonly); + zonediff.diff, zone_keys, nkeys, zone->mctx, + inception, soaexpire, check_ksk, keyset_kskonly); if (result != ISC_R_SUCCESS) { dns_zone_log(zone, ISC_LOG_ERROR, "zone_nsec3chain:" "add_sigs -> %s", dns_result_totext(result)); @@ -6431,7 +6603,7 @@ zone_nsec3chain(dns_zone_t *zone) { } /* Write changes to journal file. */ - CHECK(zone_journal(zone, &sig_diff, "zone_nsec3chain")); + CHECK(zone_journal(zone, zonediff.diff, "zone_nsec3chain")); LOCK_ZONE(zone); zone_needdump(zone, DNS_DUMP_DELAY); @@ -6451,6 +6623,7 @@ zone_nsec3chain(dns_zone_t *zone) { /* * Everything has succeeded. Commit the changes. + * Unconditionally commit as zonediff.offline not checked above. */ dns_db_closeversion(db, &version, ISC_TRUE); @@ -6520,7 +6693,7 @@ zone_nsec3chain(dns_zone_t *zone) { dns_diff_clear(¶m_diff); dns_diff_clear(&nsec3_diff); dns_diff_clear(&nsec_diff); - dns_diff_clear(&sig_diff); + dns_diff_clear(&_sig_diff); if (iterator != NULL) dns_rdatasetiter_destroy(&iterator); @@ -6622,11 +6795,13 @@ del_sig(dns_db_t *db, dns_dbversion_t *version, dns_name_t *name, */ static void zone_sign(dns_zone_t *zone) { + const char *me = "zone_sign"; dns_db_t *db = NULL; dns_dbnode_t *node = NULL; dns_dbversion_t *version = NULL; - dns_diff_t sig_diff; + dns_diff_t _sig_diff; dns_diff_t post_diff; + zonediff_t zonediff; dns_fixedname_t fixed; dns_fixedname_t nextfixed; dns_name_t *name, *nextname; @@ -6648,14 +6823,17 @@ zone_sign(dns_zone_t *zone) { unsigned int nkeys = 0; isc_uint32_t nodes; + ENTER; + dns_rdataset_init(&rdataset); dns_fixedname_init(&fixed); name = dns_fixedname_name(&fixed); dns_fixedname_init(&nextfixed); nextname = dns_fixedname_name(&nextfixed); - dns_diff_init(zone->mctx, &sig_diff); - sig_diff.resign = zone->sigresigninginterval; + dns_diff_init(zone->mctx, &_sig_diff); + _sig_diff.resign = zone->sigresigninginterval; dns_diff_init(zone->mctx, &post_diff); + zonediff_init(&zonediff, &_sig_diff); ISC_LIST_INIT(cleanup); /* @@ -6769,7 +6947,7 @@ zone_sign(dns_zone_t *zone) { dns_dbiterator_pause(signing->dbiterator); CHECK(del_sig(db, version, name, node, nkeys, signing->algorithm, signing->keyid, - &sig_diff)); + zonediff.diff)); } /* @@ -6864,7 +7042,7 @@ zone_sign(dns_zone_t *zone) { build_nsec, zone_keys[i], inception, expire, zone->minimum, is_ksk, ISC_TF(both && keyset_kskonly), - &delegation, &sig_diff, + &delegation, zonediff.diff, &signatures, zone->mctx)); /* * If we are adding we are done. Look for other keys @@ -6946,7 +7124,7 @@ zone_sign(dns_zone_t *zone) { if (ISC_LIST_HEAD(post_diff.tuples) != NULL) { result = update_sigs(&post_diff, db, version, zone_keys, nkeys, zone, inception, expire, now, - check_ksk, keyset_kskonly, &sig_diff); + check_ksk, keyset_kskonly, &zonediff); if (result != ISC_R_SUCCESS) { dns_zone_log(zone, ISC_LOG_ERROR, "zone_sign:" "update_sigs -> %s", @@ -6958,7 +7136,9 @@ zone_sign(dns_zone_t *zone) { /* * Have we changed anything? */ - if (ISC_LIST_HEAD(sig_diff.tuples) == NULL) { + if (ISC_LIST_EMPTY(zonediff.diff->tuples)) { + if (zonediff.offline) + commit = ISC_TRUE; result = ISC_R_SUCCESS; goto pauseall; } @@ -6966,7 +7146,7 @@ zone_sign(dns_zone_t *zone) { commit = ISC_TRUE; result = del_sigs(zone, db, version, &zone->origin, dns_rdatatype_soa, - &sig_diff, zone_keys, nkeys, now, ISC_FALSE); + &zonediff, zone_keys, nkeys, now, ISC_FALSE); if (result != ISC_R_SUCCESS) { dns_zone_log(zone, ISC_LOG_ERROR, "zone_sign:del_sigs -> %s", @@ -6974,7 +7154,7 @@ zone_sign(dns_zone_t *zone) { goto failure; } - result = increment_soa_serial(db, version, &sig_diff, zone->mctx); + result = increment_soa_serial(db, version, zonediff.diff, zone->mctx); if (result != ISC_R_SUCCESS) { dns_zone_log(zone, ISC_LOG_ERROR, "zone_sign:increment_soa_serial -> %s", @@ -6987,8 +7167,8 @@ zone_sign(dns_zone_t *zone) { * termination is sensible. */ result = add_sigs(db, version, &zone->origin, dns_rdatatype_soa, - &sig_diff, zone_keys, nkeys, zone->mctx, inception, - soaexpire, check_ksk, keyset_kskonly); + zonediff.diff, zone_keys, nkeys, zone->mctx, + inception, soaexpire, check_ksk, keyset_kskonly); if (result != ISC_R_SUCCESS) { dns_zone_log(zone, ISC_LOG_ERROR, "zone_sign:add_sigs -> %s", @@ -6999,7 +7179,7 @@ zone_sign(dns_zone_t *zone) { /* * Write changes to journal file. */ - CHECK(zone_journal(zone, &sig_diff, "zone_sign")); + CHECK(zone_journal(zone, zonediff.diff, "zone_sign")); pauseall: /* @@ -7059,7 +7239,7 @@ zone_sign(dns_zone_t *zone) { signing = ISC_LIST_NEXT(signing, link)) dns_dbiterator_pause(signing->dbiterator); - dns_diff_clear(&sig_diff); + dns_diff_clear(&_sig_diff); for (i = 0; i < nkeys; i++) dst_key_free(&zone_keys[i]); @@ -7090,19 +7270,22 @@ normalize_key(dns_rdata_t *rr, dns_rdata_t *target, dns_rdata_dnskey_t dnskey; dns_rdata_keydata_t keydata; isc_buffer_t buf; + isc_result_t result; dns_rdata_reset(target); isc_buffer_init(&buf, data, size); switch (rr->type) { case dns_rdatatype_dnskey: - dns_rdata_tostruct(rr, &dnskey, NULL); + result = dns_rdata_tostruct(rr, &dnskey, NULL); + RUNTIME_CHECK(result == ISC_R_SUCCESS); dnskey.flags &= ~DNS_KEYFLAG_REVOKE; dns_rdata_fromstruct(target, rr->rdclass, dns_rdatatype_dnskey, &dnskey, &buf); break; case dns_rdatatype_keydata: - dns_rdata_tostruct(rr, &keydata, NULL); + result = dns_rdata_tostruct(rr, &keydata, NULL); + RUNTIME_CHECK(result == ISC_R_SUCCESS); dns_keydata_todnskey(&keydata, &dnskey, NULL); dns_rdata_fromstruct(target, rr->rdclass, dns_rdatatype_dnskey, &dnskey, &buf); @@ -7509,7 +7692,8 @@ keyfetch_done(isc_task_t *task, isc_event_t *event) { result = dns_rdataset_next(&kfetch->keydataset)) { dns_rdata_reset(&keydatarr); dns_rdataset_current(&kfetch->keydataset, &keydatarr); - dns_rdata_tostruct(&keydatarr, &keydata, NULL); + result = dns_rdata_tostruct(&keydatarr, &keydata, NULL); + RUNTIME_CHECK(result == ISC_R_SUCCESS); /* * If any keydata record has a nonzero add holddown, then @@ -7599,7 +7783,8 @@ keyfetch_done(isc_task_t *task, isc_event_t *event) { dns_rdata_reset(&dnskeyrr); dns_rdataset_current(&kfetch->dnskeyset, &dnskeyrr); - dns_rdata_tostruct(&dnskeyrr, &dnskey, NULL); + result = dns_rdata_tostruct(&dnskeyrr, &dnskey, NULL); + RUNTIME_CHECK(result == ISC_R_SUCCESS); /* Skip ZSK's */ if (!ISC_TF(dnskey.flags & DNS_KEYFLAG_KSK)) @@ -7610,7 +7795,8 @@ keyfetch_done(isc_task_t *task, isc_event_t *event) { if (matchkey(&kfetch->keydataset, &dnskeyrr)) { dns_rdata_reset(&keydatarr); dns_rdataset_current(&kfetch->keydataset, &keydatarr); - dns_rdata_tostruct(&keydatarr, &keydata, NULL); + result = dns_rdata_tostruct(&keydatarr, &keydata, NULL); + RUNTIME_CHECK(result == ISC_R_SUCCESS); if (revoked && revocable(kfetch, &keydata)) { if (keydata.addhd > now) { @@ -7710,7 +7896,8 @@ keyfetch_done(isc_task_t *task, isc_event_t *event) { &keydatarr)); } else if (newkey) { /* Convert DNSKEY to KEYDATA */ - dns_rdata_tostruct(&dnskeyrr, &dnskey, NULL); + result = dns_rdata_tostruct(&dnskeyrr, &dnskey, NULL); + RUNTIME_CHECK(result == ISC_R_SUCCESS); dns_keydata_fromdnskey(&keydata, &dnskey, 0, 0, 0, NULL); keydata.addhd = initializing ? now : now + MONTH; @@ -7729,7 +7916,8 @@ keyfetch_done(isc_task_t *task, isc_event_t *event) { if (trustkey) { /* Trust this key. */ - dns_rdata_tostruct(&dnskeyrr, &dnskey, NULL); + result = dns_rdata_tostruct(&dnskeyrr, &dnskey, NULL); + RUNTIME_CHECK(result == ISC_R_SUCCESS); trust_key(zone, keyname, &dnskey, mctx); } @@ -8020,6 +8208,14 @@ zone_maintenance(dns_zone_t *zone) { } /* + * Slaves send notifies before backing up to disk, masters after. + */ + if (zone->type == dns_zone_slave && + DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NEEDNOTIFY) && + isc_time_compare(&now, &zone->notifytime) >= 0) + zone_notify(zone, &now); + + /* * Do we need to consolidate the backing store? */ switch (zone->type) { @@ -8049,14 +8245,28 @@ zone_maintenance(dns_zone_t *zone) { } /* + * Master/redirect zones send notifies now, if needed + */ + switch (zone->type) { + case dns_zone_master: + if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NEEDNOTIFY) && + isc_time_compare(&now, &zone->notifytime) >= 0) + zone_notify(zone, &now); + default: + break; + } + + /* * Do we need to refresh keys? */ switch (zone->type) { case dns_zone_key: - if (isc_time_compare(&now, &zone->refreshkeytime) >= 0 && - DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADED) && - !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_REFRESHING)) - zone_refreshkeys(zone); + if (isc_time_compare(&now, &zone->refreshkeytime) >= 0) { + if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADED) && + !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_REFRESHING)) { + zone_refreshkeys(zone); + } + } break; case dns_zone_master: if (!isc_time_isepoch(&zone->refreshkeytime) && @@ -8070,12 +8280,6 @@ zone_maintenance(dns_zone_t *zone) { case dns_zone_master: case dns_zone_slave: /* - * Do we need to send out notify messages? - */ - if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NEEDNOTIFY) && - isc_time_compare(&now, &zone->notifytime) >= 0) - zone_notify(zone, &now); - /* * Do we need to sign/resign some RRsets? */ if (!isc_time_isepoch(&zone->signingtime) && @@ -8088,7 +8292,7 @@ zone_maintenance(dns_zone_t *zone) { isc_time_compare(&now, &zone->nsec3chaintime) >= 0) zone_nsec3chain(zone); /* - * Do we need to issue a key expiry warning. + * Do we need to issue a key expiry warning? */ if (!isc_time_isepoch(&zone->keywarntime) && isc_time_compare(&now, &zone->keywarntime) >= 0) @@ -8237,6 +8441,7 @@ dns_zone_dump(dns_zone_t *zone) { static void zone_needdump(dns_zone_t *zone, unsigned int delay) { + const char me[] = "zone_needdump"; isc_time_t dumptime; isc_time_t now; @@ -8246,6 +8451,7 @@ zone_needdump(dns_zone_t *zone, unsigned int delay) { REQUIRE(DNS_ZONE_VALID(zone)); REQUIRE(LOCKED_ZONE(zone)); + ENTER; /* * Do we have a place to dump to and are we loaded? @@ -8898,9 +9104,9 @@ notify_send_toaddr(isc_task_t *task, isc_event_t *event) { dns_message_destroy(&message); cleanup: UNLOCK_ZONE(notify->zone); + isc_event_free(&event); if (result != ISC_R_SUCCESS) notify_destroy(notify, ISC_FALSE); - isc_event_free(&event); } static void @@ -9247,7 +9453,7 @@ stub_callback(isc_task_t *task, isc_event_t *event) { isc_time_t now; isc_boolean_t exiting = ISC_FALSE; isc_interval_t i; - unsigned int j; + unsigned int j, soacount; stub = revent->ev_arg; INSIST(DNS_STUB_VALID(stub)); @@ -9390,9 +9596,9 @@ stub_callback(isc_task_t *task, isc_event_t *event) { ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_write); if (zone->db == NULL) zone_attachdb(zone, stub->db); - result = zone_get_from_db(zone, zone->db, NULL, NULL, NULL, &refresh, - &retry, &expire, NULL, NULL); - if (result == ISC_R_SUCCESS) { + result = zone_get_from_db(zone, zone->db, NULL, &soacount, NULL, + &refresh, &retry, &expire, NULL, NULL); + if (result == ISC_R_SUCCESS && soacount > 0U) { zone->refresh = RANGE(refresh, zone->minrefresh, zone->maxrefresh); zone->retry = RANGE(retry, zone->minretry, zone->maxretry); @@ -9728,10 +9934,12 @@ refresh_callback(isc_task_t *task, isc_event_t *event) { serial = soa.serial; if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADED)) { - result = zone_get_from_db(zone, zone->db, NULL, NULL, + unsigned int soacount; + result = zone_get_from_db(zone, zone->db, NULL, &soacount, &oldserial, NULL, NULL, NULL, NULL, NULL); RUNTIME_CHECK(result == ISC_R_SUCCESS); + RUNTIME_CHECK(soacount > 0U); zone_debuglog(zone, me, 1, "serial: new %u, old %u", serial, oldserial); } else @@ -10953,6 +11161,7 @@ dns_zone_notifyreceive(dns_zone_t *zone, isc_sockaddr_t *from, result = dns_rdataset_first(rdataset); if (result == ISC_R_SUCCESS) { isc_uint32_t serial = 0, oldserial; + unsigned int soacount; dns_rdataset_current(rdataset, &rdata); result = dns_rdata_tostruct(&rdata, &soa, NULL); @@ -10962,10 +11171,11 @@ dns_zone_notifyreceive(dns_zone_t *zone, isc_sockaddr_t *from, * The following should safely be performed without DB * lock and succeed in this context. */ - result = zone_get_from_db(zone, zone->db, NULL, NULL, - &oldserial, NULL, NULL, NULL, - NULL, NULL); + result = zone_get_from_db(zone, zone->db, NULL, + &soacount, &oldserial, NULL, + NULL, NULL, NULL, NULL); RUNTIME_CHECK(result == ISC_R_SUCCESS); + RUNTIME_CHECK(soacount > 0U); if (isc_serial_le(serial, oldserial)) { dns_zone_log(zone, ISC_LOG_INFO, @@ -11652,6 +11862,7 @@ zone_replacedb(dns_zone_t *zone, dns_db_t *db, isc_boolean_t dump) { DNS_ZONE_OPTION(zone, DNS_ZONEOPT_IXFRFROMDIFFS) && !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_FORCEXFER)) { isc_uint32_t serial, oldserial; + unsigned int soacount; dns_zone_log(zone, ISC_LOG_DEBUG(3), "generating diffs"); @@ -11666,10 +11877,11 @@ zone_replacedb(dns_zone_t *zone, dns_db_t *db, isc_boolean_t dump) { /* * This is checked in zone_postload() for master zones. */ - result = zone_get_from_db(zone, zone->db, NULL, NULL, + result = zone_get_from_db(zone, zone->db, NULL, &soacount, &oldserial, NULL, NULL, NULL, NULL, NULL); RUNTIME_CHECK(result == ISC_R_SUCCESS); + RUNTIME_CHECK(soacount > 0U); if (zone->type == dns_zone_slave && !isc_serial_gt(serial, oldserial)) { isc_uint32_t serialmin, serialmax; @@ -11916,6 +12128,8 @@ zone_xfrdone(dns_zone_t *zone, isc_result_t result) { * won't hurt with an AXFR. */ if (zone->masterfile != NULL || zone->journal != NULL) { + unsigned int delay = DNS_DUMP_DELAY; + result = ISC_R_FAILURE; if (zone->journal != NULL) result = isc_file_settime(zone->journal, &now); @@ -11923,14 +12137,16 @@ zone_xfrdone(dns_zone_t *zone, isc_result_t result) { zone->masterfile != NULL) result = isc_file_settime(zone->masterfile, &now); - /* Someone removed the file from underneath us! */ - if (result == ISC_R_FILENOTFOUND && - zone->masterfile != NULL) { - unsigned int delay = DNS_DUMP_DELAY; - if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NODELAY)) - delay = 0; + + if ((DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NODELAY) != 0) || + result == ISC_R_FILENOTFOUND) + delay = 0; + + if ((result == ISC_R_SUCCESS || + result == ISC_R_FILENOTFOUND) && + zone->masterfile != NULL) zone_needdump(zone, delay); - } else if (result != ISC_R_SUCCESS) + else if (result != ISC_R_SUCCESS) dns_zone_log(zone, ISC_LOG_ERROR, "transfer: could not set file " "modification time of '%s': %s", @@ -13323,6 +13539,8 @@ dns_zonemgr_unreachabledel(dns_zonemgr_t *zmgr, isc_sockaddr_t *remote, for (i = 0; i < UNREACH_CHACHE_SIZE; i++) { if (isc_sockaddr_equal(&zmgr->unreachable[i].remote, remote) && isc_sockaddr_equal(&zmgr->unreachable[i].local, local)) { + if (zmgr->unreachable[i].expire == 0) + break; result = isc_rwlock_tryupgrade(&zmgr->urlock); if (result == ISC_R_SUCCESS) { locktype = isc_rwlocktype_write; @@ -13994,7 +14212,7 @@ add_signing_records(dns_db_t *db, dns_rdatatype_t privatetype, static isc_result_t sign_apex(dns_zone_t *zone, dns_db_t *db, dns_dbversion_t *ver, - dns_diff_t *diff, dns_diff_t *sig_diff) + dns_diff_t *diff, zonediff_t *zonediff) { isc_result_t result; isc_stdtime_t now, inception, soaexpire; @@ -14034,7 +14252,7 @@ sign_apex(dns_zone_t *zone, dns_db_t *db, dns_dbversion_t *ver, if (tuple == NULL) { result = del_sigs(zone, db, ver, &zone->origin, - dns_rdatatype_dnskey, sig_diff, + dns_rdatatype_dnskey, zonediff, zone_keys, nkeys, now, ISC_FALSE); if (result != ISC_R_SUCCESS) { dns_zone_log(zone, ISC_LOG_ERROR, @@ -14043,7 +14261,7 @@ sign_apex(dns_zone_t *zone, dns_db_t *db, dns_dbversion_t *ver, goto failure; } result = add_sigs(db, ver, &zone->origin, dns_rdatatype_dnskey, - sig_diff, zone_keys, nkeys, zone->mctx, + zonediff->diff, zone_keys, nkeys, zone->mctx, inception, soaexpire, check_ksk, keyset_kskonly); if (result != ISC_R_SUCCESS) { @@ -14056,7 +14274,7 @@ sign_apex(dns_zone_t *zone, dns_db_t *db, dns_dbversion_t *ver, result = update_sigs(diff, db, ver, zone_keys, nkeys, zone, inception, soaexpire, now, check_ksk, - keyset_kskonly, sig_diff); + keyset_kskonly, zonediff); if (result != ISC_R_SUCCESS) { dns_zone_log(zone, ISC_LOG_ERROR, @@ -14209,7 +14427,8 @@ zone_rekey(dns_zone_t *zone) { dns_rdataset_t soaset, soasigs, keyset, keysigs; dns_dnsseckeylist_t dnskeys, keys, rmkeys; dns_dnsseckey_t *key; - dns_diff_t diff, sig_diff; + dns_diff_t diff, _sig_diff; + zonediff_t zonediff; isc_boolean_t commit = ISC_FALSE, newactive = ISC_FALSE; isc_boolean_t newalg = ISC_FALSE; isc_boolean_t fullsign; @@ -14233,8 +14452,9 @@ zone_rekey(dns_zone_t *zone) { dir = dns_zone_getkeydirectory(zone); mctx = zone->mctx; dns_diff_init(mctx, &diff); - dns_diff_init(mctx, &sig_diff); - sig_diff.resign = zone->sigresigninginterval; + dns_diff_init(mctx, &_sig_diff); + _sig_diff.resign = zone->sigresigninginterval; + zonediff_init(&zonediff, &_sig_diff); CHECK(dns_zone_getdb(zone, &db)); CHECK(dns_db_newversion(db, &ver)); @@ -14334,8 +14554,8 @@ zone_rekey(dns_zone_t *zone) { ISC_TF(newalg || fullsign))); CHECK(increment_soa_serial(db, ver, &diff, mctx)); CHECK(add_chains(zone, db, ver, &diff)); - CHECK(sign_apex(zone, db, ver, &diff, &sig_diff)); - CHECK(zone_journal(zone, &sig_diff, "zone_rekey")); + CHECK(sign_apex(zone, db, ver, &diff, &zonediff)); + CHECK(zone_journal(zone, zonediff.diff, "zone_rekey")); commit = ISC_TRUE; } } @@ -14425,7 +14645,7 @@ zone_rekey(dns_zone_t *zone) { * Cause the zone to add/delete NSEC3 chains for the * deferred NSEC3PARAM changes. */ - for (tuple = ISC_LIST_HEAD(sig_diff.tuples); + for (tuple = ISC_LIST_HEAD(zonediff.diff->tuples); tuple != NULL; tuple = ISC_LIST_NEXT(tuple, link)) { unsigned char buf[DNS_NSEC3PARAM_BUFFERSIZE]; @@ -14500,7 +14720,7 @@ zone_rekey(dns_zone_t *zone) { failure: dns_diff_clear(&diff); - dns_diff_clear(&sig_diff); + dns_diff_clear(&_sig_diff); clear_keylist(&dnskeys, mctx); clear_keylist(&keys, mctx); |