Commit 6fc51915 authored by Libor Peltan's avatar Libor Peltan

catalog: check catalog zone version

parent b7a9d25a
......@@ -601,7 +601,8 @@ and ACLs. Being a catalog zone is indicated by setting the option
:ref:`zone_catalog-template`. The difference is, that standard DNS
queries to catalog zone are answered with REFUSED, as if such zone
wouldn't exist, unless querying from an address with transfers enabled
by ACL. The name of the zone is arbitrary.
by ACL. The name of the zone is arbitrary. It's however required to
include version record ``version 0 IN TXT "2"``.
.. WARNING::
Don't choose the name for catalog zone below a name of any other
......
......@@ -715,19 +715,25 @@ static int commit_catalog(conf_t *conf, zone_update_t *update)
update->zone->flags |= ZONE_IS_CATALOG;
int ret = KNOT_EOK;
if ((update->flags & UPDATE_INCREMENTAL)) {
ret = knot_cat_update_from_zone(update->zone->catalog_upd, update->change.remove, true, update->zone->catalog);
ret = knot_cat_update_from_zone(update->zone->catalog_upd, update->change.remove,
true, false, update->zone->catalog);
if (ret == KNOT_EOK) {
ret = knot_cat_update_from_zone(update->zone->catalog_upd, update->change.add, false, NULL);
ret = knot_cat_update_from_zone(update->zone->catalog_upd,
update->change.add, false, false, NULL);
}
} else {
ret = knot_cat_update_del_all(update->zone->catalog_upd, update->zone->catalog, update->zone->name);
if (ret == KNOT_EOK) {
ret = knot_cat_update_from_zone(update->zone->catalog_upd, update->zone->contents, false, NULL);
ret = knot_cat_update_from_zone(update->zone->catalog_upd,
update->zone->contents, false, true, NULL);
}
}
if (ret == KNOT_EOK) {
kill(getpid(), SIGUSR1);
} else if (ret == KNOT_EZONEINVAL) {
log_zone_warning(update->zone->name, "catalog zone has none or invalid version");
ret = KNOT_EOK;
}
return ret;
}
......
......@@ -26,9 +26,33 @@
#include "knot/zone/contents.h"
#define CATALOG_VERSION "1.0"
#define CATALOG_ZONE_VERSION "2" // must be just one char long
const MDB_val knot_catalog_iter_prefix = { 1, "" };
static bool check_zone_version(const zone_contents_t *zone)
{
size_t zone_size = knot_dname_size(zone->apex->owner);
knot_dname_t sub[zone_size + 8];
memcpy(sub, "\x07""version", 8);
memcpy(sub + 8, zone->apex->owner, zone_size);
const zone_node_t *ver_node = zone_contents_find_node(zone, sub);
knot_rdataset_t *ver_rr = node_rdataset(ver_node, KNOT_RRTYPE_TXT);
if (ver_rr == NULL) {
return false;
}
knot_rdata_t *rd = ver_rr->rdata;
for (int i = 0; i < ver_rr->count; i++) {
if (rd->len == 2 && rd->data[1] == CATALOG_ZONE_VERSION[0]) {
return true;
}
rd = knot_rdataset_next(rd);
}
return false;
}
void knot_catalog_init(knot_catalog_t *cat, const char *path, size_t mapsize)
{
knot_lmdb_init(&cat->db, path, mapsize, 0, NULL);
......@@ -323,8 +347,12 @@ static int cat_update_add_node(zone_node_t *node, void *data)
}
int knot_cat_update_from_zone(knot_cat_update_t *u, struct zone_contents *zone,
bool remove, knot_catalog_t *check)
bool remove, bool check_ver, knot_catalog_t *check)
{
if (check_ver && !check_zone_version(zone)) {
return KNOT_EZONEINVAL;
}
size_t zone_size = knot_dname_size(zone->apex->owner);
knot_dname_t sub[zone_size + 6];
memcpy(sub, "\x05""zones", 6);
......
......@@ -104,7 +104,7 @@ knot_cat_upd_val_t *knot_cat_update_get(knot_cat_update_t *u, const knot_dname_t
struct zone_contents;
int knot_cat_update_from_zone(knot_cat_update_t *u, struct zone_contents *zone,
bool remove, knot_catalog_t *check);
bool remove, bool check_ver, knot_catalog_t *check);
int knot_cat_update_del_all(knot_cat_update_t *u, knot_catalog_t *cat, const knot_dname_t *zone);
......
......@@ -4,5 +4,6 @@ $TTL 0
@ SOA ns admin 1 25 25 80 600
NS ns
ns AAAA ::0
version TXT "2"
foo.bar.zones PTR cataloged1.
not.zones.in PTR not-cataloged1.
Markdown is supported
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