return;
}
assert(catz->cat_members != NULL); // if this failed to allocate, catz wasn't added to zonedb
- knot_dname_t *owner = catalog_member_owner(zone->name, cg, zone->timers.catalog_member);
+ knot_dname_t *owner = catalog_member_owner(zone->name, cg, zone->timers->catalog_member);
if (owner == NULL) {
catz->cat_members->error = KNOT_ENOENT;
return;
log_zone_error(zone->name, "member zone belongs to non-generated catalog zone");
return;
}
- knot_dname_t *owner = catalog_member_owner(zone->name, cg, zone->timers.catalog_member);
+ knot_dname_t *owner = catalog_member_owner(zone->name, cg, zone->timers->catalog_member);
if (owner == NULL) {
catz->cat_members->error = KNOT_ENOENT;
return;
if (dnssec_ctx->policy->ds_push && node_rrtype_exists(ch.add->apex, KNOT_RRTYPE_CDS)) {
// there is indeed a change to CDS
- update->zone->timers.next_ds_push = time(NULL) + dnssec_ctx->policy->propagation_delay;
- zone_events_schedule_at(update->zone, ZONE_EVENT_DS_PUSH, update->zone->timers.next_ds_push);
+ update->zone->timers->next_ds_push = time(NULL) + dnssec_ctx->policy->propagation_delay;
+ zone_events_schedule_at(update->zone, ZONE_EVENT_DS_PUSH, update->zone->timers->next_ds_push);
}
ret = zone_update_apply_changeset(update, &ch);
log_dnssec_next(zone->name, (time_t)refresh_at);
if (refresh->plan_ds_check) {
- zone->timers.next_ds_check = now;
+ zone->timers->next_ds_check = now;
}
unsigned jitter = dnskey_sync_jitter(conf, zone);
ret = knot_parent_ds_query(conf, &ctx, zone->server,
conf->cache.srv_tcp_remote_io_timeout);
- zone->timers.next_ds_check = 0;
+ zone->timers->next_ds_check = 0;
switch (ret) {
case KNOT_NO_READY_KEY:
break;
default:
if (ctx.policy->ksk_sbm_check_interval > 0) {
time_t next_check = time(NULL) + ctx.policy->ksk_sbm_check_interval;
- zone->timers.next_ds_check = next_check;
+ zone->timers->next_ds_check = next_check;
zone_events_schedule_at(zone, ZONE_EVENT_DS_CHECK, next_check);
}
}
conf_remote_t parent = conf_remote(conf, iter.id, i);
ret = send_ds_push(conf, zone, &parent, timeout);
if (ret == KNOT_EOK) {
- zone->timers.next_ds_push = 0;
+ zone->timers->next_ds_push = 0;
break;
}
}
if (ret != KNOT_EOK) {
time_t next_push = time(NULL) + DS_PUSH_RETRY;
zone_events_schedule_at(zone, ZONE_EVENT_DS_PUSH, next_push);
- zone->timers.next_ds_push = next_push;
+ zone->timers->next_ds_push = next_push;
}
conf_mix_iter_next(&iter);
}
char expires_in[32] = "";
- if (zone->timers.next_expire > 0) {
+ if (zone->timers->next_expire > 0) {
(void)snprintf(expires_in, sizeof(expires_in),
", expires in %u seconds",
- (uint32_t)MAX(zone->timers.next_expire - time(NULL), 0));
+ (uint32_t)MAX(zone->timers->next_expire - time(NULL), 0));
}
log_zone_info(zone->name, "loaded, serial %s -> %u%s, %zu bytes%s",
replan_from_timers(conf, zone);
- if (!zone_timers_serial_notified(&zone->timers, new_serial)) {
+ if (!zone_timers_serial_notified(zone->timers, new_serial)) {
zone_schedule_notify(conf, zone, 0);
}
zone_redis_disconnect(db_ctx, true);
NOTIFY_OUT_LOG(LOG_INFO, zone->name, slave,
requestor.layer.flags,
"%sserial %u", log_retry, knot_soa_serial(soa->rrs.rdata));
- zone->timers.last_notified_serial = (knot_soa_serial(soa->rrs.rdata) | LAST_NOTIFIED_SERIAL_VALID);
+ zone->timers->last_notified_serial = (knot_soa_serial(soa->rrs.rdata) | LAST_NOTIFIED_SERIAL_VALID);
} else if (knot_pkt_ext_rcode(req->resp) == 0) {
NOTIFY_OUT_LOG(LOG_WARNING, zone->name, slave,
requestor.layer.flags,
if (expire_opt != NULL && knot_edns_opt_get_length(expire_opt) == sizeof(uint32_t)) {
uint32_t edns_expire = knot_wire_read_u32(knot_edns_opt_get_data(expire_opt));
data->expire_timer = strictly_follow ? edns_expire :
- MAX(edns_expire, data->zone->timers.next_expire - time(NULL));
+ MAX(edns_expire, data->zone->timers->next_expire - time(NULL));
}
}
uint32_t soa_refresh = knot_soa_refresh(soa->rdata);
limit_timer(conf, zone->name, &soa_refresh, "refresh",
C_REFRESH_MIN_INTERVAL, C_REFRESH_MAX_INTERVAL);
- zone->timers.next_refresh = now + soa_refresh;
- zone->timers.last_refresh_ok = true;
+ zone->timers->next_refresh = now + soa_refresh;
+ zone->timers->last_refresh_ok = true;
if (zone->is_catalog_flag) {
// It's already zero in most cases.
- zone->timers.next_expire = 0;
+ zone->timers->next_expire = 0;
} else if (also_expire) {
limit_timer(conf, zone->name, &data->expire_timer, "expire",
// Limit min if not received as EDNS Expire.
data->expire_timer == knot_soa_expire(soa->rdata) ?
C_EXPIRE_MIN_INTERVAL : 0,
C_EXPIRE_MAX_INTERVAL);
- zone->timers.next_expire = now + data->expire_timer;
+ zone->timers->next_expire = now + data->expire_timer;
}
}
static void fill_expires_in(char *expires_in, size_t size, const struct refresh_data *data)
{
- assert(!data->zone->is_catalog_flag || data->zone->timers.next_expire == 0);
- if (data->zone->timers.next_expire > 0 && data->expire_timer > 0) {
+ assert(!data->zone->is_catalog_flag || data->zone->timers->next_expire == 0);
+ if (data->zone->timers->next_expire > 0 && data->expire_timer > 0) {
(void)snprintf(expires_in, size,
", expires in %u seconds", data->expire_timer);
}
} else if (data->fallback->trying_last) {
return false;
// Pinned master expected but not yet set, force AXFR (e.g. dropped timers).
- } else if (data->zone->timers.last_master.sin6_family == AF_UNSPEC) {
+ } else if (data->zone->timers->last_master.sin6_family == AF_UNSPEC) {
data->xfr_type = XFR_TYPE_AXFR;
return false;
}
time_t now = time(NULL);
// Starting countdown for master transition.
- if (data->zone->timers.master_pin_hit == 0) {
- data->zone->timers.master_pin_hit = now;
+ if (data->zone->timers->master_pin_hit == 0) {
+ data->zone->timers->master_pin_hit = now;
zone_events_schedule_at(data->zone, ZONE_EVENT_REFRESH, now + data->fallback->pin_tol);
// Switch to a new master.
- } else if (data->zone->timers.master_pin_hit + data->fallback->pin_tol <= now) {
+ } else if (data->zone->timers->master_pin_hit + data->fallback->pin_tol <= now) {
data->xfr_type = XFR_TYPE_AXFR;
return false;
// Replan the refresh to the moment when the pin tolerance times out.
} else {
zone_events_schedule_at(data->zone, ZONE_EVENT_REFRESH,
- data->zone->timers.master_pin_hit + data->fallback->pin_tol);
+ data->zone->timers->master_pin_hit + data->fallback->pin_tol);
}
return true;
limit_timer(conf, zone->name, &next, "retry",
C_RETRY_MIN_INTERVAL, C_RETRY_MAX_INTERVAL);
time_t now = time(NULL);
- zone->timers.next_refresh = now + next;
- zone->timers.last_refresh_ok = false;
+ zone->timers->next_refresh = now + next;
+ zone->timers->last_refresh_ok = false;
char time_str[64] = { 0 };
struct tm time_gm = { 0 };
- localtime_r(&zone->timers.next_refresh, &time_gm);
+ localtime_r(&zone->timers->next_refresh, &time_gm);
strftime(time_str, sizeof(time_str), KNOT_LOG_TIME_FORMAT, &time_gm);
char expires_in[32] = "";
if (!zone->is_catalog_flag) {
struct refresh_data data = {
.zone = zone,
- .expire_timer = zone->timers.next_expire - now,
+ .expire_timer = zone->timers->next_expire - now,
};
fill_expires_in(expires_in, sizeof(expires_in), &data);
}
time_t refresh = TIME_CANCEL;
if (zone_is_slave(conf, zone)) {
- refresh = zone->timers.next_refresh;
- if (zone->contents == NULL && zone->timers.last_refresh_ok) { // zone disappeared w/o expiry
+ refresh = zone->timers->next_refresh;
+ if (zone->contents == NULL && zone->timers->last_refresh_ok) { // zone disappeared w/o expiry
refresh = now;
}
if (refresh == 0) { // sanitize in case of concurrent purge event
time_t expire = TIME_IGNORE;
if (zone_is_slave(conf, zone) && zone->contents != NULL) {
expire_pre = TIME_CANCEL;
- expire = zone->timers.next_expire;
+ expire = zone->timers->next_expire;
}
time_t flush = TIME_IGNORE;
conf_val_t val = conf_zone_get(conf, C_ZONEFILE_SYNC, zone->name);
int64_t sync_timeout = conf_int(&val);
if (sync_timeout > 0) {
- flush = zone->timers.last_flush + sync_timeout;
+ flush = zone->timers->last_flush + sync_timeout;
}
}
}
}
- ds_check = zone->timers.next_ds_check;
+ ds_check = zone->timers->next_ds_check;
if (ds_check == 0) {
ds_check = TIME_IGNORE;
}
- ds_push = zone->timers.next_ds_push;
+ ds_push = zone->timers->next_ds_push;
if (ds_push == 0) {
ds_push = TIME_IGNORE;
}
if (knot_pkt_edns_option(qdata->query, KNOT_EDNS_OPTION_EXPIRE) != NULL &&
qdata->extra->contents != NULL && !qdata->extra->zone->is_catalog_flag) {
knot_time_t expire = knot_time_min(ATOMIC_GET(qdata->extra->contents->dnssec_expire),
- qdata->extra->zone->timers.next_expire);
+ qdata->extra->zone->timers->next_expire);
uint32_t timer;
if (expire == 0) {
timer = zone_soa_expire(qdata->extra->zone);
return ret;
}
if (ctx->restore_mode) {
- ret = zone_timers_read(&ctx->bck_timer_db, zone->name, &zone->timers);
+ ret = zone_timers_read(&ctx->bck_timer_db, zone->name, zone->timers);
zone_timers_sanitize(conf, zone);
zone->zonefile.bootstrap_cnt = 0;
} else {
- ret = zone_timers_write(&ctx->bck_timer_db, zone->name, &zone->timers);
+ ret = zone_timers_write(&ctx->bck_timer_db, zone->name, zone->timers);
}
if (ret != KNOT_EOK) {
LOG_MARK_FAIL("timers");
static void txn_zone_write(zone_t *z, knot_lmdb_txn_t *txn)
{
- txn_write_timers(txn, z->name, &z->timers);
+ txn_write_timers(txn, z->name, z->timers);
}
int zone_timers_write_all(knot_lmdb_db_t *db, knot_zonedb_t *zonedb)
flush_journal_replan:
/* Plan next journal flush after proper period. */
- zone->timers.last_flush = time(NULL);
+ zone->timers->last_flush = time(NULL);
if (sync_timeout > 0) {
- time_t next_flush = zone->timers.last_flush + sync_timeout;
+ time_t next_flush = zone->timers->last_flush + sync_timeout;
zone_events_schedule_at(zone, ZONE_EVENT_FLUSH, (time_t)0,
ZONE_EVENT_FLUSH, next_flush);
}
return NULL;
}
+ zone->timers = calloc(1, sizeof(*zone->timers));
+ if (zone->timers == NULL) {
+ knot_dname_free(zone->name, NULL);
+ free(zone);
+ return NULL;
+ }
+
// DDNS
pthread_mutex_init(&zone->ddns_lock, NULL);
zone->ddns_queue_size = 0;
ATOMIC_DEINIT(zone->backup_ctx);
+ free(zone->timers);
free(zone);
*zone_ptr = NULL;
}
// Purge the zone timers.
if (params & PURGE_ZONE_TIMERS) {
- bool member = (zone->catalog_gen != NULL);
- zone->timers = (zone_timers_t) {
- .catalog_member = member ? zone->timers.catalog_member : 0
- };
+ time_t member = (zone->catalog_gen != NULL ? zone->timers->catalog_member : 0);
+ memset(zone->timers, 0, sizeof(*zone->timers));
+ zone->timers->catalog_member = member;
+
if (member) {
ret = zone_timers_write(&zone->server->timerdb, zone->name,
- &zone->timers);
+ zone->timers);
} else {
ret = zone_timers_sweep(&zone->server->timerdb,
dname_cmp_sweep_wrap, zone->name);
zone_set_last_master(zone, NULL);
- zone->timers.next_expire = time(NULL);
- zone->timers.next_refresh = zone->timers.next_expire;
+ zone->timers->next_expire = time(NULL);
+ zone->timers->next_refresh = zone->timers->next_expire;
replan_from_timers(conf, zone);
}
}
if (addr == NULL) {
- memset(&zone->timers.last_master, 0, sizeof(zone->timers.last_master));
+ memset(&zone->timers->last_master, 0, sizeof(zone->timers->last_master));
} else {
- memcpy(&zone->timers.last_master, addr, sizeof(zone->timers.last_master));
+ memcpy(&zone->timers->last_master, addr, sizeof(zone->timers->last_master));
}
- zone->timers.master_pin_hit = 0;
+ zone->timers->master_pin_hit = 0;
}
static void set_flag(zone_t *zone, zone_flag_t flag, bool remove)
return false;
}
- const zone_timers_t *timers = &zone->timers;
-
- return timers->next_expire > 0 && timers->next_expire <= time(NULL);
+ return zone->timers->next_expire > 0 && zone->timers->next_expire <= time(NULL);
}
static void time_set_default(time_t *time, time_t value)
time_t now = time(NULL);
// assume now if we don't know when we flushed
- time_set_default(&zone->timers.last_flush, now);
+ time_set_default(&zone->timers->last_flush, now);
if (zone_is_slave(conf, zone)) {
// assume now if we don't know
- time_set_default(&zone->timers.next_refresh, now);
+ time_set_default(&zone->timers->next_refresh, now);
if (zone->is_catalog_flag) {
- zone->timers.next_expire = 0;
+ zone->timers->next_expire = 0;
}
} else {
// invalidate if we don't have a master
- zone->timers.last_refresh = 0;
- zone->timers.next_refresh = 0;
- zone->timers.last_refresh_ok = false;
- zone->timers.next_expire = 0;
+ zone->timers->last_refresh = 0;
+ zone->timers->next_refresh = 0;
+ zone->timers->last_refresh_ok = false;
+ zone->timers->next_expire = 0;
}
}
preferred_2x = (zone->flags & ZONE_PREF_MASTER_2X);
}
if (pin_tolerance > 0 &&
- sockaddr_net_match(&remote.addr, (struct sockaddr_storage *)&zone->timers.last_master, -1)) {
+ sockaddr_net_match(&remote.addr, (struct sockaddr_storage *)&zone->timers->last_master, -1)) {
last_id = conf_str(iter.id);
last = *iter.id;
last_idx = idx;
void zone_set_lastsigned_serial(zone_t *zone, uint32_t serial)
{
- zone->timers.last_signed_serial = serial;
- zone->timers.last_signed_s_flags = LAST_SIGNED_SERIAL_FOUND | LAST_SIGNED_SERIAL_VALID;
+ zone->timers->last_signed_serial = serial;
+ zone->timers->last_signed_s_flags = LAST_SIGNED_SERIAL_FOUND | LAST_SIGNED_SERIAL_VALID;
}
int zone_get_lastsigned_serial(zone_t *zone, uint32_t *serial)
{
- if (!(zone->timers.last_signed_s_flags & LAST_SIGNED_SERIAL_FOUND)) {
+ if (!(zone->timers->last_signed_s_flags & LAST_SIGNED_SERIAL_FOUND)) {
// backwards compatibility: it used to be stored in KASP DB, moved to timers for performance
return kasp_db_load_serial(zone_kaspdb(zone), zone->name, KASPDB_SERIAL_LASTSIGNED, serial);
}
- if (!(zone->timers.last_signed_s_flags & LAST_SIGNED_SERIAL_VALID)) {
+ if (!(zone->timers->last_signed_s_flags & LAST_SIGNED_SERIAL_VALID)) {
return KNOT_ENOENT;
}
- *serial = zone->timers.last_signed_serial;
+ *serial = zone->timers->last_signed_serial;
return KNOT_EOK;
}
} zonefile;
/*! \brief Zone events. */
- zone_timers_t timers; //!< Persistent zone timers.
+ zone_timers_t *timers; //!< Persistent zone timers.
zone_events_t events; //!< Zone events timers.
/*! \brief Track unsuccessful NOTIFY targets. */
zone->contents = old_zone->contents;
zone_set_flag(zone, zone_get_flag(old_zone, ~0, false));
- zone->timers = old_zone->timers;
+ memcpy(zone->timers, old_zone->timers, sizeof(*zone->timers));
zone_timers_sanitize(conf, zone);
if (old_zone->control_update != NULL) {
return NULL;
}
- int ret = zone_timers_read(&server->timerdb, name, &zone->timers);
+ int ret = zone_timers_read(&server->timerdb, name, zone->timers);
if (ret != KNOT_EOK && ret != KNOT_ENODB && ret != KNOT_ENOENT) {
log_zone_error(zone->name, "failed to load persistent timers (%s)",
knot_strerror(ret));
conf_val_t catz = conf_zone_get(conf, C_CATALOG_ZONE, name);
assert(catz.code == KNOT_EOK); // conf consistency checked in conf/tools.c
zone->catalog_gen = knot_dname_copy(conf_dname(&catz), NULL);
- if (zone->timers.catalog_member == 0) {
- zone->timers.catalog_member = time(NULL);
+ if (zone->timers->catalog_member == 0) {
+ zone->timers->catalog_member = time(NULL);
ret = zone_timers_write(&zone->server->timerdb, zone->name,
- &zone->timers);
+ zone->timers);
}
if (ret != KNOT_EOK || zone->catalog_gen == NULL) {
log_zone_error(zone->name, "failed to initialize catalog member zone (%s)",
static zone_contents_t *zone_expire(zone_t *zone, bool zonedb_cow)
{
if (!zonedb_cow) {
- zone->timers.next_expire = time(NULL);
- zone->timers.next_refresh = zone->timers.next_expire;
+ zone->timers->next_expire = time(NULL);
+ zone->timers->next_refresh = zone->timers->next_expire;
}
return zone_switch_contents(zone, NULL);
}