return KNOT_ENOTSUP;
}
- zone->flags |= ZONE_FORCE_AXFR;
+ zone_set_flag(zone, ZONE_FORCE_AXFR);
schedule_trigger(zone, args, ZONE_EVENT_REFRESH, true);
return KNOT_EOK;
}
if (ctl_has_flag(args->data[KNOT_CTL_IDX_FLAGS], CTL_FLAG_FORCE)) {
- zone->flags |= ZONE_FORCE_FLUSH;
+ zone_set_flag(zone, ZONE_FORCE_FLUSH);
}
schedule_trigger(zone, args, ZONE_EVENT_FLUSH, true);
return KNOT_ENOTSUP;
}
- zone->flags |= ZONE_FORCE_RESIGN;
+ zone_set_flag(zone, ZONE_FORCE_RESIGN);
schedule_trigger(zone, args, ZONE_EVENT_DNSSEC, true);
return KNOT_EOK;
const char *key_type = args->data[KNOT_CTL_IDX_TYPE];
if (strncasecmp(key_type, "ksk", 3) == 0) {
- zone->flags |= ZONE_FORCE_KSK_ROLL;
+ zone_set_flag(zone, ZONE_FORCE_KSK_ROLL);
} else if (strncasecmp(key_type, "zsk", 3) == 0) {
- zone->flags |= ZONE_FORCE_ZSK_ROLL;
+ zone_set_flag(zone, ZONE_FORCE_ZSK_ROLL);
} else {
return KNOT_EINVAL;
}
int sign_flags = 0;
bool zone_changed = false;
- if (zone->flags & ZONE_FORCE_RESIGN) {
+ if (zone_get_flag(zone, ZONE_FORCE_RESIGN, true)) {
log_zone_info(zone->name, "DNSSEC, dropping previous "
"signatures, re-signing zone");
- zone->flags &= ~ZONE_FORCE_RESIGN;
sign_flags = ZONE_SIGN_DROP_SIGNATURES;
} else {
log_zone_info(zone->name, "DNSSEC, signing zone");
sign_flags = 0;
}
- if (zone->flags & ZONE_FORCE_KSK_ROLL) {
- zone->flags &= ~ZONE_FORCE_KSK_ROLL;
+ if (zone_get_flag(zone, ZONE_FORCE_KSK_ROLL, true)) {
r_flags |= KEY_ROLL_FORCE_KSK_ROLL;
}
- if (zone->flags & ZONE_FORCE_ZSK_ROLL) {
- zone->flags &= ~ZONE_FORCE_ZSK_ROLL;
+ if (zone_get_flag(zone, ZONE_FORCE_ZSK_ROLL, true)) {
r_flags |= KEY_ROLL_FORCE_ZSK_ROLL;
}
try_refresh_ctx_t trctx = { 0 };
// TODO: Flag on zone is ugly. Event specific parameters would be nice.
- if (zone->flags & ZONE_FORCE_AXFR) {
- zone->flags &= ~ZONE_FORCE_AXFR;
+ if (zone_get_flag(zone, ZONE_FORCE_AXFR, true)) {
trctx.force_axfr = true;
zone->zonefile.retransfer = true;
}
}
/* Allow normal queries to catalog only over TCP and if allowed by ACL. */
- if (qdata->extra->zone != NULL && (qdata->extra->zone->flags & ZONE_IS_CATALOG) &&
+ if (qdata->extra->zone != NULL && qdata->extra->zone->is_catalog_flag &&
query_type(query) == KNOTD_QUERY_TYPE_NORMAL) {
if ((qdata->params->flags & KNOTD_QUERY_FLAG_LIMIT_SIZE) ||
!process_query_acl_check(conf(), ACL_ACTION_TRANSFER, qdata)) {
return (val.code == KNOT_ENOENT || val.code == KNOT_YP_EINVAL_ID) ? KNOT_EOK : val.code;
}
- update->zone->flags |= ZONE_IS_CATALOG;
+ zone_set_flag(update->zone, ZONE_IS_CATALOG);
int ret = KNOT_EOK;
if ((update->flags & UPDATE_INCREMENTAL)) {
int ret = KNOT_EOK;
zone_journal_t j = zone_journal(zone);
- bool force = zone->flags & ZONE_FORCE_FLUSH;
- zone->flags &= ~ZONE_FORCE_FLUSH;
+ bool force = zone_get_flag(zone, ZONE_FORCE_FLUSH, true);
conf_val_t val = conf_zone_get(conf, C_ZONEFILE_SYNC, zone->name);
int64_t sync_timeout = conf_int(&val);
pthread_mutex_unlock(&zone->preferred_lock);
}
+void zone_set_flag(zone_t *zone, zone_flag_t flag)
+{
+ if (zone == NULL) {
+ return;
+ }
+
+ pthread_mutex_lock(&zone->preferred_lock); // this mutex seems OK to be reused for this
+ zone->flags |= flag;
+ pthread_mutex_unlock(&zone->preferred_lock);
+
+ if (flag & ZONE_IS_CATALOG) {
+ zone->is_catalog_flag = true;
+ }
+}
+
+zone_flag_t zone_get_flag(zone_t *zone, zone_flag_t flag, bool clear)
+{
+ if (zone == NULL) {
+ return 0;
+ }
+
+ pthread_mutex_lock(&zone->preferred_lock);
+ zone_flag_t res = (zone->flags & flag);
+ if (clear && res) {
+ zone->flags &= ~flag;
+ }
+ assert(((bool)(zone->flags & ZONE_IS_CATALOG)) == zone->is_catalog_flag);
+ pthread_mutex_unlock(&zone->preferred_lock);
+
+ return res;
+}
+
const knot_rdataset_t *zone_soa(const zone_t *zone)
{
if (!zone || zone_contents_is_empty(zone->contents)) {
/*!
* \brief Zone flags.
*/
-typedef enum zone_flag_t {
+typedef enum {
ZONE_FORCE_AXFR = 1 << 0, /*!< Force AXFR as next transfer. */
ZONE_FORCE_RESIGN = 1 << 1, /*!< Force zone re-sign. */
ZONE_FORCE_FLUSH = 1 << 2, /*!< Force zone flush. */
knot_dname_t *name;
zone_contents_t *contents;
zone_flag_t flags;
+ bool is_catalog_flag; //!< Lock-less indication of ZONE_IS_CATALOG flag.
/*! \brief Dynamic configuration zone change type. */
conf_io_type_t change_type;
catalog_t *catalog;
catalog_update_t *catalog_upd;
- /*! \brief Preferred master lock. */
+ /*! \brief Preferred master lock. Also used for flags access. */
pthread_mutex_t preferred_lock;
/*! \brief Preferred master for remote operation. */
struct sockaddr_storage *preferred_master;
/*! \brief Clears the current preferred master address. */
void zone_clear_preferred_master(zone_t *zone);
+/*! \brief Sets a zone flag. */
+void zone_set_flag(zone_t *zone, zone_flag_t flag);
+
+/*! \brief Returns if a flag is set (and optionally clears it). */
+zone_flag_t zone_get_flag(zone_t *zone, zone_flag_t flag, bool clear);
+
/*! \brief Get zone SOA RR. */
const knot_rdataset_t *zone_soa(const zone_t *zone);
}
zone->contents = old_zone->contents;
- zone->flags = (old_zone->flags & (ZONE_IS_CATALOG | ZONE_IS_CAT_MEMBER));
+ zone_set_flag(zone, zone_get_flag(old_zone, ZONE_IS_CATALOG | ZONE_IS_CAT_MEMBER, false));
zone->timers = old_zone->timers;
timers_sanitize(conf, zone);
static zone_t *reuse_member_zone(zone_t *zone, server_t *server, conf_t *conf,
list_t *expired_contents)
{
- if (!(zone->flags & ZONE_IS_CAT_MEMBER)) {
+ if (!zone_get_flag(zone, ZONE_IS_CAT_MEMBER, false)) {
return NULL;
}
if (newzone == NULL) {
log_zone_error(zone->name, "zone cannot be created");
} else {
- assert(newzone->flags & ZONE_IS_CAT_MEMBER);
+ assert(zone_get_flag(newzone, ZONE_IS_CAT_MEMBER, false));
conf_activate_modules(conf, server, newzone->name, &newzone->query_modules,
&newzone->query_plan);
}
if (zone == NULL) {
log_zone_error(zname, "zone cannot be created");
} else {
- zone->flags |= ZONE_IS_CAT_MEMBER;
+ zone_set_flag(zone, ZONE_IS_CAT_MEMBER);
conf_activate_modules(conf, server, zone->name, &zone->query_modules,
&zone->query_plan);
}
log_zone_error(val->member, "zone cannot be created");
catalog_del2(conf->catalog, val);
} else {
- zone->flags |= ZONE_IS_CAT_MEMBER;
+ zone_set_flag(zone, ZONE_IS_CAT_MEMBER);
conf_activate_modules(conf, server, zone->name, &zone->query_modules,
&zone->query_plan);
log_zone_info(val->member, "zone added from catalog");