Skip to content
Snippets Groups Projects
Commit d20fccce authored by Marek Vavrusa's avatar Marek Vavrusa
Browse files

Implemented zone duplicate checks with AVL.

Not so slow with large number of zones now.

refs #2174, #2204
parent d2f1ac95
No related branches found
No related tags found
No related merge requests found
......@@ -207,28 +207,22 @@ static void conf_zone_start(void *scanner, char *name) {
cf_error(scanner, "invalid zone origin");
} else {
/* Check for duplicates. */
conf_zone_t* pz = 0;
WALK_LIST (pz, new_config->zones) {
knot_dname_t *tn = knot_dname_new_from_str(pz->name, strlen(pz->name), 0);
if (knot_dname_compare(tn, dn) == 0) {
snprintf(buf, sizeof(buf), "zone '%s' is already present, refusing to duplicate", pz->name);
if (gen_tree_find(new_config->zone_tree, dn) != NULL) {
snprintf(buf, sizeof(buf), "zone '%s' is already present, "
"refusing to duplicate", this_zone->name);
knot_dname_free(&dn);
knot_dname_free(&tn);
free(this_zone->name);
this_zone->name = NULL;
/* Must not free, some versions of flex might continue after error and segfault.
* free(this_zone);
* this_zone = NULL;
* free(this_zone); this_zone = NULL;
*/
cf_error(scanner, buf);
return;
}
knot_dname_free(&tn);
}
/* Directly discard dname, won't be needed. */
knot_dname_free(&dn);
add_tail(&new_config->zones, &this_zone->n);
gen_tree_add(new_config->zone_tree, dn, NULL); /* Will hold reference. */
++new_config->zones_count;
/* Initialize ACL lists. */
......
......@@ -73,6 +73,30 @@ void cf_error(void *scanner, const char *msg)
_parser_res = KNOT_EPARSEFAIL;
}
static int conf_ztree_compare(void *p1, void *p2)
{
return knot_dname_compare((knot_dname_t*)p1, (knot_dname_t*)p2);
}
static void conf_ztree_free(void *node, void *data)
{
UNUSED(data);
knot_dname_t *zname = (knot_dname_t*)node;
knot_dname_free(&zname);
}
static void conf_parse_begin(conf_t *conf)
{
conf->zone_tree = gen_tree_new(conf_ztree_compare);
}
static void conf_parse_end(conf_t *conf)
{
if (conf->zone_tree) {
gen_tree_destroy(&conf->zone_tree, conf_ztree_free, NULL);
}
}
/*!
* \brief Call config hooks that need updating.
*
......@@ -383,6 +407,7 @@ static int conf_fparser(conf_t *conf)
int ret = KNOT_EOK;
pthread_mutex_lock(&_parser_lock);
// {
// Hook new configuration
new_config = conf;
......@@ -404,6 +429,7 @@ static int conf_fparser(conf_t *conf)
fclose(f);
// }
pthread_mutex_unlock(&_parser_lock);
return ret;
}
......@@ -502,8 +528,10 @@ int conf_add_hook(conf_t * conf, int sections,
int conf_parse(conf_t *conf)
{
/* Parse file. */
conf_parse_begin(conf);
int ret = conf_fparser(conf);
conf_parse_end(conf);
/* Postprocess config. */
if (ret == 0) {
ret = conf_process(conf);
......@@ -521,7 +549,9 @@ int conf_parse(conf_t *conf)
int conf_parse_str(conf_t *conf, const char* src)
{
/* Parse config from string. */
conf_parse_begin(conf);
int ret = conf_strparser(conf, src);
conf_parse_end(conf);
/* Postprocess config. */
conf_process(conf);
......@@ -690,7 +720,9 @@ int conf_open(const char* path)
}
/* Parse config. */
conf_parse_begin(nconf);
int ret = conf_fparser(nconf);
conf_parse_end(nconf);
if (ret == KNOT_EOK) {
/* Postprocess config. */
ret = conf_process(nconf);
......
......@@ -40,6 +40,7 @@
#include "common/log.h"
#include "common/acl.h"
#include "common/sockaddr.h"
#include "common/general-tree.h"
/* Constants. */
#define CONFIG_DEFAULT_PORT 53
......@@ -216,6 +217,7 @@ typedef struct conf_t {
int dbsync_timeout; /*!< Default interval between syncing to zonefile.*/
size_t ixfr_fslimit; /*!< File size limit for IXFR journal. */
int build_diffs; /*!< Calculate differences from changes. */
general_tree_t *zone_tree; /*!< Zone tree for duplicate checking. */
/*
* Remote control interface.
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment