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);
+ zone->timers->flags |= LAST_NOTIFIED_SERIAL_VALID;
} else if (knot_pkt_ext_rcode(req->resp) == 0) {
NOTIFY_OUT_LOG(LOG_WARNING, zone->name, slave,
requestor.layer.flags,
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->flags |= LAST_REFRESH_OK;
if (zone->is_catalog_flag) {
// It's already zero in most cases.
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->flags &= ~LAST_REFRESH_OK;
char time_str[64] = { 0 };
struct tm time_gm = { 0 };
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
+ if (zone->contents == NULL && (zone->timers->flags & LAST_REFRESH_OK)) { // zone disappeared w/o expiry
refresh = now;
}
if (refresh == 0) { // sanitize in case of concurrent purge event
#define TIMER_SIZE (sizeof(uint8_t) + sizeof(uint64_t))
+inline static void set_flag(zone_timers_t *t, uint32_t flag, uint32_t on)
+{
+ if (on) {
+ t->flags |= flag;
+ } else {
+ t->flags &= ~flag;
+ }
+}
+
/*!
* \brief Deserialize timers from a binary buffer.
*
switch (id) {
case TIMER_LAST_FLUSH: timers.last_flush = value; break;
case TIMER_NEXT_REFRESH: timers.next_refresh = value; break;
- case TIMER_LAST_REFR_OK: timers.last_refresh_ok = value; break;
- case TIMER_LAST_NOTIFIED: timers.last_notified_serial = value; break;
+ case TIMER_LAST_REFR_OK: set_flag(&timers, LAST_REFRESH_OK, value); break;
+ case TIMER_LAST_NOTIFIED:
+ timers.last_notified_serial = (value & 0xffffffffLLU);
+ set_flag(&timers, LAST_NOTIFIED_SERIAL_VALID, (value >> 32));
+ break;
case TIMER_NEXT_DS_CHECK: timers.next_ds_check = value; break;
case TIMER_NEXT_DS_PUSH: timers.next_ds_push = value; break;
case TIMER_CATALOG_MEMBER: timers.catalog_member = value; break;
case TIMER_MASTER_PIN_HIT: timers.master_pin_hit = value; break;
case TIMER_LAST_SIGNED:
timers.last_signed_serial = (value & 0xffffffffLLU);
- timers.last_signed_s_flags = LAST_SIGNED_SERIAL_FOUND;
- timers.last_signed_s_flags |= (value >> 32) & LAST_SIGNED_SERIAL_VALID;
+ timers.flags |= LAST_SIGNED_SERIAL_FOUND;
+ set_flag(&timers, LAST_SIGNED_SERIAL_VALID, (value >> 32));
break;
default: break; // ignore
}
MDB_val v = knot_lmdb_make_key(format,
TIMER_LAST_FLUSH, (uint64_t)timers->last_flush,
TIMER_NEXT_REFRESH, (uint64_t)timers->next_refresh,
- TIMER_LAST_REFR_OK, (uint64_t)timers->last_refresh_ok,
- TIMER_LAST_NOTIFIED, timers->last_notified_serial,
+ TIMER_LAST_REFR_OK, (uint64_t)(bool)(timers->flags & LAST_REFRESH_OK),
+ TIMER_LAST_NOTIFIED, (uint64_t)timers->last_notified_serial | (((uint64_t)(bool)(timers->flags & LAST_NOTIFIED_SERIAL_VALID)) << 32),
TIMER_NEXT_DS_CHECK, (uint64_t)timers->next_ds_check,
TIMER_NEXT_DS_PUSH, (uint64_t)timers->next_ds_push,
TIMER_CATALOG_MEMBER,(uint64_t)timers->catalog_member,
TIMER_NEXT_EXPIRE, (uint64_t)timers->next_expire,
- TIMER_LAST_SIGNED, (uint64_t)timers->last_signed_serial | (((uint64_t)timers->last_signed_s_flags) << 32),
+ TIMER_LAST_SIGNED, (uint64_t)timers->last_signed_serial | (((uint64_t)(bool)(timers->flags & LAST_SIGNED_SERIAL_VALID)) << 32),
TIMER_MASTER_PIN_HIT,(uint64_t)timers->master_pin_hit, // those items should be last two
TIMER_LAST_MASTER, &timers->last_master, sizeof(timers->last_master));
knot_lmdb_insert(txn, &k, &v);
bool zone_timers_serial_notified(const zone_timers_t *timers, uint32_t serial)
{
- return (timers->last_notified_serial & LAST_NOTIFIED_SERIAL_VALID) &&
- ((uint32_t)timers->last_notified_serial == serial);
+ return (timers->flags & LAST_NOTIFIED_SERIAL_VALID) &&
+ (timers->last_notified_serial == serial);
}
#include "libknot/dname.h"
#include "knot/journal/knot_lmdb.h"
-#define LAST_NOTIFIED_SERIAL_VALID (1LLU << 32)
-#define LAST_SIGNED_SERIAL_FOUND (1 << 0)
-#define LAST_SIGNED_SERIAL_VALID (1 << 1)
+#define LAST_SIGNED_SERIAL_FOUND (1 << 1)
+#define LAST_SIGNED_SERIAL_VALID (1 << 2)
+#define LAST_NOTIFIED_SERIAL_VALID (1 << 3)
+#define LAST_REFRESH_OK (1 << 4)
/*!
* \brief Persistent zone timers.
*/
struct zone_timers {
+ uint32_t flags; //!< Various flags.
time_t last_flush; //!< Last zone file synchronization.
time_t next_refresh; //!< Next zone refresh attempt.
uint32_t last_signed_serial; //!< SOA serial of last signed zone version.
- uint8_t last_signed_s_flags; //!< If last signed serial detected and valid;
- bool last_refresh_ok; //!< Last zone refresh attempt was successful.
- uint64_t last_notified_serial; //!< SOA serial of last successful NOTIFY; (1<<32) if none.
+ uint32_t last_notified_serial; //!< SOA serial of last successful NOTIFY.
time_t next_ds_check; //!< Next parent DS check.
time_t next_ds_push; //!< Next DDNS to parent zone with updated DS record.
time_t catalog_member; //!< This catalog member zone created.
} else {
// invalidate if we don't have a master
zone->timers->next_refresh = 0;
- zone->timers->last_refresh_ok = false;
+ zone->timers->flags &= ~LAST_REFRESH_OK;
zone->timers->next_expire = 0;
}
}
{
bool extra_txn = (zone->control_update != NULL && zone->timers == zone->timers_static && zone_timers_begin(zone) == KNOT_EOK); // zone_update_commit() is not within a zone event in case of control_update
zone->timers->last_signed_serial = serial;
- zone->timers->last_signed_s_flags = LAST_SIGNED_SERIAL_FOUND | LAST_SIGNED_SERIAL_VALID;
+ zone->timers->flags |= LAST_SIGNED_SERIAL_FOUND | LAST_SIGNED_SERIAL_VALID;
if (extra_txn) {
zone_timers_commit(zone);
}
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->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->flags & LAST_SIGNED_SERIAL_VALID)) {
return KNOT_ENOENT;
}
*serial = zone->timers->last_signed_serial;
#include "libknot/error.h"
static const zone_timers_t MOCK_TIMERS = {
+ .flags = LAST_SIGNED_SERIAL_FOUND | LAST_SIGNED_SERIAL_VALID,
.last_flush = 1474559960,
.next_refresh = 1474559961,
- .last_refresh_ok = true,
.last_notified_serial = 123456,
.next_ds_check = 1474559962,
.next_ds_push = 1474559963,
.last_master = { .sin6_family = AF_INET, .sin6_port = 53 },
.master_pin_hit = 1474559966,
.last_signed_serial = 12354678,
- .last_signed_s_flags = LAST_SIGNED_SERIAL_FOUND | LAST_SIGNED_SERIAL_VALID,
};
static bool timers_eq(const zone_timers_t *val, const zone_timers_t *ref)
{
return val->last_flush == ref->last_flush &&
+ val->flags == ref->flags &&
val->next_refresh == ref->next_refresh &&
- val->last_refresh_ok == ref->last_refresh_ok &&
- val->last_notified_serial == ref->last_notified_serial &&
+ (val->last_notified_serial == ref->last_notified_serial || !(val->flags & LAST_NOTIFIED_SERIAL_VALID)) &&
val->next_ds_check == ref->next_ds_check &&
val->next_ds_push == ref->next_ds_push &&
val->catalog_member == ref->catalog_member &&
sockaddr_cmp((struct sockaddr_storage *)&val->last_master,
(struct sockaddr_storage *)&ref->last_master, false) == 0 &&
val->master_pin_hit == ref->master_pin_hit &&
- (val->last_signed_s_flags & LAST_SIGNED_SERIAL_VALID) == (ref->last_signed_s_flags & LAST_SIGNED_SERIAL_VALID) &&
- (val->last_signed_serial == ref->last_signed_serial || !(val->last_signed_s_flags & LAST_SIGNED_SERIAL_VALID));
+ (val->last_signed_serial == ref->last_signed_serial || !(val->flags & LAST_SIGNED_SERIAL_VALID));
}
static bool keep_all(const knot_dname_t *zone, void *data)