* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: rriterator.h,v 1.2 2009/06/30 02:52:32 each Exp $ */
+/* $Id: rriterator.h,v 1.3 2011/11/01 04:00:45 each Exp $ */
#ifndef DNS_RRITERATOR_H
#define DNS_RRITERATOR_H 1
isc_result_t
dns_rriterator_init(dns_rriterator_t *it, dns_db_t *db,
dns_dbversion_t *ver, isc_stdtime_t now);
+/*%
+ * Initialize an rriterator; sets the cursor to the origin node
+ * of the database.
+ *
+ * Requires:
+ *
+ * \li 'db' is a valid database.
+ *
+ * Returns:
+ *
+ * \li #ISC_R_SUCCESS
+ * \li #ISC_R_NOMEMORY
+ */
isc_result_t
dns_rriterator_first(dns_rriterator_t *it);
+/*%<
+ * Move the rriterator cursor to the first rdata in the database.
+ *
+ * Requires:
+ *\li 'it' is a valid, initialized rriterator
+ *
+ * Returns:
+ *\li #ISC_R_SUCCESS
+ *\li #ISC_R_NOMORE There are no rdata in the set.
+ */
isc_result_t
dns_rriterator_nextrrset(dns_rriterator_t *it);
+/*%<
+ * Move the rriterator cursor to the next rrset in the database,
+ * skipping over any remaining records that have the same rdatatype
+ * as the current one.
+ *
+ * Requires:
+ *\li 'it' is a valid, initialized rriterator
+ *
+ * Returns:
+ *\li #ISC_R_SUCCESS
+ *\li #ISC_R_NOMORE No more rrsets in the database
+ */
isc_result_t
dns_rriterator_next(dns_rriterator_t *it);
+/*%<
+ * Move the rriterator cursor to the next rrset in the database,
+ * skipping over any remaining records that have the same rdatatype
+ * as the current one.
+ *
+ * Requires:
+ *\li 'it' is a valid, initialized rriterator
+ *
+ * Returns:
+ *\li #ISC_R_SUCCESS
+ *\li #ISC_R_NOMORE No more records in the database
+ */
void
dns_rriterator_current(dns_rriterator_t *it, dns_name_t **name,
isc_uint32_t *ttl, dns_rdataset_t **rdataset,
dns_rdata_t **rdata);
+/*%<
+ * Make '*name' refer to the current name. If 'rdataset' is not NULL,
+ * make '*rdataset' refer to the current * rdataset. If '*rdata' is not
+ * NULL, make '*rdata' refer to the current record.
+ *
+ * Requires:
+ *\li '*name' is a valid name object
+ *\li 'rdataset' is NULL or '*rdataset' is NULL
+ *\li 'rdata' is NULL or '*rdata' is NULL
+ *
+ * Ensures:
+ *\li 'rdata' refers to the rdata at the rdata cursor location of
+ *\li 'rdataset'.
+ */
void
dns_rriterator_pause(dns_rriterator_t *it);
+/*%<
+ * Pause rriterator. Frees any locks held by the database iterator.
+ * Callers should use this routine any time they are not going to
+ * execute another rriterator method in the immediate future.
+ *
+ * Requires:
+ *\li 'it' is a valid iterator.
+ *
+ * Ensures:
+ *\li Any database locks being held for efficiency of iterator access are
+ * released.
+ */
void
dns_rriterator_destroy(dns_rriterator_t *it);
+/*%<
+ * Shut down and free resources in rriterator 'it'.
+ *
+ * Requires:
+ *
+ *\li 'it' is a valid iterator.
+ *
+ * Ensures:
+ *
+ *\li All resources used by the rriterator are freed.
+ */
ISC_LANG_ENDDECLS
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: zone.c,v 1.643 2011/10/28 12:27:06 marka Exp $ */
+/* $Id: zone.c,v 1.644 2011/11/01 04:00:44 each Exp $ */
/*! \file */
for (result = dns_rriterator_first(&rrit);
result == ISC_R_SUCCESS;
result = dns_rriterator_nextrrset(&rrit)) {
- dns_rdataset_t *rdataset;
+ dns_rdataset_t *rdataset = NULL;
dns_name_t *rrname = NULL;
isc_uint32_t ttl;
dns_rdata_keydata_t kd;
isc_stdtime_t now;
isc_boolean_t commit = ISC_FALSE;
+ isc_boolean_t fetching = ISC_FALSE, fetch_err = ISC_FALSE;
ENTER;
REQUIRE(zone->db != NULL);
result == ISC_R_SUCCESS;
result = dns_rriterator_nextrrset(&rrit)) {
isc_stdtime_t timer = 0xffffffff;
+ dns_name_t *name = NULL, *kname = NULL;
+ dns_rdataset_t *kdset = NULL;
dns_keyfetch_t *kfetch;
- dns_rdataset_t *kdset;
- dns_name_t *name = NULL;
isc_uint32_t ttl;
dns_rriterator_current(&rrit, &name, &ttl, &kdset, NULL);
- if (!dns_rdataset_isassociated(kdset))
- continue;
-
- if (kdset->type != dns_rdatatype_keydata)
+ if (kdset == NULL || kdset->type != dns_rdatatype_keydata ||
+ !dns_rdataset_isassociated(kdset))
continue;
/*
if (timer > now)
continue;
- zone->refreshkeycount++;
-
kfetch = isc_mem_get(zone->mctx, sizeof(dns_keyfetch_t));
+ if (kfetch == NULL) {
+ fetch_err = ISC_TRUE;
+ goto failure;
+ }
+
+ zone->refreshkeycount++;
kfetch->zone = zone;
zone->irefs++;
INSIST(zone->irefs != 0);
dns_fixedname_init(&kfetch->name);
- dns_name_dup(name, zone->mctx,
- dns_fixedname_name(&kfetch->name));
+ kname = dns_fixedname_name(&kfetch->name);
+ dns_name_dup(name, zone->mctx, kname);
dns_rdataset_init(&kfetch->dnskeyset);
dns_rdataset_init(&kfetch->dnskeysigset);
dns_rdataset_init(&kfetch->keydataset);
dns_db_attach(db, &kfetch->db);
kfetch->fetch = NULL;
- dns_resolver_createfetch(zone->view->resolver,
- dns_fixedname_name(&kfetch->name),
- dns_rdatatype_dnskey,
- NULL, NULL, NULL,
- DNS_FETCHOPT_NOVALIDATE,
- zone->task, keyfetch_done, kfetch,
- &kfetch->dnskeyset,
- &kfetch->dnskeysigset,
- &kfetch->fetch);
+ result = dns_resolver_createfetch(zone->view->resolver,
+ kname, dns_rdatatype_dnskey,
+ NULL, NULL, NULL,
+ DNS_FETCHOPT_NOVALIDATE,
+ zone->task,
+ keyfetch_done, kfetch,
+ &kfetch->dnskeyset,
+ &kfetch->dnskeysigset,
+ &kfetch->fetch);
+ if (result == ISC_R_SUCCESS)
+ fetching = ISC_TRUE;
+ else {
+ zone->refreshkeycount--;
+ zone->irefs--;
+ dns_db_detach(&kfetch->db);
+ dns_rdataset_disassociate(&kfetch->keydataset);
+ dns_name_free(kname, zone->mctx);
+ isc_mem_put(zone->mctx, kfetch, sizeof(dns_keyfetch_t));
+ dns_zone_log(zone, ISC_LOG_WARNING,
+ "Failed to create fetch for "
+ "DNSKEY update");
+ fetch_err = ISC_TRUE;
+ }
}
if (!ISC_LIST_EMPTY(diff.tuples)) {
CHECK(update_soa_serial(db, ver, &diff, zone->mctx,
}
failure:
+ if (fetch_err) {
+ /*
+ * Error during a key fetch; retry in an hour.
+ */
+ isc_time_t timenow, timethen;
+ char timebuf[80];
+
+ TIME_NOW(&timenow);
+ DNS_ZONE_TIME_ADD(&timenow, HOUR, &timethen);
+ zone->refreshkeytime = timethen;
+ zone_settimer(zone, &timenow);
+
+ isc_time_formattimestamp(&zone->refreshkeytime, timebuf, 80);
+ dns_zone_log(zone, ISC_LOG_DEBUG(1), "retry key refresh: %s",
+ timebuf);
+
+ if (!fetching)
+ DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_REFRESHING);
+ }
+
UNLOCK_ZONE(zone);
dns_diff_clear(&diff);