diff options
author | Marek Vavrusa <marek.vavrusa@nic.cz> | 2012-11-13 15:37:15 +0100 |
---|---|---|
committer | Marek Vavrusa <marek.vavrusa@nic.cz> | 2012-11-13 16:16:48 +0100 |
commit | 051e94325b3be83791d2bd0a757eb8b1701a0314 (patch) | |
tree | 4b56a20ca5142870dd654df2afdc4200ac925417 | |
parent | Fixed small resource leak on daemon quit. (diff) | |
download | knot-051e94325b3be83791d2bd0a757eb8b1701a0314.tar.xz knot-051e94325b3be83791d2bd0a757eb8b1701a0314.zip |
Implemented zone duplicate checks with AVL.
Not so slow with large number of zones now.
refs #2174, #2204
Conflicts:
src/knot/conf/conf.h
-rw-r--r-- | src/knot/conf/cf-parse.y | 16 | ||||
-rw-r--r-- | src/knot/conf/conf.c | 34 | ||||
-rw-r--r-- | src/knot/conf/conf.h | 4 |
3 files changed, 41 insertions, 13 deletions
diff --git a/src/knot/conf/cf-parse.y b/src/knot/conf/cf-parse.y index 033bd2e41..4f490b540 100644 --- a/src/knot/conf/cf-parse.y +++ b/src/knot/conf/cf-parse.y @@ -201,28 +201,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. */ diff --git a/src/knot/conf/conf.c b/src/knot/conf/conf.c index 0583c883e..d9d0a77bf 100644 --- a/src/knot/conf/conf.c +++ b/src/knot/conf/conf.c @@ -72,6 +72,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. * @@ -346,6 +370,7 @@ static int conf_fparser(conf_t *conf) int ret = KNOT_EOK; pthread_mutex_lock(&_parser_lock); + // { // Hook new configuration new_config = conf; @@ -367,6 +392,7 @@ static int conf_fparser(conf_t *conf) fclose(f); // } pthread_mutex_unlock(&_parser_lock); + return ret; } @@ -456,8 +482,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); @@ -475,7 +503,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); @@ -625,7 +655,9 @@ int conf_open(const char* path) conf_t *nconf = conf_new(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); diff --git a/src/knot/conf/conf.h b/src/knot/conf/conf.h index 391a85f18..9f2440e85 100644 --- a/src/knot/conf/conf.h +++ b/src/knot/conf/conf.h @@ -39,6 +39,7 @@ #include "common/lists.h" #include "common/log.h" #include "common/sockaddr.h" +#include "common/general-tree.h" /* Constants. */ #define CONFIG_DEFAULT_PORT 53 @@ -199,7 +200,8 @@ 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. */ + /* * Implementation specifics */ |