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

catalog: check catalog zone version

parent 2a27c502
Branches
Tags
1 merge request!1132Zone catalog implemeted
......@@ -600,7 +600,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 a catalog zone are answered with REFUSED as if such a zone
wouldn't exist, unless querying from an address with transfers enabled
by ACL. The name of the catalog zone is arbitrary.
by ACL. The name of the catalog zone is arbitrary. It's however required to
include version record ``version 0 IN TXT "2"``.
It's possible to configure more catalog zones.
.. WARNING::
......
......@@ -717,19 +717,24 @@ static int update_catalog(conf_t *conf, zone_update_t *update)
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);
if (kill(getpid(), SIGUSR1) != 0) {
ret = knot_map_errno();
}
}
return ret;
......@@ -874,9 +879,12 @@ int zone_update_commit(conf_t *conf, zone_update_t *update)
zone_contents_t *old_contents;
old_contents = zone_switch_contents(update->zone, update->new_cont);
ret = commit_catalog(conf, update);
if (ret != KNOT_EOK) {
log_zone_warning(update->zone->name, "catalog zone not fully populated (%s)", knot_strerror(ret));
ret = update_catalog(conf, update);
if (ret == KNOT_EZONEINVAL) {
log_zone_warning(update->zone->name, "invalid catalog zone version");
} else if (ret != KNOT_EOK) {
log_zone_warning(update->zone->name, "catalog zone not fully populated (%s)",
knot_strerror(ret));
}
if (update->flags & (UPDATE_INCREMENTAL | UPDATE_HYBRID)) {
......
......@@ -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);
......@@ -325,8 +349,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);
......
......@@ -101,7 +101,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.
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