summaryrefslogtreecommitdiffstats
path: root/lib/dns/zone.c
diff options
context:
space:
mode:
Diffstat (limited to 'lib/dns/zone.c')
-rw-r--r--lib/dns/zone.c468
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, &param_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,
&param_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(&param_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(&param_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);
OpenPOWER on IntegriCloud