Skip to content
Snippets Groups Projects
Commit d427665e authored by Daniel Salzman's avatar Daniel Salzman Committed by Libor Peltan
Browse files

conf: add support for mixed references

parent 4338236d
Branches
Tags
1 merge request!1403Remote groups
......@@ -539,6 +539,70 @@ bool conf_val_equal(
return false;
}
conf_mix_iter_t conf_mix_iter(
conf_t *conf,
conf_val_t *mix_id)
{
assert(mix_id != NULL && mix_id->item != NULL);
assert(mix_id->item->type == YP_TREF &&
mix_id->item->var.r.ref != NULL &&
mix_id->item->var.r.grp_ref != NULL &&
mix_id->item->var.r.ref->var.g.id->type == YP_TSTR &&
mix_id->item->var.r.grp_ref->var.g.id->type == YP_TSTR);
conf_mix_iter_t iter = {
.conf = conf,
.mix_id = mix_id,
.id = mix_id
};
if (mix_id->code != KNOT_EOK) {
return iter;
}
iter.sub_id = conf_id_get_txn(conf, &conf->read_txn,
mix_id->item->var.r.grp_ref_name,
mix_id->item->var.r.ref_name,
mix_id);
if (iter.sub_id.code == KNOT_EOK) {
conf_val(&iter.sub_id);
iter.id = &iter.sub_id;
iter.nested = true;
}
return iter;
}
void conf_mix_iter_next(
conf_mix_iter_t *iter)
{
conf_val_next(iter->id);
if (iter->nested) {
if (iter->id->code == KNOT_EOK) {
return;
}
conf_val_next(iter->mix_id);
if (iter->mix_id->code != KNOT_EOK) {
return;
}
} else if (iter->id->code != KNOT_EOK){
return;
}
iter->sub_id = conf_id_get_txn(iter->conf, &iter->conf->read_txn,
iter->mix_id->item->var.r.grp_ref_name,
iter->mix_id->item->var.r.ref_name,
iter->mix_id);
if (iter->sub_id.code == KNOT_EOK) {
conf_val(&iter->sub_id);
iter->id = &iter->sub_id;
iter->nested = true;
} else {
iter->id = iter->mix_id;
iter->nested = false;
}
}
int64_t conf_int(
conf_val_t *val)
{
......
......@@ -48,6 +48,20 @@ typedef struct {
int code;
} conf_iter_t;
/*! Configuration iterator over mixed references (e.g. remote and remotes). */
typedef struct {
/*! Configuration context. */
conf_t *conf;
/*! Mixed references. */
conf_val_t *mix_id;
/*! Temporary nested references. */
conf_val_t sub_id;
/*! Current (possibly expanded) reference to use. */
conf_val_t *id;
/*! Nested references in use indication. */
bool nested;
} conf_mix_iter_t;
/*! Configuration module getter output. */
typedef struct {
/*! Module name. */
......@@ -407,6 +421,30 @@ bool conf_val_equal(
conf_val_t *val2
);
/*!
* Prepares a mixed reference iterator.
*
* The following access is through val->id.
*
* \param[in] conf Configuration.
* \param[in] mix_id First mixed reference.
*
* \return Mixed reference iterator.
*/
conf_mix_iter_t conf_mix_iter(
conf_t *conf,
conf_val_t *mix_id
);
/*!
* Increments the mixed iterator.
*
* \param[in] iter Mixed reference iterator.
*/
void conf_mix_iter_next(
conf_mix_iter_t *iter
);
/*!
* Gets the numeric value of the item.
*
......
......@@ -212,12 +212,27 @@ int check_ref(
knotd_conf_check_args_t *args)
{
const yp_item_t *ref = args->item->var.r.ref;
const yp_item_t *ref2 = args->item->var.r.grp_ref;
// Try to find a referenced block with the id.
if (!conf_rawid_exists_txn(args->extra->conf, args->extra->txn, ref->name,
args->data, args->data_len)) {
args->err_str = "invalid reference";
return KNOT_ENOENT;
bool found1 = false, found2 = false;
// Try to find the id in the first section.
found1 = conf_rawid_exists_txn(args->extra->conf, args->extra->txn,
ref->name, args->data, args->data_len);
if (ref2 != NULL) {
// Try to find the id in the second section if supported.
found2 = conf_rawid_exists_txn(args->extra->conf, args->extra->txn,
ref2->name, args->data, args->data_len);
}
if (found1 == found2) {
if (found1) {
args->err_str = "ambiguous reference";
return KNOT_ENOENT;
} else {
args->err_str = "invalid reference";
return KNOT_ENOENT;
}
}
return KNOT_EOK;
......
/* Copyright (C) 2019 CZ.NIC, z.s.p.o. <knot-dns@labs.nic.cz>
/* Copyright (C) 2021 CZ.NIC, z.s.p.o. <knot-dns@labs.nic.cz>
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
......@@ -43,15 +43,24 @@ static int set_ref_item(
return KNOT_EINVAL;
}
// Get reference category.
// Get referenced section.
const yp_name_t *ref_name = dst->var.r.ref_name;
const yp_item_t *ref = yp_schema_find(ref_name, NULL, schema);
if (ref == NULL) {
return KNOT_YP_EINVAL_ITEM;
}
dst->var.r.ref = ref;
// Get referenced group if supported.
const yp_name_t *grp_ref_name = dst->var.r.grp_ref_name;
if (grp_ref_name != NULL) {
const yp_item_t *grp_ref = yp_schema_find(grp_ref_name, NULL, schema);
if (grp_ref == NULL) {
return KNOT_YP_EINVAL_ITEM;
}
dst->var.r.grp_ref = grp_ref;
}
return KNOT_EOK;
}
......
/* Copyright (C) 2017 CZ.NIC, z.s.p.o. <knot-dns@labs.nic.cz>
/* Copyright (C) 2021 CZ.NIC, z.s.p.o. <knot-dns@labs.nic.cz>
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
......@@ -168,10 +168,14 @@ typedef union {
} d;
/*! Reference variables. */
struct {
/*! Referenced group name. */
/*! Referenced section name. */
yp_name_t const *ref_name;
/*! Referenced item (dynamic value). */
/*! Referenced group section name (optional). */
yp_name_t const *grp_ref_name;
/*! Referenced section item (dynamic value). */
yp_item_t const *ref;
/*! Referenced group section item (dynamic value). */
yp_item_t const *grp_ref;
} r;
/*! Group variables. */
struct {
......
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment