}
void event_dnssec_reschedule(conf_t *conf, zone_t *zone,
- const zone_sign_reschedule_t *refresh, bool zone_changed)
+ const zone_sign_reschedule_t *refresh)
{
time_t now = time(NULL);
time_t ignore = -1;
ZONE_EVENT_DS_CHECK, refresh->plan_ds_check ? now : ignore,
ZONE_EVENT_DNSKEY_SYNC, refresh->plan_dnskey_sync ? now + jitter : ignore
);
- if (zone_changed) {
+ if (refresh->zone_changed) {
zone_schedule_notify(zone, 0);
}
}
zone_sign_reschedule_t resch = { 0 };
zone_sign_roll_flags_t r_flags = KEY_ROLL_ALLOW_ALL;
int sign_flags = 0;
- bool zone_changed = false;
if (zone_get_flag(zone, ZONE_FORCE_RESIGN, true)) {
log_zone_info(zone->name, "DNSSEC, dropping previous "
goto done;
}
- zone_changed = !zone_update_no_change(&up);
+ resch.zone_changed = !zone_update_no_change(&up);
+
+ zone_update_set_post_commit(&up, (zone_update_commit_cb_t)event_dnssec_reschedule, &resch);
ret = zone_update_commit(conf, &up);
if (ret != KNOT_EOK) {
}
done:
- // Schedule dependent events
- event_dnssec_reschedule(conf, zone, &resch, zone_changed);
-
if (ret != KNOT_EOK) {
zone_update_clear(&up);
}
enum state state; //!< Event processing state.
enum xfr_type xfr_type; //!< Transfer type (mostly IXFR versus AXFR).
bool axfr_style_ixfr; //!< Master responded with AXFR-style-IXFR.
+ bool axfr_bootstrap;
knot_rrset_t *initial_soa_copy; //!< Copy of the received initial SOA.
struct xfr_stats stats; //!< Transfer statistics.
struct timespec started; //!< When refresh started.
size_t change_size; //!< Size of added and removed RRs.
+ uint32_t old_serial;
+ uint32_t master_serial;
struct {
zone_contents_t *zone; //!< AXFR result, new zone.
zone_contents_set_soa_serial(new_contents, new_serial);
}
+static void post_commit(conf_t *conf, zone_t *zone, void *ctx)
+{
+ struct refresh_data *data = ctx;
+ conf_val_t val = conf_zone_get(data->conf, C_DNSSEC_SIGNING, data->zone->name);
+ bool dnssec_enable = conf_bool(&val);
+
+ if (dnssec_enable && (data->xfr_type == XFR_TYPE_AXFR || !EMPTY_LIST(data->ixfr.changesets))) {
+ int ret = zone_set_master_serial(data->zone, data->master_serial);
+ if (ret != KNOT_EOK) {
+ log_zone_warning(data->zone->name,
+ "unable to save master serial, future transfers might be broken");
+ }
+ }
+
+ finalize_timers(data);
+ xfr_log_publish(data, data->old_serial, zone_contents_serial(data->zone->contents),
+ data->master_serial, dnssec_enable, data->axfr_bootstrap);
+
+
+ if (data->xfr_type == XFR_TYPE_AXFR || data->old_serial != zone_contents_serial(data->zone->contents)) {
+ data->fallback->remote = false;
+ zone_set_last_master(data->zone, (const struct sockaddr_storage *)data->remote);
+ }
+}
+
static int axfr_finalize(struct refresh_data *data)
{
zone_contents_t *new_zone = data->axfr.zone;
conf_val_t val = conf_zone_get(data->conf, C_DNSSEC_SIGNING, data->zone->name);
bool dnssec_enable = conf_bool(&val);
- uint32_t old_serial = zone_contents_serial(data->zone->contents), master_serial = 0;
- bool bootstrap = (data->zone->contents == NULL);
+ data->old_serial = zone_contents_serial(data->zone->contents);
+ data->axfr_bootstrap = (data->zone->contents == NULL);
zone_skip_t skip = { 0 };
int ret = KNOT_EOK;
if (dnssec_enable) {
- axfr_slave_sign_serial(new_zone, data->zone, data->conf, &master_serial);
+ axfr_slave_sign_serial(new_zone, data->zone, data->conf, &data->master_serial);
ret = zone_skip_add_dnssec_diff(&skip);
assert(ret == KNOT_EOK); // static size of zone_skip is enough to cover dnssec types
}
return ret;
}
+ zone_update_set_post_commit(&up, post_commit, data);
+
ret = zone_update_commit(data->conf, &up);
if (ret != KNOT_EOK) {
zone_update_clear(&up);
return ret;
}
- if (dnssec_enable) {
- ret = zone_set_master_serial(data->zone, master_serial);
- if (ret != KNOT_EOK) {
- log_zone_warning(data->zone->name,
- "unable to save master serial, future transfers might be broken");
- }
- }
-
- finalize_timers(data);
- xfr_log_publish(data, old_serial, zone_contents_serial(data->zone->contents),
- master_serial, dnssec_enable, bootstrap);
-
- data->fallback->remote = false;
- zone_set_last_master(data->zone, (const struct sockaddr_storage *)data->remote);
-
return KNOT_EOK;
}
{
conf_val_t val = conf_zone_get(data->conf, C_DNSSEC_SIGNING, data->zone->name);
bool dnssec_enable = conf_bool(&val);
- uint32_t master_serial = 0, old_serial = zone_contents_serial(data->zone->contents);
+ data->old_serial = zone_contents_serial(data->zone->contents);
if (dnssec_enable) {
- int ret = ixfr_slave_sign_serial(&data->ixfr.changesets, data->zone, data->conf, &master_serial);
+ int ret = ixfr_slave_sign_serial(&data->ixfr.changesets, data->zone, data->conf, &data->master_serial);
if (ret != KNOT_EOK) {
IXFRIN_LOG(LOG_WARNING, data,
"failed to adjust SOA serials from unsigned remote (%s)",
return ret;
}
+ zone_update_set_post_commit(&up, post_commit, data);
+
ret = zone_update_commit(data->conf, &up);
if (ret != KNOT_EOK) {
zone_update_clear(&up);
return ret;
}
- if (dnssec_enable && !EMPTY_LIST(data->ixfr.changesets)) {
- ret = zone_set_master_serial(data->zone, master_serial);
- if (ret != KNOT_EOK) {
- log_zone_warning(data->zone->name,
- "unable to save master serial, future transfers might be broken");
- }
- }
-
- finalize_timers(data);
- xfr_log_publish(data, old_serial, zone_contents_serial(data->zone->contents),
- master_serial, dnssec_enable, false);
-
- if (old_serial != zone_contents_serial(data->zone->contents)) {
- data->fallback->remote = false;
- zone_set_last_master(data->zone, (const struct sockaddr_storage *)data->remote);
- }
-
return KNOT_EOK;
}
int warning;
} dnssec_validation_hint_t;
+typedef void (*zone_update_commit_cb_t)(conf_t *, zone_t *, void *);
+
/*! \brief Structure for zone contents updating / querying. */
typedef struct zone_update {
zone_t *zone; /*!< Zone being updated. */
changeset_t extra_ch; /*!< Extra changeset to store just diff btwn zonefile and result. */
apply_ctx_t *a_ctx; /*!< Context for applying changesets. */
uint32_t flags; /*!< Zone update flags. */
+ void *post_commit_cb_ctx;
+ zone_update_commit_cb_t post_commit_cb;
dnssec_validation_hint_t validation_hint;
} zone_update_t;
*/
int zone_update_commit(conf_t *conf, zone_update_t *update);
+/*!
+ * \brief Set a callback to be called after successful zone_update_commit.
+ *
+ * \param update Zone update.
+ * \param cb Callback.
+ * \param cb_ctx Arbitrary context.
+ */
+void zone_update_set_post_commit(zone_update_t *update, zone_update_commit_cb_t cb, void *cb_ctx);
+
/*!
* \brief Returns bool whether there are any changes at all.
*