Commit 4d08662f authored by Daniel Salzman's avatar Daniel Salzman

Switch to the new zscanner API

parent 25f35912
......@@ -33,22 +33,23 @@
*
* \todo Currently, the function waits for the first DNSKEY record, and skips
* the others. We should be more strict and report other records as errors.
* However, there is currently no API to stop the scanner.
*/
static void parse_record(zs_scanner_t *scanner)
{
assert(scanner);
assert(scanner->data);
assert(scanner->process.data);
dnssec_key_t *key = scanner->data;
dnssec_key_t *key = scanner->process.data;
if (dnssec_key_get_dname(key) != NULL) {
// skip till the the parser finishes
// should report error
scanner->state = ZS_STATE_STOP;
return;
}
if (scanner->r_type != RTYPE_DNSKEY) {
// should report error
scanner->state = ZS_STATE_STOP;
return;
}
......@@ -73,16 +74,25 @@ int legacy_pubkey_parse(const char *filename, dnssec_key_t **key_ptr)
uint16_t cls = CLASS_IN;
uint32_t ttl = 0;
zs_scanner_t *scanner = zs_scanner_create(".", cls, ttl,
parse_record, NULL, key);
if (!scanner) {
zs_scanner_t *scanner = malloc(sizeof(zs_scanner_t));
if (scanner == NULL) {
dnssec_key_free(key);
return DNSSEC_ENOMEM;
}
if (zs_init(scanner, ".", cls, ttl) != 0 ||
zs_set_input_file(scanner, filename) != 0 ||
zs_set_processing(scanner, parse_record, NULL, key) != 0 ||
zs_parse_all(scanner) != 0) {
zs_deinit(scanner);
free(scanner);
dnssec_key_free(key);
return DNSSEC_NOT_FOUND;
}
zs_deinit(scanner);
free(scanner);
result = zs_scanner_parse_file(scanner, filename);
zs_scanner_free(scanner);
if (result != 0 || dnssec_key_get_dname(key) == NULL) {
if (dnssec_key_get_dname(key) == NULL) {
dnssec_key_free(key);
return DNSSEC_INVALID_PUBLIC_KEY;
}
......
......@@ -170,7 +170,7 @@ size_t estimator_trie_htable_memsize(hattrie_t *table)
void estimator_rrset_memsize_wrap(zs_scanner_t *scanner)
{
rrset_memsize(scanner->data, scanner);
rrset_memsize(scanner->process.data, scanner);
}
int estimator_free_trie_node(value_t *val, void *data)
......
......@@ -794,6 +794,12 @@ static int cmd_checkzone(cmd_args_t *args)
static int cmd_memstats(cmd_args_t *args)
{
zs_scanner_t *zs = malloc(sizeof(zs_scanner_t));
if (zs == NULL) {
log_error("not enough memory");
return 1;
}
/* Zone checking */
double total_size = 0;
......@@ -833,28 +839,29 @@ static int cmd_memstats(cmd_args_t *args)
conf_iter_finish(conf(), &iter);
break;
}
zs_scanner_t *zs = zs_scanner_create(zone_name,
KNOT_CLASS_IN, 3600,
estimator_rrset_memsize_wrap,
NULL, &est);
free(zone_name);
if (zs == NULL) {
if (zs_init(zs, zone_name, KNOT_CLASS_IN, 3600) != 0 ||
zs_set_processing(zs, estimator_rrset_memsize_wrap, NULL, &est) != 0) {
log_zone_error(conf_dname(&id), "failed to load zone");
zs_deinit(zs);
free(zone_name);
hattrie_free(est.node_table);
continue;
}
free(zone_name);
/* Do a parser run, but do not actually create the zone. */
char *zonefile = conf_zonefile(conf(), conf_dname(&id));
int ret = zs_scanner_parse_file(zs, zonefile);
free(zonefile);
if (ret != 0) {
if (zs_set_input_file(zs, zonefile) != 0 ||
zs_parse_all(zs) != 0) {
log_zone_error(conf_dname(&id), "failed to parse zone");
hattrie_apply_rev(est.node_table, estimator_free_trie_node, NULL);
hattrie_free(est.node_table);
zs_scanner_free(zs);
free(zonefile);
zs_deinit(zs);
continue;
}
free(zonefile);
zs_deinit(zs);
/* Only size of ahtables inside trie's nodes is missing. */
assert(est.htable_size == 0);
......@@ -872,10 +879,11 @@ static int cmd_memstats(cmd_args_t *args)
log_zone_info(conf_dname(&id), "%zu RRs, used memory estimation is %zu MB",
est.record_count, (size_t)zone_size);
zs_scanner_free(zs);
total_size += zone_size;
}
free(zs);
if (args->argc == 0) { // for all zones
log_info("estimated memory consumption for all zones is %zu MB",
(size_t)total_size);
......
......@@ -59,7 +59,7 @@ static void help(FILE *stream)
/* Global instance of RR scanner. */
static void parse_err(zs_scanner_t *s) {
fprintf(stderr, "failed to parse RDATA: %s\n", zs_strerror(s->error_code));
fprintf(stderr, "failed to parse RDATA: %s\n", zs_strerror(s->error.code));
}
static zs_scanner_t *g_scanner = NULL;
......@@ -99,16 +99,24 @@ int main(int argc, char *argv[])
argv += 3;
argc -= 3;
g_scanner = zs_scanner_create(".", KNOT_CLASS_IN, 0, NULL, parse_err, NULL);
g_scanner = malloc(sizeof(zs_scanner_t));
if (g_scanner == NULL) {
return EXIT_FAILURE;
}
if (zs_init(g_scanner, ".", KNOT_CLASS_IN, 0) != 0 ||
zs_set_processing(g_scanner, NULL, parse_err, NULL) != 0) {
zs_deinit(g_scanner);
free(g_scanner);
return EXIT_FAILURE;
}
/* Open cache for operations. */
struct cache *cache = cache_open(dbdir, 0, NULL);
if (cache == NULL) {
fprintf(stderr, "failed to open db '%s'\n", dbdir);
zs_scanner_free(g_scanner);
zs_deinit(g_scanner);
free(g_scanner);
return EXIT_FAILURE;
}
......@@ -147,7 +155,8 @@ int main(int argc, char *argv[])
}
cache_close(cache);
zs_scanner_free(g_scanner);
zs_deinit(g_scanner);
free(g_scanner);
if (!found) {
help(stderr);
......@@ -168,17 +177,17 @@ static int parse_rdata(struct entry *entry, const char *owner, const char *rrtyp
/* Synthetize RR line */
char *rr_line = sprintf_alloc("%s %u IN %s %s\n", owner, ttl, rrtype, rdata);
ret = zs_scanner_parse(g_scanner, rr_line, rr_line + strlen(rr_line), true);
if (zs_set_input_string(g_scanner, rr_line, strlen(rr_line)) != 0 ||
zs_parse_all(g_scanner) != 0) {
free(rr_line);
return KNOT_EPARSEFAIL;
}
free(rr_line);
/* Write parsed RDATA. */
if (ret == KNOT_EOK) {
knot_rdata_t rr[knot_rdata_array_size(g_scanner->r_data_length)];
knot_rdata_init(rr, g_scanner->r_data_length, g_scanner->r_data, ttl);
ret = knot_rdataset_add(&entry->data.rrs, rr, mm);
}
return ret;
knot_rdata_t rr[knot_rdata_array_size(g_scanner->r_data_length)];
knot_rdata_init(rr, g_scanner->r_data_length, g_scanner->r_data, ttl);
return knot_rdataset_add(&entry->data.rrs, rr, mm);
}
static int rosedb_add(struct cache *cache, MDB_txn *txn, int argc, char *argv[])
......
......@@ -41,19 +41,19 @@
static void process_error(zs_scanner_t *s)
{
zcreator_t *zc = s->data;
zcreator_t *zc = s->process.data;
const knot_dname_t *zname = zc->z->apex->owner;
ERROR(zname, "%s in zone, file '%s', line %"PRIu64" (%s)",
s->stop ? "fatal error" : "error",
s->error.fatal ? "fatal error" : "error",
s->file.name, s->line_counter,
zs_strerror(s->error_code));
zs_strerror(s->error.code));
}
static int add_rdata_to_rr(knot_rrset_t *rrset, const zs_scanner_t *scanner)
{
return knot_rrset_add_rdata(rrset, scanner->r_data, scanner->r_data_length,
scanner->r_ttl, NULL);
scanner->r_ttl, NULL);
}
static void log_ttl_error(const zone_contents_t *zone, const zone_node_t *node,
......@@ -142,11 +142,11 @@ int zcreator_step(zcreator_t *zc, const knot_rrset_t *rr)
}
/*! \brief Creates RR from parser input, passes it to handling function. */
static void scanner_process(zs_scanner_t *scanner)
static void process_data(zs_scanner_t *scanner)
{
zcreator_t *zc = scanner->data;
zcreator_t *zc = scanner->process.data;
if (zc->ret != KNOT_EOK) {
scanner->stop = true;
scanner->state = ZS_STATE_STOP;
return;
}
......@@ -190,6 +190,8 @@ int zonefile_open(zloader_t *loader, const char *source,
return KNOT_EINVAL;
}
memset(loader, 0, sizeof(zloader_t));
/* Check zone file. */
if (access(source, F_OK | R_OK) != 0) {
return KNOT_EACCES;
......@@ -215,19 +217,17 @@ int zonefile_open(zloader_t *loader, const char *source,
return KNOT_ENOMEM;
}
/* Create file loader. */
memset(loader, 0, sizeof(zloader_t));
loader->scanner = zs_scanner_create(origin_str, KNOT_CLASS_IN, 3600,
scanner_process, process_error,
zc);
if (loader->scanner == NULL) {
if (zs_init(&loader->scanner, origin_str, KNOT_CLASS_IN, 3600) != 0 ||
zs_set_input_file(&loader->scanner, source) != 0 ||
zs_set_processing(&loader->scanner, process_data, process_error, zc) != 0) {
zs_deinit(&loader->scanner);
free(origin_str);
free(zc);
return KNOT_ERROR;
}
free(origin_str);
loader->source = strdup(source);
loader->origin = origin_str;
loader->creator = zc;
loader->semantic_checks = semantic_checks;
......@@ -244,10 +244,10 @@ zone_contents_t *zonefile_load(zloader_t *loader)
const knot_dname_t *zname = zc->z->apex->owner;
assert(zc);
int ret = zs_scanner_parse_file(loader->scanner, loader->source);
if (ret != 0 && loader->scanner->error_counter == 0) {
int ret = zs_parse_all(&loader->scanner);
if (ret != 0 && loader->scanner.error.counter == 0) {
ERROR(zname, "failed to load zone, file '%s' (%s)",
loader->source, zs_strerror(loader->scanner->error_code));
loader->source, zs_strerror(loader->scanner.error.code));
goto fail;
}
......@@ -257,9 +257,9 @@ zone_contents_t *zonefile_load(zloader_t *loader)
goto fail;
}
if (loader->scanner->error_counter > 0) {
if (loader->scanner.error.counter > 0) {
ERROR(zname, "failed to load zone, file '%s', %"PRIu64" errors",
loader->source, loader->scanner->error_counter);
loader->source, loader->scanner.error.counter);
goto fail;
}
......@@ -271,11 +271,10 @@ zone_contents_t *zonefile_load(zloader_t *loader)
zone_node_t *first_nsec3_node = NULL;
zone_node_t *last_nsec3_node = NULL;
int kret = zone_contents_adjust_full(zc->z,
&first_nsec3_node, &last_nsec3_node);
if (kret != KNOT_EOK) {
ret = zone_contents_adjust_full(zc->z, &first_nsec3_node, &last_nsec3_node);
if (ret != KNOT_EOK) {
ERROR(zname, "failed to finalize zone contents (%s)",
knot_strerror(kret));
knot_strerror(ret));
goto fail;
}
......@@ -419,10 +418,8 @@ void zonefile_close(zloader_t *loader)
return;
}
zs_scanner_free(loader->scanner);
zs_deinit(&loader->scanner);
free(loader->source);
free(loader->origin);
free(loader->creator);
}
......
......@@ -47,11 +47,10 @@ typedef struct zcreator {
*/
typedef struct zloader {
char *source; /*!< Zone source file. */
char *origin; /*!< Zone's origin string. */
bool semantic_checks; /*!< Do semantic checks. */
err_handler_t *err_handler; /*!< Semantic checks error handler. */
zs_scanner_t *scanner; /*!< Zone scanner. */
zcreator_t *creator; /*!< Loader context. */
zs_scanner_t scanner; /*!< Zone scanner. */
} zloader_t;
/*!
......
......@@ -157,8 +157,9 @@ static bool dname_isvalid(const char *lp)
/* This is probably redundant, but should be a bit faster so let's keep it. */
static int parse_full_rr(zs_scanner_t *s, const char* lp)
{
if (zs_scanner_parse(s, lp, lp + strlen(lp), true) < 0) {
ERR("invalid record (%s)\n", zs_strerror(s->error_code));
if (zs_set_input_string(s, lp, strlen(lp)) != 0 ||
zs_parse_all(s) != 0) {
ERR("invalid record (%s)\n", zs_strerror(s->error.code));
return KNOT_EPARSEFAIL;
}
......@@ -294,8 +295,9 @@ static int parse_partial_rr(zs_scanner_t *s, const char *lp, unsigned flags)
if (rr == NULL) {
return KNOT_ENOMEM;
}
if (zs_scanner_parse(s, rr, rr + strlen(rr), true) < 0) {
ERR("invalid rdata (%s)\n", zs_strerror(s->error_code));
if (zs_set_input_string(s, rr, strlen(rr)) != 0 ||
zs_parse_all(s) != 0) {
ERR("invalid rdata (%s)\n", zs_strerror(s->error.code));
return KNOT_EPARSEFAIL;
}
free(rr);
......@@ -607,18 +609,18 @@ int cmd_add(const char* lp, knsupdate_params_t *params)
{
DBG("%s: lp='%s'\n", __func__, lp);
if (parse_full_rr(params->parser, lp) != KNOT_EOK) {
if (parse_full_rr(&params->parser, lp) != KNOT_EOK) {
return KNOT_EPARSEFAIL;
}
return rr_list_append(params->parser, &params->update_list, &params->mm);
return rr_list_append(&params->parser, &params->update_list, &params->mm);
}
int cmd_del(const char* lp, knsupdate_params_t *params)
{
DBG("%s: lp='%s'\n", __func__, lp);
zs_scanner_t *rrp = params->parser;
zs_scanner_t *rrp = &params->parser;
int ret = parse_partial_rr(rrp, lp, PARSE_NODEFAULT);
if (ret != KNOT_EOK) {
return ret;
......@@ -654,7 +656,7 @@ int cmd_class(const char* lp, knsupdate_params_t *params)
}
params->class_num = cls;
params->parser->default_class = params->class_num;
params->parser.default_class = params->class_num;
return KNOT_EOK;
}
......@@ -687,7 +689,7 @@ int cmd_nxdomain(const char *lp, knsupdate_params_t *params)
{
DBG("%s: lp='%s'\n", __func__, lp);
zs_scanner_t *s = params->parser;
zs_scanner_t *s = &params->parser;
int ret = parse_partial_rr(s, lp, PARSE_NODEFAULT | PARSE_NAMEONLY);
if (ret != KNOT_EOK) {
return ret;
......@@ -703,7 +705,7 @@ int cmd_yxdomain(const char *lp, knsupdate_params_t *params)
{
DBG("%s: lp='%s'\n", __func__, lp);
zs_scanner_t *s = params->parser;
zs_scanner_t *s = &params->parser;
int ret = parse_partial_rr(s, lp, PARSE_NODEFAULT | PARSE_NAMEONLY);
if (ret != KNOT_EOK) {
return ret;
......@@ -719,7 +721,7 @@ int cmd_nxrrset(const char *lp, knsupdate_params_t *params)
{
DBG("%s: lp='%s'\n", __func__, lp);
zs_scanner_t *s = params->parser;
zs_scanner_t *s = &params->parser;
int ret = parse_partial_rr(s, lp, PARSE_NOTTL);
if (ret != KNOT_EOK) {
return ret;
......@@ -741,7 +743,7 @@ int cmd_yxrrset(const char *lp, knsupdate_params_t *params)
{
DBG("%s: lp='%s'\n", __func__, lp);
zs_scanner_t *s = params->parser;
zs_scanner_t *s = &params->parser;
int ret = parse_partial_rr(s, lp, PARSE_NOTTL);
if (ret != KNOT_EOK) {
return ret;
......
......@@ -56,7 +56,7 @@ static const style_t DEFAULT_STYLE_NSUPDATE = {
};
static void parse_err(zs_scanner_t *s) {
ERR("failed to parse RR: %s\n", zs_strerror(s->error_code));
ERR("failed to parse RR: %s\n", zs_strerror(s->error.code));
}
static int parser_set_default(zs_scanner_t *s, const char *fmt, ...)
......@@ -73,7 +73,8 @@ static int parser_set_default(zs_scanner_t *s, const char *fmt, ...)
}
/* Buffer must contain newline */
if (zs_scanner_parse(s, buf, buf + n, true) < 0) {
if (zs_set_input_string(s, buf, n) != 0 ||
zs_parse_all(s) != 0) {
return KNOT_EPARSEFAIL;
}
......@@ -108,10 +109,11 @@ static int knsupdate_init(knsupdate_params_t *params)
params->zone = strdup(".");
/* Initialize RR parser. */
params->parser = zs_scanner_create(".", params->class_num, 0,
NULL, parse_err, NULL);
if (!params->parser)
if (zs_init(&params->parser, ".", params->class_num, 0) != 0 ||
zs_set_processing(&params->parser, NULL, parse_err, NULL) != 0) {
zs_deinit(&params->parser);
return KNOT_ENOMEM;
}
/* Default style. */
params->style = DEFAULT_STYLE_NSUPDATE;
......@@ -138,7 +140,7 @@ void knsupdate_clean(knsupdate_params_t *params)
srv_info_free(params->server);
srv_info_free(params->srcif);
free(params->zone);
zs_scanner_free(params->parser);
zs_deinit(&params->parser);
knot_pkt_free(&params->query);
knot_pkt_free(&params->answer);
knot_tsig_key_deinit(&params->tsig_key);
......@@ -282,7 +284,7 @@ int knsupdate_parse(knsupdate_params_t *params, int argc, char *argv[])
int knsupdate_set_ttl(knsupdate_params_t *params, const uint32_t ttl)
{
int ret = parser_set_default(params->parser, "$TTL %u\n", ttl);
int ret = parser_set_default(&params->parser, "$TTL %u\n", ttl);
if (ret == KNOT_EOK) {
params->ttl = ttl;
} else {
......@@ -295,7 +297,7 @@ int knsupdate_set_origin(knsupdate_params_t *params, const char *origin)
{
char *fqdn = get_fqd_name(origin);
int ret = parser_set_default(params->parser, "$ORIGIN %s\n", fqdn);
int ret = parser_set_default(&params->parser, "$ORIGIN %s\n", fqdn);
free(fqdn);
......
......@@ -67,7 +67,7 @@ typedef struct {
/*!< Current zone. */
char *zone;
/*!< RR parser. */
zs_scanner_t *parser;
zs_scanner_t parser;
/*!< Current packet. */
knot_pkt_t *query;
/*!< Current response. */
......
......@@ -38,7 +38,7 @@ knot_rrset_t rrset;
static void process_rr(zs_scanner_t *scanner)
{
// get zone to insert into
zone_contents_t *zc = scanner->data;
zone_contents_t *zc = scanner->process.data;
// create data
knot_rrset_init(&rrset, scanner->r_owner, scanner->r_type, scanner->r_class);
......@@ -73,11 +73,16 @@ int main(int argc, char *argv[])
zone_t zone = { .contents = zc, .name = apex };
// Parse initial node
zs_scanner_t *sc = zs_scanner_create("test.", KNOT_CLASS_IN, 3600,
process_rr, NULL, zc);
assert(sc);
ret = zs_scanner_parse(sc, zone_str, zone_str + strlen(zone_str), true);
assert(ret == 0);
zs_scanner_t sc;
if (zs_init(&sc, "test.", KNOT_CLASS_IN, 3600) != 0 ||
zs_set_processing(&sc, process_rr, NULL, zc) != 0) {
assert(0);
}
if (zs_set_input_string(&sc, zone_str, strlen(zone_str)) != 0 ||
zs_parse_all(&sc) != 0) {
assert(0);
}
// Initial node added, now just parse the RRs
to_zone = false;
......@@ -93,8 +98,10 @@ int main(int argc, char *argv[])
"incremental zone update: no change");
// Parse RR for addition and add it
ret = zs_scanner_parse(sc, add_str, add_str + strlen(add_str), true);
assert(ret == 0);
if (zs_set_input_string(&sc, add_str, strlen(add_str)) != 0 ||
zs_parse_all(&sc) != 0) {
assert(0);
}
ret = zone_update_add(&update, &rrset);
knot_rdataset_clear(&rrset.rrs, NULL);
ok(ret == KNOT_EOK, "incremental zone update: addition");
......@@ -105,8 +112,10 @@ int main(int argc, char *argv[])
"incremental zone update: add change");
// Parse RR for removal and remove it
ret = zs_scanner_parse(sc, del_str, del_str + strlen(del_str), true);
assert(ret == 0);
if (zs_set_input_string(&sc, del_str, strlen(del_str)) != 0 ||
zs_parse_all(&sc) != 0) {
assert(0);
}
ret = zone_update_remove(&update, &rrset);
knot_rdataset_clear(&rrset.rrs, NULL);
ok(ret == KNOT_EOK, "incremental zone update: removal");
......@@ -119,7 +128,7 @@ int main(int argc, char *argv[])
zone_update_clear(&update);
ok(update.zone == NULL && changeset_empty(&update.change), "incremental zone update: cleanup");
zs_scanner_free(sc);
zs_deinit(&sc);
zone_contents_deep_free(&zc);
knot_dname_free(&apex, NULL);
......
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