#include "knot/dnssec/key-events.h"
#include "knot/dnssec/policy.h"
#include "knot/dnssec/zone-keys.h"
+#include "knot/zone/serial.h"
+#include "libdnssec/random.h"
static bool key_present(const kdnssec_ctx_t *ctx, bool ksk, bool zsk)
{
}
return false;
}
+
+unsigned dnskey_sync_jitter(conf_t *conf, zone_t *zone)
+{
+ conf_val_t id = conf_zone_get(conf, C_DNSSEC_POLICY, zone->name);
+ conf_id_fix_default(&id);
+ conf_val_t val = conf_id_get(conf, C_POLICY, C_KEYTAG_MODULO, &id);
+ if (val.code == KNOT_EOK) {
+ int zero;
+ uint32_t rem, mod;
+ int ret = serial_modulo_parse(conf_str(&val), &rem, &mod, &zero);
+ if (ret == KNOT_EOK && mod > 1) {
+ return 2 * rem;
+ }
+ }
+ return dnssec_random_uint16_t() % 5;
+}
* \return False if there is no submitted key or if error; True otherwise
*/
bool zone_has_key_sbm(const kdnssec_ctx_t *ctx);
+
+/*!
+ * \brief Returns jitter for dnskey-sync event schedulling
+ *
+ * The purpose of the jitter is to minimize a race condition during mutual
+ * synchronization.
+ *
+ * \param conf Configuration.
+ * \param zon Zone to compute jitter for.
+ *
+ * \return Jitter value.
+ */
+unsigned dnskey_sync_jitter(conf_t *conf, zone_t *zone);
// NOTE: this is usually NOOP since signing planned earlier
zone_events_schedule_at(update->zone, ZONE_EVENT_DNSSEC, (time_t)(next ? next : -1));
if (ctx.policy->has_dnskey_sync) {
- zone_events_schedule_now(update->zone, ZONE_EVENT_DNSKEY_SYNC);
+ unsigned jitter = dnskey_sync_jitter(conf, update->zone);
+ zone_events_schedule_at(update->zone, ZONE_EVENT_DNSKEY_SYNC,
+ time(NULL) + jitter);
}
update->new_cont->dnssec_expire = knot_time_min(update->zone->contents->dnssec_expire, ctx.stats->expire);
}
}
if (data.ddns_sent && ret == KNOT_ETIMEOUT) {
- DNSKEY_SYNC_LOG(LOG_WARNING, zone->name, remote, requestor.layer.flags,
+ DNSKEY_SYNC_LOG(LOG_NOTICE, zone->name, remote, requestor.layer.flags,
"timed out, may be caused by parallel mutual DNSKEY sync, "
"may settle down after check-interval");
ret = KNOT_EOK;
#include "knot/common/log.h"
#include "knot/conf/conf.h"
+#include "knot/dnssec/key-events.h"
#include "knot/dnssec/zone-events.h"
#include "knot/updates/apply.h"
#include "knot/zone/zone.h"
zone->timers.next_ds_check = now;
}
+ unsigned jitter = dnskey_sync_jitter(conf, zone);
zone_events_schedule_at(zone,
ZONE_EVENT_DNSSEC, refresh_at ? (time_t)refresh_at : ignore,
ZONE_EVENT_DS_CHECK, refresh->plan_ds_check ? now : ignore,
- ZONE_EVENT_DNSKEY_SYNC, refresh->plan_dnskey_sync ? now : ignore
+ ZONE_EVENT_DNSKEY_SYNC, refresh->plan_dnskey_sync ? now + jitter : ignore
);
if (zone_changed) {
zone_schedule_notify(zone, 0);
t.sleep(0.5)
signer3.ctl("zone-key-rollover %s %s" % (zone[0].name, "zsk" if SIGNER2ROLL == 0 else "ksk"))
-t.sleep(6)
+t.sleep(8)
check_same_dnskey(signer1, signer2, signer3, t)
-t.sleep(6)
+t.sleep(8)
check_same_dnskey(signer1, signer2, signer3, t)
t.end()