diff --git a/Doxyfile b/Doxyfile index 54f6145e40b275f6757743306d1c1a67e3a80256..b0163856ae2cd3258b547ac4947dfc73d15d6eba 100644 --- a/Doxyfile +++ b/Doxyfile @@ -595,7 +595,6 @@ INPUT = src/common \ src/libknot \ src/common \ src/knot \ - src/zcompile \ src/zscanner \ src/utils \ Doxy.page.h diff --git a/Knot.files b/Knot.files index c74974e80ae149cfec0077ad5de2af3977cbbb08..56517c0314aba41d72beee8d7e8fd1c8d1ff0e4e 100644 --- a/Knot.files +++ b/Knot.files @@ -57,8 +57,6 @@ src/libknot/zone/zone-contents.c src/libknot/zone/zone-contents.h src/libknot/zone/zone-tree.h src/libknot/zone/zone-tree.c -src/libknot/zone/dname-table.h -src/libknot/zone/dname-table.c src/Makefile.am src/common/hattrie src/common/hattrie/ahtable.c @@ -124,16 +122,6 @@ src/common/fdset_kqueue.h src/common/fdset_kqueue.c src/common/log.c src/common/log.h -src/zcompile/parser-descriptor.h -src/zcompile/parser-descriptor.c -src/zcompile/parser-util.h -src/zcompile/parser-util.c -src/zcompile/zcompile.c -src/zcompile/zcompile.h -src/zcompile/zparser.y -src/zcompile/zlexer.l -src/zcompile/zcompile-error.h -src/zcompile/zcompile_main.c src/knot/common.h src/knot/main.c src/knot/ctl/knotc_main.c @@ -173,15 +161,10 @@ src/knot/conf/conf.c src/knot/conf/conf.h src/knot/conf/logconf.c src/knot/conf/logconf.h -src/knot/zone/zone-dump.c -src/knot/zone/zone-dump.h src/knot/zone/zone-load.c src/knot/zone/zone-load.h src/knot/zone/zone-dump-text.h src/knot/zone/zone-dump-text.c -src/zcompile/tests/unittests_zp_main.c -src/zcompile/tests/zcompile_tests.c -src/zcompile/zcompile-error.c src/tests/unittests_main.c src/tests/common/acl_tests.c src/tests/common/acl_tests.h @@ -206,55 +189,8 @@ src/tests/knot/journal_tests.h src/tests/knot/server_tests.c src/tests/knot/server_tests.h src/tests/libknot/unittests_libknot.c -src/tests/libknot/libknot/dname_tests.c -src/tests/libknot/libknot/dname_tests.h -src/tests/libknot/libknot/edns_tests.c -src/tests/libknot/libknot/edns_tests.h -src/tests/libknot/libknot/node_tests.c -src/tests/libknot/libknot/node_tests.h -src/tests/libknot/libknot/rdata_tests.c -src/tests/libknot/libknot/rdata_tests.h -src/tests/libknot/libknot/response_tests.c -src/tests/libknot/libknot/response_tests.h src/tests/libknot/libknot/rrset_tests.c src/tests/libknot/libknot/rrset_tests.h -src/tests/libknot/libknot/zone_tests.c -src/tests/libknot/libknot/zone_tests.h -src/tests/libknot/libknot/zonedb_tests.c -src/tests/libknot/libknot/zonedb_tests.h -src/tests/libknot/libknot/cuckoo_tests.c -src/tests/libknot/libknot/cuckoo_tests.h -src/tests/libknot/libknot/dname_table_tests.h -src/tests/libknot/libknot/dname_table_tests.c -src/tests/libknot/libknot/packet_tests.c -src/tests/libknot/libknot/packet_tests.h -src/tests/libknot/libknot/query_tests.c -src/tests/libknot/libknot/query_tests.h -src/tests/libknot/libknot/nsec3_tests.c -src/tests/libknot/libknot/nsec3_tests.h -src/tests/libknot/realdata/unittests_libknot_realdata.c -src/tests/libknot/realdata/libknot/packet_tests_realdata.c -src/tests/libknot/realdata/libknot/packet_tests_realdata.h -src/tests/libknot/realdata/libknot/dname_tests_realdata.c -src/tests/libknot/realdata/libknot/dname_tests_realdata.h -src/tests/libknot/realdata/libknot/edns_tests_realdata.c -src/tests/libknot/realdata/libknot/edns_tests_realdata.h -src/tests/libknot/realdata/libknot/node_tests_realdata.c -src/tests/libknot/realdata/libknot/node_tests_realdata.h -src/tests/libknot/realdata/libknot/rdata_tests_realdata.c -src/tests/libknot/realdata/libknot/rdata_tests_realdata.h -src/tests/libknot/realdata/libknot/response_tests_realdata.c -src/tests/libknot/realdata/libknot/response_tests_realdata.h -src/tests/libknot/realdata/libknot/rrset_tests_realdata.c -src/tests/libknot/realdata/libknot/rrset_tests_realdata.h -src/tests/libknot/realdata/libknot/zone_tests_realdata.c -src/tests/libknot/realdata/libknot/zone_tests_realdata.h -src/tests/libknot/realdata/libknot/zonedb_tests_realdata.c -src/tests/libknot/realdata/libknot/zonedb_tests_realdata.h -src/tests/libknot/realdata/libknot_tests_loader_realdata.c -src/tests/libknot/realdata/libknot_tests_loader_realdata.h -src/tests/libknot/libknot/zone_tree_tests.c -src/tests/libknot/libknot/zone_tree_tests.h samples/Makefile.am src/libknot/tsig.h src/libknot/tsig.c diff --git a/src/Makefile.am b/src/Makefile.am index a05def8eb0ed7eac93c5df7866c6c242b32efda1..80c4557e24e4f5f2f6f08822d53aefdefb104e08 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -89,12 +89,8 @@ libknot_la_SOURCES = \ libknot/zone/zonedb.c \ libknot/zone/zonedb.h \ libknot/zone/node.c \ - libknot/zone/dname-table.h \ - libknot/zone/dname-table.c \ libknot/zone/zone-diff.h \ libknot/zone/zone-diff.c \ - zcompile/zcompile.h \ - zcompile/zcompile.c \ libknot/hash/hash-functions.c \ libknot/hash/cuckoo-hash-table.c \ libknot/hash/universal-system.c \ @@ -225,6 +221,8 @@ libknotd_la_SOURCES = \ knot/server/zones.h \ knot/zone/semantic-check.c \ knot/zone/semantic-check.h \ + knot/zone/zone-load.h \ + knot/zone/zone-load.c \ knot/server/server.h zscanner/scanner.c: zscanner/scanner.rl zscanner/scanner_body.rl diff --git a/src/knot/server/journal.c b/src/knot/server/journal.c index faa911398acf395ec47e8b0be621415464a34eb9..f6f6072266153ad964fc90ce7d2fc6a23b52b567 100644 --- a/src/knot/server/journal.c +++ b/src/knot/server/journal.c @@ -24,8 +24,8 @@ #include <sys/mman.h> #include "common/crc.h" +#include "common.h" #include "knot/other/debug.h" -#include "knot/zone/zone-dump.h" #include "journal.h" /*! \brief Infinite file size limit. */ diff --git a/src/knot/server/journal.h b/src/knot/server/journal.h index 94628095e8f4edfdaa772e320704458f1aae533f..cd7377b54fb5e75673a391ad07c9a1e23a2ecb3c 100644 --- a/src/knot/server/journal.h +++ b/src/knot/server/journal.h @@ -44,6 +44,8 @@ #include <stdint.h> #include <fcntl.h> +#include "knot/zone/zone-load.h" + /*! * \brief Journal entry flags. */ diff --git a/src/knot/server/zones.c b/src/knot/server/zones.c index 4f7ecfb46ffe60e1d157fe766e733c80add173c2..4dfd9063265eaadc69de664ffd510ea0b23cbd9f 100644 --- a/src/knot/server/zones.c +++ b/src/knot/server/zones.c @@ -33,7 +33,6 @@ #include "knot/server/xfr-handler.h" #include "libknot/updates/xfr-in.h" #include "knot/server/zones.h" -#include "knot/zone/zone-dump.h" #include "libknot/nameserver/name-server.h" #include "libknot/updates/changesets.h" #include "libknot/tsig-op.h" @@ -41,7 +40,6 @@ #include "libknot/packet/response.h" #include "libknot/zone/zone-diff.h" #include "libknot/updates/ddns.h" -#include "zcompile/zcompile.h" static const size_t XFRIN_CHANGESET_BINARY_SIZE = 100; static const size_t XFRIN_CHANGESET_BINARY_STEP = 100; @@ -875,38 +873,19 @@ static int zones_load_zone(knot_zone_t **dst, const char *zone_name, } *dst = NULL; - /* Duplicate zone name. */ - size_t zlen = strlen(zone_name); - char *zname = NULL; - if (zlen > 0) { - if ((zname = strdup(zone_name)) == NULL) { - return KNOT_ENOMEM; - } - } else { - return KNOT_EINVAL; - } - zname[zlen - 1] = '\0'; /* Trim last dot */ - - /* Check if the compiled file still exists. */ - struct stat st; - if (stat(source, &st) != 0) { - char reason[256] = {0}; - strerror_r(errno, reason, sizeof(reason)); - log_server_warning("Failed to open zone file '%s' (%s).\n", - zname, reason); - free(zname); - return KNOT_EZONEINVAL; - } - - int ret = zone_read(zone_name, source, 0, dst); - /* Attempt to open compiled zone for loading. */ + zloader_t *zl = NULL; + int ret = knot_zload_open(&zl, source, zone_name, 0); if (ret != KNOT_EOK) { - log_server_warning("Failed to parser zone file '%s' (%s).\n", - source, knot_strerror(ret)); - free(zname); return ret; } + *dst = knot_zload_load(zl); + if (*dst == NULL) { + log_zone_error("Zone %s could not be loaded.\n", zone_name); + knot_zload_close(zl); + return KNOT_ERROR; + } + //TODO, change to zone parsing // switch(knot_zload_open(&zl, filename)) { // case KNOT_EOK: @@ -966,7 +945,7 @@ static int zones_load_zone(knot_zone_t **dst, const char *zone_name, /* Check if loaded origin matches. */ const knot_dname_t *dname = knot_zone_name(*dst); knot_dname_t *dname_req = NULL; - dname_req = knot_dname_new_from_str(zone_name, zlen, 0); + dname_req = knot_dname_new_from_str(zone_name, strlen(zone_name), 0); if (knot_dname_compare(dname, dname_req) != 0) { log_server_error("Origin of the zone db file is " "different than '%s'\n", @@ -975,18 +954,17 @@ static int zones_load_zone(knot_zone_t **dst, const char *zone_name, ret = KNOT_EZONEINVAL; } else { /* Save the timestamp from the zone db file. */ - if (stat(source, &st) < 0) { // TODO REVIEW MV - dbg_zones("zones: failed to stat() zone db, " - "something is seriously wrong\n"); - knot_zone_deep_free(dst, 0); - ret = KNOT_EZONEINVAL; - } else { - knot_zone_set_version(*dst, st.st_mtime); - } +// if (stat(source, &st) < 0) { // TODO REVIEW MV +// dbg_zones("zones: failed to stat() zone db, " +// "something is seriously wrong\n"); +// knot_zone_deep_free(dst, 0); +// ret = KNOT_EZONEINVAL; +// } else { +// knot_zone_set_version(*dst, st.st_mtime); +// } } knot_dname_free(&dname_req); -// knot_zload_close(zl); - free(zname); + knot_zload_close(zl); return ret; } diff --git a/src/knot/zone/semantic-check.c b/src/knot/zone/semantic-check.c index 32b21325ca782e72ff8347bb3601249bcfad3a4c..09d223528b81ceacb897c04dd8b911efa118a762 100644 --- a/src/knot/zone/semantic-check.c +++ b/src/knot/zone/semantic-check.c @@ -3,12 +3,12 @@ #include <arpa/inet.h> #include "knot/common.h" -#include "knot/zone/zone-dump.h" #include "knot/other/debug.h" #include "libknot/libknot.h" #include "common/base32hex.h" #include "common/crc.h" #include "common/descriptor_new.h" +#include "common/mempattern.h" #include "semantic-check.h" diff --git a/src/knot/zone/zone-dump.c b/src/knot/zone/zone-dump.c deleted file mode 100644 index c24afb3724ef183f61f257a083e25ef7194ea2b8..0000000000000000000000000000000000000000 --- a/src/knot/zone/zone-dump.c +++ /dev/null @@ -1,1119 +0,0 @@ -/* Copyright (C) 2011 CZ.NIC, z.s.p.o. <knot-dns@labs.nic.cz> - - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see <http://www.gnu.org/licenses/>. - */ - -#include <config.h> -#include <stdio.h> -#include <stdint.h> -#include <assert.h> -#include <netinet/in.h> -#include <unistd.h> -#include <fcntl.h> -#include <sys/stat.h> - -#include "libknot/common.h" -#include "knot/zone/zone-dump.h" -#include "libknot/libknot.h" -#include "common/crc.h" -#include "knot/other/debug.h" -#include "common/skip-list.h" -#include "semantic-check.h" - -/*! \note Contents of a dump file: - * MAGIC(knotxx) db_filename dname_table - * NUMBER_OF_NORMAL_NODES NUMBER_OF_NSEC3_NODES - * [normal_nodes] [nsec3_nodes] - * -------------------------------------------- - * dname_table is dumped as follows: - * NUMBER_OF_DNAMES [dname_wire_length dname_wire label_count dname_labels ID] - * node has following format: - * owner_id - * node_flags node_rrset_count [node_rrsets] - * rrset has following format: - * rrset_type rrset_class rrset_ttl rrset_rdata_count rrset_rrsig_count - * [rrset_rdata] [rrset_rrsigs] - * rdata can contain either dname ID, - * or raw data stored like this: data_len [data] - */ - -static const size_t BUFFER_SIZE = 4096; - -static inline int write_to_file_crc(const void *src, - size_t size, size_t n, int fd, - crc_t *crc) -{ - if (src == NULL || fd < 0) { - return KNOT_EINVAL; - } - ssize_t rc = write(fd, src, size * n); - if (rc != size * n) { - fprintf(stderr, "write: invalid write %zd (expected %zu)\n", rc, - n); - } - - if (size * n > 0) { - *crc = - crc_update(*crc, (unsigned char *)src, - size * n); - } - - return rc == size * n; -} - -static inline int write_to_stream(const void *src, - size_t size, size_t n, - uint8_t *stream, - size_t max_size, - size_t *written_bytes) -{ - if (src == NULL || stream == NULL || written_bytes == NULL) { - return KNOT_EINVAL; - } - - /* Check that the stream boundary will not be crossed. */ - if (*written_bytes + (size * n) > max_size) { - /* Buffer overflown. */ - dbg_zdump("zdump: write_to_stream: Cannot write to stream, no " - "space left.\n"); - return KNOT_ERANGE; - } - - /* Do the actual write. */ - memcpy(stream + *written_bytes, src, size * n); - /* Expand size. */ - *written_bytes += (size * n); - - return KNOT_EOK; -} - -static int write_wrapper(const void *src, - size_t size, size_t n, int fd, - uint8_t *stream, size_t max_size, - size_t *written_bytes, crc_t *crc) -{ - if (src == NULL) { - dbg_zdump("zdump: write_wrapper: NULL source.\n"); - return KNOT_EINVAL; - } - - dbg_zdump_detail("zdump: write_wrapper: Writing %zu bytes to fd: %d.\n", - size * n, fd); - - if (fd < 0) { - assert(stream && written_bytes); - assert(crc == NULL); - /*!< \todo To comply with calling convention of write_wrapper, - * we have to lose the error. */ - int ret = write_to_stream(src, size, n, stream, max_size, - written_bytes); - if (ret != KNOT_EOK) { - dbg_zdump("zdump: write_wrapper: Could not write to " - "stream. Reason: %s.\n", knot_strerror(ret)); - /* Intentional! */ - return 0; - } else { - /* Intentional! */ - return 1; - } - } else { - /* Write to buffer first, if possible. */ - if (*written_bytes + (size * n) < BUFFER_SIZE) { - dbg_zdump_detail("zdump: write_wrapper: Fits to " - "buffer. Remaining=%lu.\n", - BUFFER_SIZE - *written_bytes); - int ret = write_to_stream(src, size, n, - stream, - BUFFER_SIZE, written_bytes); - if (ret != KNOT_EOK) { - dbg_zdump("zdump: write_wrapper: " - "Could not write to " - "stream. Reason: %s.\n", - knot_strerror(ret)); - /* Intentional! */ - return 0; - } else { - /* Intentional! */ - return 1; - } - } else { - /* Fill remainder of buffer. */ - size_t remainder = BUFFER_SIZE - *written_bytes; - dbg_zdump_detail("zdump: write_wrapper: " - "Flushing buffer, " - "appending %zu bytes.\n", remainder); - int ret = write_to_stream(src, 1, - remainder, - stream, - BUFFER_SIZE, - written_bytes); - if (ret != KNOT_EOK) { - dbg_zdump("zdump: write_wrapper: " - "Could not write to stream: %s\n", - knot_strerror(ret)); - // failure - return 0; - } - - assert(*written_bytes == BUFFER_SIZE); - - /* Buffer is filled, write to the actual file. */ - ret = write_to_file_crc(stream, 1, - *written_bytes, fd, crc); - if (!ret) { - dbg_zdump("zdump: write_wrapper: " - "Could not write to file.\n"); - // failure - return 0; - } - - /* Reset counter. */ - *written_bytes = 0; - - /* Write remaining data to new buffer. */ - if ((size * n) - remainder > BUFFER_SIZE) { - /* Write through. */ - dbg_zdump("zdump: Attempting buffer write " - "through. Total: %zu bytes.\n", - (size * n) - remainder); - ret = write_to_file_crc(src + remainder, 1, - (size * n) - remainder, - fd, crc); - if (!ret) { - dbg_zdump("zdump: write_wrapper: " - "Could not write rest of buffer to " - "file: %s.\n", knot_strerror(ret)); - // failure - return 0; - } - } else { - /* Normal buffer filling. */ - ret = write_to_stream(src + remainder, - 1, (size * n) - remainder, - stream, BUFFER_SIZE, - written_bytes); - if (ret != KNOT_EOK) { - dbg_zdump("zdump: write_wrapper: " - "Could not write rest of buffer to " - "stream: %s.\n", knot_strerror(ret)); - // failure - return 0; - } - } - - // OK - return 1; - } - } -} - -/*! - * \brief Dumps dname labels in binary format to given file. - * - * \param dname Dname whose labels are to be dumped. - * \param f Output file. - */ -static int knot_labels_dump_binary(const knot_dname_t *dname, int fd, - uint8_t *stream, size_t max_size, - size_t *written_bytes, crc_t *crc) -{ - if (dname == NULL) { - dbg_zdump("zdump: dump_labels: NULL dname.\n"); - return KNOT_EINVAL; - } - - uint16_t label_count = dname->label_count; - if (!write_wrapper(&label_count, sizeof(label_count), 1, fd, stream, - max_size, written_bytes, crc)) { - dbg_zdump("zdump: dump_labels: Could not write label count.\n"); - return KNOT_ERROR; - } - - if (!write_wrapper(dname->labels, sizeof(uint8_t), dname->label_count, - fd, stream, max_size, written_bytes, crc)) { - dbg_zdump("zdump: dump_labels: Could not write labels.\n"); - return KNOT_ERROR; - } - - dbg_zdump_verb("zdump: dump_labels: Labels dumped successfully.\n"); - return KNOT_EOK; -} - -/*! - * \brief Dumps dname in binary format to given file. - * - * \param dname Dname to be dumped. - * \param f Output file. - */ -static int knot_dname_dump_binary(const knot_dname_t *dname, int fd, - uint8_t *stream, size_t max_size, - size_t *written_bytes, - crc_t *crc) -{ - if (dname == NULL) { - dbg_zdump("zdump: dump_dname: NULL dname.\n"); - return KNOT_EINVAL; - } - - /*! \todo too big */ - uint32_t dname_size = dname->size; - if (!write_wrapper(&dname_size, sizeof(dname_size), 1, fd, stream, - max_size, written_bytes, crc)) { - dbg_zdump("zdump: dump_dname: Cannot write dname size.\n"); - return KNOT_ERROR; - } - - if (!write_wrapper(dname->name, sizeof(uint8_t), dname->size, fd, - stream, max_size, written_bytes, crc)) { - dbg_zdump("zdump: dump_dname: Cannot write dname name.\n"); - return KNOT_ERROR; - } - - dbg_zdump_verb("zdump: dump_dname: Dname dumped successfully.\n"); - return knot_labels_dump_binary(dname, fd, stream, max_size, - written_bytes, crc); -} - -/*!< \todo #1684 some global variable indicating error! */ -static int dump_dname_with_id(const knot_dname_t *dname, int fd, - uint8_t *stream, size_t max_size, - size_t *written_bytes, crc_t *crc) -{ - if (dname == NULL) { - dbg_zdump("zdump: dump_dname: NULL dname.\n"); - return KNOT_EINVAL; - } - - uint32_t id = dname->id; - if (!write_wrapper(&id, sizeof(id), 1, fd, stream, max_size, - written_bytes, crc)) { - dbg_zdump("zdump: dump_dname: Cannot write ID.\n"); - return KNOT_ERROR; - } - return knot_dname_dump_binary(dname, fd, stream, max_size, - written_bytes, crc); -} - -/*! - * \brief Dumps given rdata in binary format to given file. - * - * \param rdata Rdata to be dumped. - * \param type Type of rdata. - * \param data Arguments to be propagated. - */ -static int knot_rdata_dump_binary(knot_rdata_t *rdata, - uint32_t type, int fd, int use_ids, - uint8_t *stream, size_t max_size, - size_t *written_bytes, - crc_t *crc) -{ - if (rdata == NULL) { - dbg_zdump("zdump: dump_rdata: NULL rdata.\n"); - return KNOT_EINVAL; - } - knot_rrtype_descriptor_t *desc = - knot_rrtype_descriptor_by_type(type); - assert(desc != NULL); - - if (desc->fixed_items) { - assert(desc->length == rdata->count); - } - - /* Write rdata count. */ - if (!write_wrapper(&(rdata->count), - sizeof(rdata->count), 1, fd, stream, max_size, - written_bytes, crc)) { - dbg_zdump("zdump: dump_rdata: Could not write RDATA count.\n"); - return KNOT_ERROR; - } - - for (int i = 0; i < rdata->count; i++) { - dbg_zdump_detail("zdump: dump_rdata: Dumping item nr: %d\n", i); - if (desc->wireformat[i] == KNOT_RDATA_WF_COMPRESSED_DNAME || - desc->wireformat[i] == KNOT_RDATA_WF_UNCOMPRESSED_DNAME || - desc->wireformat[i] == KNOT_RDATA_WF_LITERAL_DNAME ) { - /* some temp variables - this is way too long */ - assert(rdata->items[i].dname != NULL); - knot_dname_t *wildcard = NULL; - - if (rdata->items[i].dname->node != NULL && - rdata->items[i].dname->node->owner != - rdata->items[i].dname) { - wildcard = rdata->items[i].dname->node->owner; - } - - dbg_zdump_detail("zdump: dump_rdata: " - "Writing dname: %s.\n", - knot_dname_to_str( - rdata->items[i].dname)); - - if (use_ids) { - /* Write ID. */ - assert(rdata->items[i].dname->id != 0); - - uint32_t id = rdata->items[i].dname->id; - if (!write_wrapper(&id, - sizeof(id), - 1, fd, stream, max_size, - written_bytes, crc)) { - dbg_zdump("zdump: dump_rdata: Cannot " - "write dname ID.\n"); - return KNOT_ERROR; - } - } else { - int ret = dump_dname_with_id( - rdata->items[i].dname, - fd, stream, - max_size, - written_bytes, - crc); - if (ret != KNOT_EOK) { - dbg_zdump("zdump: dump_rdata: Cannot " - "dump dname.\n"); - return ret; - } - } - - /* Write in the zone bit */ - /*! \todo Does not have to be so complex. - * Create extra variable. */ - if (rdata->items[i].dname->node != NULL && !wildcard) { - dbg_zdump("zdump: dump_rdata: " - "This dname is in the zone.\n"); - if (!write_wrapper((uint8_t *)"\1", - sizeof(uint8_t), 1, fd, - stream, max_size, - written_bytes, crc)) { - dbg_zdump("zdump: dump_rdata: Cannot " - "write zone bit.\n"); - return KNOT_ERROR; - } - } else { - dbg_zdump("zdump: dump_rdata: " - "This dname is not in the zone.\n"); - if (!write_wrapper((uint8_t *)"\0", - sizeof(uint8_t), - 1, fd, - stream, max_size, - written_bytes, crc)) { - dbg_zdump("zdump: dump_rdata: Cannot " - "write zone bit.\n"); - return KNOT_ERROR; - } - } - - if (use_ids && wildcard) { - if (!write_wrapper((uint8_t *)"\1", - sizeof(uint8_t), 1, - fd, stream, max_size, - written_bytes, crc)) { - dbg_zdump("zdump: dump_rdata: Cannot " - "write wildcard bit.\n"); - return KNOT_ERROR; - } - - uint32_t wildcard_id = wildcard->id; - dbg_zdump("zdump: dump_rdata: " - "This dname is covered by wc (%s).\n", - knot_dname_to_str(wildcard)); - if (!write_wrapper(&wildcard_id, - sizeof(wildcard_id), 1, - fd, stream, max_size, - written_bytes, crc)) { - dbg_zdump("zdump: dump_rdata: Cannot " - "write wildcard ID.\n"); - return KNOT_ERROR; - } - } else { - if (!write_wrapper((uint8_t *)"\0", - sizeof(uint8_t), - 1, fd, stream, - max_size, written_bytes, - crc)) { - dbg_zdump("zdump: dump_rdata: Cannot " - "write wildcard bit.\n"); - return KNOT_ERROR; - } - } - } else { - dbg_zdump_detail("zdump: dump_rdata: " - "Writing raw data. Item nr.: %d\n", - i); - assert(rdata->items[i].raw_data != NULL); - if (!write_wrapper(rdata->items[i].raw_data, - sizeof(uint8_t), - rdata->items[i].raw_data[0] + 2, fd, - stream, max_size, - written_bytes, crc)) { - dbg_zdump("zdump: dump_rdata: Cannot write raw " - "data.\n"); - return KNOT_ERROR; - } - - dbg_zdump_detail("zdump: dump_rdata: " - "Written %d long raw data.\n", - rdata->items[i].raw_data[0]); - } - } - - dbg_zdump_verb("zdump: dump_rdata: RDATA dumped successfully.\n"); - return KNOT_EOK; -} - -/*! - * \brief Dumps RRSIG in binary format to given file. - * - * \param rrsig RRSIG to be dumped. - * \param data Arguments to be propagated. - * - * \todo This whole function is obsolete. Change after 1.0.2 release. - */ -static int knot_rrsig_set_dump_binary(knot_rrset_t *rrsig, int fd, - int use_ids, - uint8_t *stream, size_t max_size, - size_t *written_bytes, crc_t *crc) -{ - if (rrsig == NULL) { - dbg_zdump("zdump: dump_rrsig: NULL RRSIG.\n"); - return KNOT_EINVAL; - } - -dbg_zdump_exec_detail( - char *name = knot_dname_to_str(knot_rrset_owner(rrsig)); - dbg_zdump_detail("zdump: dump_rrsig: Dumping RRSIG \\w owner: %s.\n", - name); - free(name); -); - assert(rrsig->type == KNOT_RRTYPE_RRSIG); - assert(rrsig->rdata); - if (!write_wrapper(&rrsig->type, sizeof(rrsig->type), 1, fd, - stream, max_size, written_bytes, crc)) { - dbg_zdump("zdump: dump_rrsig: Cannot write type.\n"); - return KNOT_ERROR; - } - - if (!write_wrapper(&rrsig->rclass, sizeof(rrsig->rclass), 1, fd, - stream, max_size, written_bytes, crc)) { - dbg_zdump("zdump: dump_rrsig: Cannot write class.\n"); - return KNOT_ERROR; - } - - if (!write_wrapper(&rrsig->ttl, sizeof(rrsig->ttl), 1, fd, - stream, max_size, written_bytes, crc)) { - dbg_zdump("zdump: dump_rrsig: Cannot write TTL.\n"); - return KNOT_ERROR; - } - - uint32_t rdata_count = 1; - /* Calculate rrset rdata count. */ - knot_rdata_t *tmp_rdata = rrsig->rdata; - while(tmp_rdata->next != rrsig->rdata) { - tmp_rdata = tmp_rdata->next; - rdata_count++; - } - - if (!write_wrapper(&rdata_count, sizeof(rdata_count), 1, fd, - stream, max_size, written_bytes, crc)) { - dbg_zdump("zdump: dump_rrsig: Cannot write rdata count.\n"); - return KNOT_ERROR; - } - - dbg_zdump_verb("zdump: dump_rrsig: Static data dumped.\n"); - - tmp_rdata = rrsig->rdata; - while (tmp_rdata->next != rrsig->rdata) { - int ret = knot_rdata_dump_binary(tmp_rdata, KNOT_RRTYPE_RRSIG, - fd, - use_ids, stream, max_size, - written_bytes, crc); - if (ret != KNOT_EOK) { - dbg_zdump("zdump: rrsig_to_binary: Could not dump " - "rdata. Reason: %s.\n", knot_strerror(ret)); - return ret; - } - tmp_rdata = tmp_rdata->next; - } - return knot_rdata_dump_binary(tmp_rdata, KNOT_RRTYPE_RRSIG, fd, use_ids, - stream, max_size, written_bytes, crc); -} - -/*! - * \brief Dumps RRSet in binary format to given file. - * - * \param rrset RRSSet to be dumped. - * \param data Arguments to be propagated. - */ -static int knot_rrset_dump_binary(const knot_rrset_t *rrset, int fd, - int use_ids, - uint8_t *stream, size_t max_size, - size_t *written_bytes, - crc_t *crc) -{ - if (rrset == NULL) { - dbg_zdump("zdump: dump_rrset: NULL RRSet.\n"); - return KNOT_EINVAL; - } - - dbg_zdump_exec_detail( - char *name = knot_dname_to_str(knot_rrset_owner(rrset)); - dbg_zdump_detail("zdump: dump_rrset: " - "Dumping RRSet \\w owner: %s.\n", - name); - free(name); - ); - - if (!use_ids) { - assert(rrset->rrsigs == NULL); - } - - if (!use_ids) { - /*!< \todo IDs in changeset do no good. Change loading too. */ - int ret = dump_dname_with_id(rrset->owner, - fd, stream, max_size, - written_bytes, crc); - if (ret != KNOT_EOK) { - dbg_zdump("zdump: rrset_dump_binary: Could not dump " - "RRSet's owner.\n"); - return ret; - } - } - - if (!write_wrapper(&rrset->type, sizeof(rrset->type), 1, fd, - stream, max_size, written_bytes, crc)) { - dbg_zdump("zdump: dump_rrset: Cannot write type.\n"); - return KNOT_ERROR; - } - if (!write_wrapper(&rrset->rclass, sizeof(rrset->rclass), 1, fd, - stream, max_size, written_bytes, crc)) { - dbg_zdump("zdump: dump_rrset: Cannot write class.\n"); - return KNOT_ERROR; - } - if (!write_wrapper(&rrset->ttl, sizeof(rrset->ttl), 1, fd, - stream, max_size, written_bytes, crc)) { - dbg_zdump("zdump: dump_rrset: Cannot write TTL.\n"); - return KNOT_ERROR; - } - - uint32_t rdata_count = 1; - uint8_t has_rrsig = rrset->rrsigs != NULL; - - /* Calculate rrset rdata count. */ - knot_rdata_t *tmp_rdata = rrset->rdata; - while(tmp_rdata && (tmp_rdata->next != rrset->rdata)) { - tmp_rdata = tmp_rdata->next; - rdata_count++; - } - - if (rrset->rdata == NULL) { - rdata_count = 0; - } - - if (!write_wrapper(&rdata_count, sizeof(rdata_count), 1, fd, - stream, max_size, written_bytes, crc)) { - dbg_zdump("zdump: dump_rrset: Cannot write rdata count.\n"); - return KNOT_ERROR; - } - - if (!write_wrapper(&has_rrsig, sizeof(has_rrsig), 1, fd, - stream, max_size, written_bytes, crc)) { - return KNOT_ERROR; - } - - dbg_zdump_verb("zdump: rrset_dump_binary: Static data dumped.\n"); - - if (rdata_count != 0) { - - tmp_rdata = rrset->rdata; - - while (tmp_rdata->next != rrset->rdata) { - int ret = knot_rdata_dump_binary(tmp_rdata, rrset->type, - fd, use_ids, - stream, max_size, - written_bytes, crc); - if (ret != KNOT_EOK) { - dbg_zdump("zdump: rrset_to_binary: Could not " - "dump " - "rdata. Reason: %s.\n", - knot_strerror(ret)); - return ret; - } - tmp_rdata = tmp_rdata->next; - } - - int ret = knot_rdata_dump_binary(tmp_rdata, rrset->type, - fd, use_ids, - stream, - max_size, written_bytes, crc); - if (ret != KNOT_EOK) { - dbg_zdump("zdump: rrset_to_binary: Could not dump " - "rdata. Reason: %s.\n", knot_strerror(ret)); - return ret; - } - } - - dbg_zdump_verb("zdump: rrset_dump_binary: Rdata dumped.\n"); - - /* This is now obsolete, although I'd rather not use recursion - that - * would probably not work */ - - if (rrset->rrsigs != NULL) { - return knot_rrsig_set_dump_binary(rrset->rrsigs, fd, use_ids, - stream, - max_size, written_bytes, crc); - } else { - return KNOT_EOK; - } -} - -/*! - * \brief Dumps all RRSets in node to file in binary format. - * - * \param node Node to dumped. - * \param data Arguments to be propagated. - */ -static int knot_node_dump_binary(knot_node_t *node, int fd, - uint8_t *stream, - size_t max_size, - size_t *written_bytes, - crc_t *crc) -{ - if (node == NULL) { - dbg_zdump("zdump: dump_node: NULL node.\n"); - return KNOT_EINVAL; - } - - /* first write dname */ - assert(node->owner != NULL); - - /* Write owner ID. */ -dbg_zdump_exec_detail( - char *name = knot_dname_to_str(knot_node_owner(node)); - dbg_zdump_detail("zdump: dump_node: Dumping node owned by %s\n", - name); - free(name); -); - assert(node->owner->id != 0); - uint32_t owner_id = node->owner->id; - if (!write_wrapper(&owner_id, sizeof(owner_id), 1, fd, stream, - max_size, written_bytes, crc)) { - dbg_zdump("zdump: dump_node: Cannot write ID.\n"); - return KNOT_ERROR; - } - - /*!< \todo Fix after release. */ - if (knot_node_parent(node) != NULL) { - uint32_t parent_id = knot_dname_id( - knot_node_owner(knot_node_parent(node))); - if (!write_wrapper(&parent_id, sizeof(parent_id), 1, fd, - stream, max_size, written_bytes, crc)) { - dbg_zdump("zdump: dump_node: Cannot write parent " - "ID.\n"); - return KNOT_ERROR; - } - } else { - uint32_t parent_id = 0; - if (!write_wrapper(&parent_id, sizeof(parent_id), 1, fd, - stream, max_size, written_bytes, crc)) { - dbg_zdump("zdump: dump_node: Cannot write parent " - "ID.\n"); - return KNOT_ERROR; - } - } - - if (!write_wrapper(&(node->flags), sizeof(node->flags), 1, fd, - stream, max_size, written_bytes, crc)) { - dbg_zdump("zdump: dump_node: Cannot write node flags.\n"); - return KNOT_ERROR; - } - - if (knot_node_nsec3_node(node) != NULL) { - uint32_t nsec3_id = - knot_node_owner(knot_node_nsec3_node(node))->id; - if (!write_wrapper(&nsec3_id, sizeof(nsec3_id), 1, fd, - stream, max_size, written_bytes, crc)) { - dbg_zdump("zdump: dump_node: Cannot write NSEC3 ID.\n"); - return KNOT_ERROR; - } - - dbg_zdump_detail("Written nsec3 node id: %u\n", - knot_node_owner( - knot_node_nsec3_node(node))->id); - } else { - uint32_t nsec3_id = 0; - if (!write_wrapper(&nsec3_id, sizeof(nsec3_id), 1, fd, - stream, max_size, written_bytes, crc)) { - dbg_zdump("zdump: dump_node: Cannot write NSEC3 ID.\n"); - return KNOT_ERROR; - } - } - - /* Now we need (or do we?) count of rrsets to be read - * but that number is yet unknown */ - - uint16_t rrset_count = node->rrset_count; - if (!write_wrapper(&rrset_count, sizeof(rrset_count), 1, fd, - stream, max_size, written_bytes, crc)) { - dbg_zdump("zdump: dump_node: Cannot write RRSet count.\n"); - return KNOT_ERROR; - } - - const knot_rrset_t **node_rrsets = knot_node_rrsets(node); - for (int i = 0; i < rrset_count; i++) - { - int ret = knot_rrset_dump_binary(node_rrsets[i], fd, 1, - stream, max_size, - written_bytes, crc); - if (ret != KNOT_EOK) { - dbg_zdump("zdump: dump_node: Could not dump RRSet. " - "Reason: %s.\n", knot_strerror(ret)); - return ret; - } - } - - free(node_rrsets); - - dbg_zdump_verb("zdump: dump_node: Node dumped successfully.\n"); - - return KNOT_EOK; -} - -int zone_is_secure(knot_zone_contents_t *zone) -{ - if (knot_node_rrset(knot_zone_contents_apex(zone), - KNOT_RRTYPE_DNSKEY) == NULL) { - return 0; - } else { - if (knot_node_rrset(knot_zone_contents_apex(zone), - KNOT_RRTYPE_NSEC3PARAM) != NULL) { - return 2; - } else { - return 1; - } - } -} - -static void dump_dname_from_tree(knot_dname_t *dname, - void *data) -{ - arg_t *arg = (arg_t *)data; - if (arg->error_code != KNOT_EOK) { - dbg_zdump("zdump: dump_dname_from_tree: " - "Error occured previously.\n"); - return; - } - - int *fd_pointer = (int *)arg->arg1; - int fd = -1; - if (fd_pointer != NULL) { - fd = *fd_pointer; - } else { - dbg_zdump("zdump: dump_dname_from_tree: Bad fd.\n"); - arg->error_code = KNOT_EINVAL; - return; - } - - uint8_t *buffer = (uint8_t *)arg->arg5; - size_t *written_bytes = (size_t *)arg->arg6; - crc_t *crc = (crc_t*)arg->arg2; - - arg->error_code = dump_dname_with_id(dname, fd, buffer, - BUFFER_SIZE, written_bytes, crc); -} - -static int knot_dump_dname_table(const knot_dname_table_t *dname_table, - int fd, crc_t *crc, uint8_t *buffer, - size_t *written_bytes) -{ - arg_t arg; - arg.arg2 = crc; - arg.arg5 = buffer; - arg.arg6 = written_bytes; - arg.arg1 = &fd; - assert(arg.arg1 == &fd); - arg.error_code = KNOT_EOK; - /* Go through the tree and dump each dname along with its ID. */ - knot_dname_table_tree_inorder_apply(dname_table, - dump_dname_from_tree, &arg); - - return arg.error_code; -} - -static void save_node_from_tree(knot_node_t *node, void *data) -{ - arg_t *arg = (arg_t *)data; - if (arg == NULL) { - return; - } - - /* Increment node count */ - (*((uint32_t *)(arg->arg1)))++; - /* Save the first node only */ - if (arg->arg2 == NULL) { - arg->arg2 = (void *)node; - } - arg->arg3 = (void *)node; -} - -static void dump_node_to_file(knot_node_t *node, void *data) -{ - arg_t *arg = (arg_t *)data; - if (arg == NULL) { - return; - } - - if (arg->error_code != KNOT_EOK) { - dbg_zdump("zdump: dump_node_to_file: " - "Error occured previously.\n"); - return; - } - - int *fd_pointer = (int *)arg->arg1; - int fd = -1; - if (fd_pointer != NULL) { - fd = *fd_pointer; - } - - uint8_t *buffer = (uint8_t *)arg->arg5; - size_t *written_bytes = (size_t *)arg->arg6; - - arg->error_code = - knot_node_dump_binary(node, - fd, buffer, BUFFER_SIZE, written_bytes, - (crc_t *)arg->arg7); -} - -char *knot_zdump_crc_file(const char* filename) -{ - char *crc_path = - malloc(sizeof(char) * (strlen(filename) + - strlen(".crc") + 1)); - CHECK_ALLOC_LOG(crc_path, NULL); - memset(crc_path, 0, - sizeof(char) * (strlen(filename) + - strlen(".crc") + 1)); - memcpy(crc_path, filename, - sizeof(char) * strlen(filename)); - crc_path = strncat(crc_path, ".crc", strlen(".crc")); - return crc_path; -} - -int knot_zdump_binary(knot_zone_contents_t *zone, int fd, - int do_checks, const char *sfilename, - crc_t *crc) -{ - - if (fd < 0 || sfilename == NULL) { - dbg_zdump("zdump: Bad arguments.\n"); - return KNOT_EINVAL; - } - - dbg_zdump("zdump: Dumping zone %p.\n", zone); - - uint8_t buffer[BUFFER_SIZE]; - size_t written_bytes = 0; - - arg_t arguments; - /* Memory to be derefenced in the save_node_from_tree function. */ - uint32_t node_count = 0; - arguments.arg1 = &node_count; - arguments.arg2 = NULL; - - /* Count number of normal nodes. This cannot fail. */ - knot_zone_contents_tree_apply_inorder(zone, save_node_from_tree, - &arguments); - /* arg1 is now count of normal nodes */ - uint32_t normal_node_count = *((uint32_t *)arguments.arg1); - - node_count = 0; - arguments.arg1 = &node_count; - arguments.arg2 = NULL; - - /* Count number of NSEC3 nodes. This cannot fail. */ - knot_zone_contents_nsec3_apply_inorder(zone, - save_node_from_tree, &arguments); - uint32_t nsec3_node_count = *((uint32_t *)arguments.arg1); - /* arg2 is the first NSEC3 node - used in sem checks. */ - /* arg3 is the last NSEC3 node - used in sem checks. */ - const knot_node_t *first_nsec3_node = (knot_node_t *)arguments.arg2; - const knot_node_t *last_nsec3_node = (knot_node_t *)arguments.arg3; - - if (do_checks && zone_is_secure(zone)) { - do_checks += zone_is_secure(zone); - } - - /* FIXME(OS): Really descriptive call 1,1,1,1, some #defines here? */ - err_handler_t *handler = handler_new(1, 1, 1, 1, 1); - if (handler == NULL) { - return KNOT_ENOMEM; - } else { /* Do check for SOA right now */ - if (knot_node_rrset(knot_zone_contents_apex(zone), - KNOT_RRTYPE_SOA) == NULL) { - err_handler_handle_error(handler, - knot_zone_contents_apex(zone), - ZC_ERR_MISSING_SOA, - NULL); - } - } - - knot_node_t *last_node = NULL; - int ret = zone_do_sem_checks(zone, - do_checks, handler, &last_node); - log_cyclic_errors_in_zone(handler, zone, last_node, - first_nsec3_node, last_nsec3_node, - do_checks); - err_handler_log_all(handler); - free(handler); - - if (ret != KNOT_EOK) { - fprintf(stderr, "Zone will not be dumped because of " - "fatal semantic errors.\n"); - /* If remove fails, there is nothing we can do. */ - return KNOT_ERROR; - } - - *crc = crc_init(); - - /* Start writing header - magic bytes. */ - static const uint8_t MAGIC[MAGIC_LENGTH] = MAGIC_BYTES; - if (!write_wrapper(&MAGIC, sizeof(uint8_t), MAGIC_LENGTH, - fd, buffer, BUFFER_SIZE, &written_bytes, crc)) { - dbg_zdump("zdump: Cannot write magic bytes.\n"); - return KNOT_ERROR; - } - - /* Write source file length. */ - uint32_t sflen = strlen(sfilename) + 1; - if (!write_wrapper(&sflen, sizeof(uint32_t), 1, fd, - buffer, BUFFER_SIZE, &written_bytes, crc)) { - dbg_zdump("zdump: Cannot write source file length.\n"); - return KNOT_ERROR; - } - - /* Write source file. */ - if (!write_wrapper(sfilename, sflen, 1, fd, buffer, - BUFFER_SIZE, &written_bytes, crc)) { - dbg_zdump("zdump: Cannot write source file name.\n"); - return KNOT_ERROR; - } - - /* Notice: End of header, - */ - - /* Start writing compiled data. */ - if (!write_wrapper(&normal_node_count, sizeof(normal_node_count), 1, fd, - buffer, BUFFER_SIZE, &written_bytes, crc)) { - dbg_zdump("zdump: Cannot write node count.\n"); - return KNOT_ERROR; - } - - if (!write_wrapper(&nsec3_node_count, sizeof(nsec3_node_count), 1, fd, - buffer, BUFFER_SIZE, &written_bytes, crc)) { - dbg_zdump("zdump: Cannot write NSEC3 node count.\n"); - return KNOT_ERROR; - } - uint32_t auth_node_count = zone->node_count; - if (!write_wrapper(&auth_node_count, - sizeof(auth_node_count), - 1, fd, buffer, BUFFER_SIZE, &written_bytes, crc)) { - dbg_zdump("zdump: Cannot write authoritative node count.\n"); - return KNOT_ERROR; - } - - /* Write total number of dnames */ - assert(zone->dname_table); - uint32_t total_dnames = zone->dname_table->id_counter; - if (!write_wrapper(&total_dnames, - sizeof(total_dnames), 1, fd, - buffer, BUFFER_SIZE, &written_bytes, crc)) { - dbg_zdump("zdump: Cannot write dname count.\n"); - return KNOT_ERROR; - } - - /* Write dname table. */ - if (knot_dump_dname_table(zone->dname_table, fd, crc, buffer, - &written_bytes) - != KNOT_EOK) { - dbg_zdump("zdump: Cannot write dname table.\n"); - return KNOT_ERROR; - } - - arguments.arg1 = &fd; - arguments.arg3 = zone; - arguments.arg5 = buffer; - arguments.arg6 = &written_bytes; - arguments.arg7 = crc; - - arguments.error_code = KNOT_EOK; - - /*!< \todo #1685 Stop traversal upon error. */ - knot_zone_contents_tree_apply_inorder(zone, dump_node_to_file, - (void *)&arguments); - - if (arguments.error_code != KNOT_EOK) { - dbg_zdump("zdump: Dump of normal tree failed. Reason: %s.\n", - knot_strerror(arguments.error_code)); - return arguments.error_code; - } - - arguments.error_code = KNOT_EOK; - knot_zone_contents_nsec3_apply_inorder(zone, dump_node_to_file, - (void *)&arguments); - - if (arguments.error_code != KNOT_EOK) { - dbg_zdump("zdump: Dump of NSEC3 tree failed. Reason: %s.\n", - knot_strerror(arguments.error_code)); - return arguments.error_code; - } - - /* Finish the dump. */ - if (!write_to_file_crc(buffer, 1, written_bytes, fd, crc)) { - fprintf(stderr, "Failed to finalize zone db!\n"); - return KNOT_ERROR; - } - - *crc = crc_finalize(*crc); - dbg_zdump("zdump: Zone %p dumped successfully.\n", zone); - - return KNOT_EOK; -} - -int knot_zdump_rrset_serialize(const knot_rrset_t *rrset, uint8_t *stream, - size_t max_size, size_t *written_bytes) -{ - if (stream == NULL || rrset == NULL || - written_bytes == NULL) { - dbg_zdump("zdump: rrset_serialize: Bad arguments.\n"); - return KNOT_EINVAL; - } - - *written_bytes = 0; - - /* This fd will signal functions to use streams. */ - int fd = -1; - - return knot_rrset_dump_binary(rrset, fd, 0, stream, max_size, - written_bytes, NULL); -} - -int knot_zdump_dump(knot_zone_contents_t *zone, int fd, const char *sfilename, - crc_t *crc) -{ - int rc = knot_zdump_binary(zone, fd, 0, sfilename, crc); - if (rc != KNOT_EOK) { - dbg_zdump("Failed to save the zone to binary zone db\n."); - return KNOT_ERROR; - } - - return KNOT_EOK; -} diff --git a/src/knot/zone/zone-dump.h b/src/knot/zone/zone-dump.h deleted file mode 100644 index 538cb87ea9f10a38b90912d272cd2bcd37507dcc..0000000000000000000000000000000000000000 --- a/src/knot/zone/zone-dump.h +++ /dev/null @@ -1,97 +0,0 @@ -/* Copyright (C) 2011 CZ.NIC, z.s.p.o. <knot-dns@labs.nic.cz> - - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see <http://www.gnu.org/licenses/>. - */ -/*! - * \file zone-dump.h - * - * \author Jan Kadlec <jan.kadlec@nic.cz> - * - * \brief Functions for dumping zone to binary file. - * - * \addtogroup zone-load-dump - * @{ - */ - -#ifndef _KNOT_ZONEDUMP_H_ -#define _KNOT_ZONEDUMP_H_ - -#include "common/crc.h" -#include "libknot/zone/zone.h" - -/*! - * \brief Zone loader enums. - */ -enum { - MAGIC_LENGTH = 7 /*!< Compiled zone magic length. */ -}; - -/*! \brief Magic identifier: { "knot", maj_ver, min_ver, revision } */ -#define MAGIC_BYTES {'k', 'n', 'o', 't', '1', '1', '0'} - -/*! - * \brief Dumps given zone to binary file. - * - * \param zone Zone to be saved. - * \param fd File descriptor to be written to. - * \param do_checks Set to 1 to enable checking the zone for semantic errors. - * \param sfilename Source filename of the text zone file. - * \param crc Returns a calculated CRC. - * - * \retval KNOT_EOK on success. - * \retval KNOT_EINVAL if the file cannot be opened for writing. - */ -int knot_zdump_binary(knot_zone_contents_t *zone, int fd, - int do_checks, const char *sfilename, - crc_t *crc); - -/*! - * \brief Serializes RRSet into binary stream. Expects NULL pointer, memory - * is handled inside function. - * - * \param rrset RRSet to be serialized. - * \param stream Stream containing serialized RRSet. - * \param max_size Maximum size of stream. - * \param bytes_written Actually written data. - * - * \retval KNOT_EOK on success. - * \retval KNOT_EINVAL if wrong arguments are supplied. - * \retval KNOT_ENOMEM on memory error. - */ -int knot_zdump_rrset_serialize(const knot_rrset_t *rrset, uint8_t *stream, - size_t max_size, size_t *bytes_written); - -/*! - * \brief Checks if zone uses DNSSEC and/or NSEC3 - * - * \param zone Zone to be checked. - * - * \retval 0 if zone is not secured. - * \retval 2 if zone uses NSEC3 - * \retval 1 if zone uses NSEC - */ -int zone_is_secure(knot_zone_contents_t *zone); - -/*! \todo Document me (issue #1586). */ -int knot_zdump_dump(knot_zone_contents_t *zone, int fd, const char *sfilename, - crc_t *crc); - -/*! - * \brief Return name of the CRC file associated with filename. - */ -char *knot_zdump_crc_file(const char* filename); - -#endif /* _KNOT_ZONEDUMP_H_ */ - -/*! @} */ diff --git a/src/knot/zone/zone-load.c b/src/knot/zone/zone-load.c index 813a62793c07ef29f5cee7efca000ad0ca967d95..99c502368815b81c817f7c24c53db3886ea91fa6 100644 --- a/src/knot/zone/zone-load.c +++ b/src/knot/zone/zone-load.c @@ -30,8 +30,8 @@ #include "libknot/common.h" #include "knot/other/debug.h" #include "knot/zone/zone-load.h" -#include "knot/zone/zone-dump.h" #include "libknot/libknot.h" +#include "zscanner/file_loader.h" /*! * \brief Compares two time_t values. @@ -50,1158 +50,623 @@ static int timet_cmp(time_t x, time_t y) return 0; } -/*! - * \brief Safe wrapper around fread. - * - * \param dst Destination pointer. - * \param size Size of element to be read. - * \param n Number of elements to be read. - * \param fp File to read from. - * - * \retval > 0 if succesfull. - * \retval 0 if failed. - */ -static inline int fread_safe_from_file(void *dst, - size_t size, size_t n, void *source) -{ - if (dst == NULL || source == NULL) { - dbg_zload("zload: fread_safe_from_file: NULL arguments.\n"); - return 0; - } - FILE *fp = (FILE *)source; - int rc = fread(dst, size, n, fp); - if (rc != n) { - dbg_zload("zload: fread_safe_from_file: " - "invalid read %d (exp. %zu)\n", - rc, n); - } - - return rc == n; -} - -struct load_stream { - uint8_t *stream; - size_t stream_remaining; - size_t stream_size; -}; - -typedef struct load_stream load_stream_t; - -static inline int read_from_stream(void *dst, - size_t size, size_t n, void *source) -{ - if (dst == NULL || source == NULL) { - dbg_zload("zload: read_from_stream: NULL arguments.\n"); - return 0; - } - - /* Extract information from source data. */ - load_stream_t *data = (load_stream_t *)source; - - - if (data->stream_remaining < (size * n)) { - dbg_zload("zload: read_from_stream: Buffer depleted.\n"); - return 0; - } +/* ZONE LOADING FROM FILE USING RAGEL PARSER */ - memcpy(dst, - data->stream + - (data->stream_size - data->stream_remaining), - size * n); - data->stream_remaining -= size * n; - return 1; -} - -/*! \note Contents of dump file: - * MAGIC(knotxx) NUMBER_OF_NORMAL_NODES NUMBER_OF_NSEC3_NODES - * [normal_nodes] [nsec3_nodes] - * node has following format: - * owner_size owner_wire owner_label_size owner_labels owner_id - * node_flags node_rrset_count [node_rrsets] - * rrset has following format: - * rrset_type rrset_class rrset_ttl rrset_rdata_count rrset_rrsig_count - * [rrset_rdata] [rrset_rrsigs] - * rdata can either contain full dnames (that is with labels but without ID) - * or dname ID, if dname is in the zone - * or raw data stored like this: data_len [data] - */ +// TODO remove once debugging is done +static long rr_count = 0; +static long new_rr_count = 0; +static long new_dname_count = 0; +static long err_count = 0; -enum { DNAME_MAX_WIRE_LENGTH = 256 }; /*! - * \brief Helper function. Frees rdata items and temporary array of items. + * \brief Adds RRSet to list. * - * \param rdata Rdata to be freed. - * \param items Items to be freed. - * \param count Current count of rdata items. - * \param type RRSet type. + * \param head Head of list. + * \param rrsig RRSet to be added. */ -static void load_rdata_purge(knot_rdata_t *rdata, - knot_rdata_item_t *items, - int count, - knot_rrtype_descriptor_t *desc, - uint16_t type) +static int rrset_list_add(rrset_list_t **head, knot_rrset_t *rrsig) { - /* Increase refcount manually, as the set_items() doesn't see the dname - * type and thus is unable to increment refcounter. - */ - for (int i = 0; i < count; ++i) { - switch(desc->wireformat[i]) { - case KNOT_RDATA_WF_COMPRESSED_DNAME: - case KNOT_RDATA_WF_UNCOMPRESSED_DNAME: - case KNOT_RDATA_WF_LITERAL_DNAME: - knot_dname_retain(items[i].dname); - break; - default: - /*!< \todo This would leak wire data! */ - break; - } - } - - /* Copy items to rdata and free the temporary rdata. */ - knot_rdata_set_items(rdata, items, count); - knot_rdata_deep_free(&rdata, type, 0); - free(items); -} - -static knot_dname_t *read_dname_with_id(FILE *f, int use_ids) -{ - if (f == NULL) { - dbg_zload("zload: read_dname_id: NULL file.\n"); - } - knot_dname_t *ret = knot_dname_new(); - CHECK_ALLOC_LOG(ret, NULL); - - int (*fread_wrapper)(void *dst, size_t size, size_t n, void *source); - if (use_ids) { - fread_wrapper = fread_safe_from_file; + if (*head == NULL) { + *head = xmalloc(sizeof(rrset_list_t)); + (*head)->next = NULL; + (*head)->data = rrsig; } else { - fread_wrapper = read_from_stream; - } - - /* Read ID. */ - uint32_t dname_id = 0; - if (!fread_wrapper(&dname_id, sizeof(dname_id), 1, f)) { - knot_dname_release(ret); - dbg_zload("zload: read_dname_id: Cannot read dname ID.\n"); - return NULL; - } - - ret->id = dname_id; - dbg_zload_detail("zload: read_dname_id: dname id: %u\n", dname_id); - - /* Read size of dname. */ - uint32_t dname_size = 0; - if (!fread_wrapper(&dname_size, sizeof(dname_size), 1, f)) { - knot_dname_release(ret); - dbg_zload("zload: read_dname_id: Cannot read dname size.\n"); - return NULL; - } - ret->size = dname_size; - dbg_zload_detail("loaded: dname length: %u\n", ret->size); - if (ret->size > DNAME_MAX_WIRE_LENGTH) { - dbg_zload("zload: read_dname_id: Name too long.\n"); - knot_dname_release(ret); - return NULL; - } - - /* Read wireformat of dname. */ - ret->name = malloc(sizeof(uint8_t) * ret->size); - if (ret->name == NULL) { - ERR_ALLOC_FAILED; - knot_dname_release(ret); - return NULL; - } - - if (!fread_wrapper(ret->name, sizeof(uint8_t), ret->size, f)) { - knot_dname_release(ret); - dbg_zload("zload: read_dname_id: Cannot read dname name.\n"); - return NULL; - } - - /* Read labels. */ - uint16_t label_count = 0; - if (!fread_wrapper(&label_count, sizeof(label_count), 1, f)) { - knot_dname_release(ret); - dbg_zload("zload: read_dname_id: Cannot read " - "dname label count.\n"); - return NULL; - } - - ret->label_count = label_count; - - ret->labels = malloc(sizeof(uint8_t) * ret->label_count); - if (ret->labels == NULL) { - ERR_ALLOC_FAILED; - knot_dname_release(ret); - return NULL; + rrset_list_t *tmp = xmalloc(sizeof(*tmp)); + tmp->next = *head; + tmp->data = rrsig; + *head = tmp; } + + dbg_zp_verb("zp: rrset_add: Added RRSIG %p to list.\n", rrsig); - if (!fread_wrapper(ret->labels, sizeof(uint8_t), ret->label_count, f)) { - free(ret->name); - free(ret); - dbg_zload("zload: read_dname_id: Cannot read dname labels.\n"); - return NULL; - } - -dbg_zload_exec_detail( - char *name = knot_dname_to_str(ret); - dbg_zload_detail("zload: Loaded dname: %s (id: %d).\n", name, - ret->id); - free(name); -); - - return ret; + return KNOT_EOK; } /*! - * \brief Load rdata in binary format from file. + * \brief Deletes RRSet list. Sets pointer to NULL. * - * \param type Type of RRSet containing read rdata. - * \param f File to read binary data from. - * - * \return Pointer to read and created rdata on success, NULL otherwise. + * \param head Head of list to be deleted. */ -static knot_rdata_t *knot_load_rdata(uint16_t type, FILE *f, - knot_dname_t **id_array, - int use_ids) +static void rrset_list_delete(rrset_list_t **head) { - if (f == NULL) { - dbg_zload("zload: load_rdata: NULL arguments.\n"); - return NULL; - } - - int (*fread_wrapper)(void *dst, size_t size, size_t n, void *source); - if (use_ids) { - fread_wrapper = fread_safe_from_file; - } else { - fread_wrapper = read_from_stream; - } - - knot_rdata_t *rdata = knot_rdata_new(); - if (rdata == NULL) { - dbg_zload("zload: load_rdata: Cannot create new rdata.\n"); - return NULL; - } - - knot_rrtype_descriptor_t *desc = - knot_rrtype_descriptor_by_type(type); - assert(desc != NULL); - - /* First we should read rdata count. */ - - uint32_t rdata_count = 0; - - if(!fread_wrapper(&rdata_count, sizeof(rdata_count), 1, f)) { - knot_rdata_free(&rdata); - dbg_zload("zload: load_rdata: Cannot read rdata count.\n"); - return NULL; - } - - knot_rdata_item_t *items = - malloc(sizeof(knot_rdata_item_t) * rdata_count); - if (items == NULL) { - ERR_ALLOC_FAILED; - free(rdata); - return NULL; - } - - if (rdata_count > desc->length) { - dbg_zload("zload: load_rdata: Read wrong count of RDATA.\n"); - free(items); - free(rdata); - return NULL; - } - - uint16_t raw_data_length = 0; - - dbg_zload_detail("zload: load_rdata: Reading %d items\n", rdata_count); - dbg_zload_detail("zload: load_rdata: Current type: %u\n", type); - - for (int i = 0; i < rdata_count; i++) { - if (desc->wireformat[i] == KNOT_RDATA_WF_COMPRESSED_DNAME || - desc->wireformat[i] == KNOT_RDATA_WF_UNCOMPRESSED_DNAME || - desc->wireformat[i] == KNOT_RDATA_WF_LITERAL_DNAME ) { - - /*!< \todo #1686 - * Refactor these variables, some might be too big. - */ - - - uint32_t dname_id = 0; - uint8_t has_wildcard = 0; - uint8_t in_the_zone = 0; - - if (use_ids) { - if(!fread_wrapper(&dname_id, sizeof(dname_id), - 1, f)) { - load_rdata_purge(rdata, - items, i, desc, type); - dbg_zload("zload: load_rdata: " - "Cannot read dname ID.\n"); - return NULL; - } - - /* Store reference do dname. */ - knot_dname_retain(id_array[dname_id]); - items[i].dname = id_array[dname_id]; - } else { - items[i].dname = read_dname_with_id(f, use_ids); - } - - dbg_zload_detail("zload: load_rdata: " - "Loading dname: %s.\n", - knot_dname_to_str(items[i].dname)); - - - if(!fread_wrapper(&in_the_zone, sizeof(in_the_zone), - 1, f)) { - load_rdata_purge(rdata, items, i, desc, type); - dbg_zload("zload: load_rdata: " - "Cannot read zone bit.\n"); - return NULL; - } - - if(!fread_wrapper(&has_wildcard, sizeof(uint8_t), - 1, f)) { - load_rdata_purge(rdata, items, i, desc, type); - dbg_zload("zload: load_rdata: " - "Cannot read wildcard bit.\n"); - return NULL; - } - - dbg_zload_detail("zload: load_rdata: Has wildcard: " - "%d\n", has_wildcard); - - if (use_ids && !in_the_zone) { - dbg_zload_detail("zload: load_rdata: " - "Freeing node owned by: %s.\n", - knot_dname_to_str(items[i].dname)); - /* Destroy the node */ - assert(!in_the_zone); - if (items[i].dname->node != NULL && - /* - * This check is here to prevent freeing - * of previously set wildcard node. - */ - (items[i].dname->node->owner == - items[i].dname)) { - knot_node_free(&items[i].dname->node); - assert(items[i].dname->node == NULL); - } - } - - if (use_ids && has_wildcard) { - if(!fread_wrapper(&dname_id, sizeof(dname_id), - 1, f)) { - load_rdata_purge(rdata, items, - i, desc, type); - dbg_zload("zload: load_rdata: " - "Cannot read wc ID.\n"); - return NULL; - } - dbg_zload_detail("zload: load_rdata: " - "Wildcard: %s\n", - knot_dname_to_str( - id_array[dname_id])); - items[i].dname->node = - id_array[dname_id]->node; - } - - assert(items[i].dname); - } else { - if (!fread_wrapper(&raw_data_length, - sizeof(raw_data_length), 1, f)) { - load_rdata_purge(rdata, items, i, desc, type); - dbg_zload("zload: load_rdata: Cannot read " - "raw data length.\n"); - return NULL; - } - - /*!< \todo this is not proper fix, see #1678 */ - items[i].raw_data = - malloc(raw_data_length + 2); - if (items[i].raw_data == NULL) { - ERR_ALLOC_FAILED; - load_rdata_purge(rdata, items, i + 1, desc, - type); - return NULL; - } - items[i].raw_data[0] = raw_data_length; - - if (!fread_wrapper(items[i].raw_data + 1, - sizeof(uint8_t), - raw_data_length, f)) { - load_rdata_purge(rdata, items, i + 1, desc, - type); - dbg_zload("zload: load_rdata: Cannot read " - "raw data.\n"); - return NULL; - } - dbg_zload_detail("zload: load_rdata: Read raw_data " - "length=%d.\n", - raw_data_length); - } + rrset_list_t *tmp; + if (*head == NULL) { + return; } - /* Each item has refcount already incremented for saving in rdata. */ - int ret = knot_rdata_set_items(rdata, items, rdata_count); - if (ret != KNOT_EOK) { - dbg_zload("zload: read_rdata: Could not set items " - "when loading rdata. Reason: %s\n.", - knot_strerror(ret)); - load_rdata_purge(rdata, items, desc->length, desc, type); - return NULL; + while (*head != NULL) { + tmp = *head; + *head = (*head)->next; + free(tmp); } - free(items); - assert(rdata->count == rdata_count); + *head = NULL; - dbg_zload_detail("zload: read_rdata: All %d items read " - "successfully.\n", - desc->length); - - return rdata; + dbg_zp("zp: list_delete: List deleleted.\n"); } -/*! - * \brief Loads RRSIG from binary file. - * - * \param f File to read from. - * - * \return pointer to created and read RRSIG on success, NULL otherwise. - */ -static knot_rrset_t *knot_load_rrsig(void *f, knot_dname_t **id_array, - int use_ids) +static int find_rrset_for_rrsig_in_node(knot_zone_contents_t *zone, + knot_node_t *node, + knot_rrset_t *rrsig) { - if (f == NULL || id_array == NULL) { - dbg_zload("zload: load_rrsig: Bad arguments.\n"); - return NULL; + assert(node); + + assert(knot_dname_compare(rrsig->owner, node->owner) == 0); + + knot_rrset_t *tmp_rrset = + knot_node_get_rrset(node, + knot_rrset_rdata_rrsig_type_covered(rrsig)); + + int ret; + + if (tmp_rrset == NULL) { + dbg_zp("zp: find_rr_for_sig_in_node: Node does not contain " + "RRSet of type %d.\n", + knot_rrset_rdata_rrsig_type_covered(rrsig)); + tmp_rrset = knot_rrset_new(rrsig->owner, + knot_rrset_rdata_rrsig_type_covered(rrsig), + rrsig->rclass, + rrsig->ttl); + if (tmp_rrset == NULL) { + dbg_zp("zp: find_rr_for_sig_in_node: Cannot create " + "dummy RRSet.\n"); + return KNOT_ERROR; + } + + ret = knot_zone_contents_add_rrset(zone, tmp_rrset, &node, + KNOT_RRSET_DUPL_MERGE, 1); + assert(ret <= 0); + if (ret < 0) { + dbg_zp("zp: Failed to add new dummy RRSet to the zone." + "\n"); + return KNOT_ERROR; + } } - int (*fread_wrapper)(void *dst, size_t size, size_t n, void *source); - if (use_ids) { - fread_wrapper = fread_safe_from_file; - } else { - fread_wrapper = read_from_stream; - } + assert(tmp_rrset); - knot_rrset_t *rrsig = NULL; - - uint16_t rrset_type = 0; - uint16_t rrset_class = 0; - uint32_t rrset_ttl = 0; - - uint32_t rdata_count = 0; - - if (!fread_wrapper(&rrset_type, sizeof(rrset_type), 1, f)) { - dbg_zload("zload: load_rrsig: Cannot read type.\n"); - return NULL; - } - - if (rrset_type != KNOT_RRTYPE_RRSIG) { - dbg_zload("zload: load_rrsig: RRSIG has wrong type," - " probably data corruption.\n"); - return NULL; - } - dbg_zload_detail("zload: load_rrsig: RRSIG type: %d\n", rrset_type); - if (!fread_wrapper(&rrset_class, sizeof(rrset_class), 1, f)) { - dbg_zload("zload: load_rrsig: Cannot read class.\n"); - return NULL; + if (tmp_rrset->ttl != rrsig->ttl) { + char *name = knot_dname_to_str(tmp_rrset->owner); + assert(name); + log_zone_warning("RRSIG owned by: %s cannot be added to " + "its RRSet, because their TTLs differ. " + "Changing TTL to value=%d.\n", + name, tmp_rrset->ttl); + free(name); + } + + ret = knot_zone_contents_add_rrsigs(zone, rrsig, &tmp_rrset, &node, + KNOT_RRSET_DUPL_MERGE, 1); + if (ret < 0) { + dbg_zp("zp: find_rr_for_sig: Cannot add RRSIG.\n"); + return KNOT_EINVAL; + } else if (ret > 0) { + knot_rrset_deep_free(&rrsig, 0, 0); } - dbg_zload_detail("zload: load_rrsig: Class=%d\n", rrset_class); + + knot_dname_release(tmp_rrset->owner); - if (!fread_wrapper(&rrset_ttl, sizeof(rrset_ttl), 1, f)) { - dbg_zload("zload: load_rrsig: Cannot read TTL.\n"); - return NULL; - } - dbg_zload_detail("zload: load_rrsig: TTL=%d\n", rrset_ttl); + assert(tmp_rrset->rrsigs != NULL); - if (!fread_wrapper(&rdata_count, sizeof(rdata_count), 1, f)) { - dbg_zload("zload: load_rrsig: Cannot read rdata count.\n"); - return NULL; - } + return KNOT_EOK; +} - rrsig = knot_rrset_new(NULL, rrset_type, rrset_class, rrset_ttl); - if (rrsig == NULL) { - dbg_zload("zload: load_rrsig: Cannot create new RRSIG.\n"); +static knot_node_t *create_node(knot_zone_contents_t *zone, + knot_rrset_t *current_rrset, + int (*node_add_func)(knot_zone_contents_t *zone, knot_node_t *node, + int create_parents, uint8_t, int), + knot_node_t *(*node_get_func)(const knot_zone_contents_t *zone, + const knot_dname_t *owner)) +{ + dbg_zp_verb("zp: create_node: Creating node using RRSet: %p.\n", + current_rrset); + knot_node_t *node = + knot_node_new(current_rrset->owner, NULL, 0); + if (node_add_func(zone, node, 1, 0, 1) != 0) { return NULL; } + + assert(current_rrset->owner == node->owner); - knot_rdata_t *tmp_rdata = NULL; - - dbg_zload_detail("zload: load_rrsig: Loading %d rdata entries.\n", - rdata_count); + return node; +} - for (int i = 0; i < rdata_count; i++) { - tmp_rdata = knot_load_rdata(KNOT_RRTYPE_RRSIG, f, - id_array, use_ids); - if (tmp_rdata) { - int ret = knot_rrset_add_rdata(rrsig, tmp_rdata); - if (ret != KNOT_EOK) { - dbg_zload("zload: load_rrsig: Cannot " - "add RDATA\n."); - knot_rrset_deep_free(&rrsig, 0, 1, 1); - return NULL; - } - } else { - dbg_zload("zload: load_rrsig: Cannot load rdata.\n"); - knot_rrset_deep_free(&rrsig, 0, 1, 1); - return NULL; +static void process_rrsigs_in_node(parser_context_t *parser, + knot_zone_contents_t *zone, + knot_node_t *node) +{ + dbg_zp_verb("zp: process_rrsigs: Processing RRSIGS in node: %p.\n", + node); + rrset_list_t *tmp = parser->node_rrsigs; + while (tmp != NULL) { + if (find_rrset_for_rrsig_in_node(zone, node, + tmp->data) != KNOT_EOK) { + fprintf(stderr, "Could not add RRSIG to zone!\n"); + return; } + tmp = tmp->next; } - - dbg_zload_detail("zload: load_rrsig: RRSIG loaded successfully.\n"); - return rrsig; } -/*! - * \brief Loads RRSet from binary file. - * - * \param f File to read from. - * - * \return pointer to created and read RRSet on success, NULL otherwise. - */ -static knot_rrset_t *knot_load_rrset(void *f, knot_dname_t **id_array, - int use_ids) +static void process_error(const scanner_t *s) { - if (f == NULL) { - dbg_zload("zload: load_rrset: NULL arguments.\n"); - return NULL; - } - - int (*fread_wrapper)(void *dst, size_t size, size_t n, void *source); - if (use_ids) { - fread_wrapper = fread_safe_from_file; + err_count++; + if (s->stop == true) { + printf("ERROR=%s\n", knot_strerror(s->error_code)); } else { - fread_wrapper = read_from_stream; - } - - knot_rrset_t *rrset = NULL; - - uint16_t rrset_type = 0; - uint16_t rrset_class = 0; - uint32_t rrset_ttl = 0; - - uint32_t rdata_count = 0; - uint8_t rrsig_count = 0; - - knot_dname_t *owner = NULL; - - if (!use_ids) { - dbg_zload_detail("zload: load_rrset: " - "Loading owner of new RRSet from wire.\n"); - owner = read_dname_with_id(f, use_ids); - if (owner == NULL) { - dbg_zload("zload: load_rrset: Cannot load owner.\n"); - return NULL; - } + printf("WARNG=%s\n", knot_strerror(s->error_code)); } + fflush(stdout); +} - if (!fread_wrapper(&rrset_type, sizeof(rrset_type), 1, f)) { - dbg_zload("zload: load_rrset: Cannot load RRSet type.\n"); - if (!use_ids) { - knot_dname_free(&owner); +// TODO this could be a part of the cycle below, but we'd need a buffer. +static size_t calculate_item_size(const knot_rrset_t *rrset, + const scanner_t *scanner) +{ + const rdata_descriptor_t *desc = get_rdata_descriptor(rrset->type); + assert(desc); + size_t size = 0; + for (int i = 0; desc->block_types[i] != KNOT_RDATA_WF_END; i++) { + int item = desc->block_types[i]; + if (descriptor_item_is_dname(item)) { + size += sizeof(knot_dname_t *); + } else if (descriptor_item_is_fixed(item)) { + assert(item == scanner->r_data_blocks[i + 1] - + scanner->r_data_blocks[i]); + size += item; + } else if (descriptor_item_is_remainder(item)) { + size += scanner->r_data_blocks[i + 1] - + scanner->r_data_blocks[i]; + } else { + //naptr + assert(0); } - return NULL; } - dbg_zload_detail("zload: load_rrset: Type=%u\n", rrset_type); - if (!fread_wrapper(&rrset_class, sizeof(rrset_class), 1, f)) { - dbg_zload("zload: load_rrset: Cannot load RRSet class.\n"); - if (!use_ids) { - knot_dname_free(&owner); - } - return NULL; - } - dbg_zload_detail("zload: load_rrset: Class=%u\n", rrset_class); - if (!fread_wrapper(&rrset_ttl, sizeof(rrset_ttl), 1, f)) { - dbg_zload("zload: load_rrset: Cannot load RRSet TTL.\n"); - if (!use_ids) { - knot_dname_free(&owner); - } - return NULL; - } - dbg_zload_detail("zload: load_rrset: TTL=%u\n", rrset_ttl); - if (!fread_wrapper(&rdata_count, sizeof(rdata_count), 1, f)) { - if (!use_ids) { - knot_dname_free(&owner); - } - return NULL; - } - dbg_zload_detail("zload: load_rrset: rdata count=%u\n", rdata_count); - if (!fread_wrapper(&rrsig_count, sizeof(rrsig_count), 1, f)) { - if (!use_ids) { - knot_dname_free(&owner); - } - return NULL; - } - dbg_zload_detail("zload: load_rrset: RRSIG count=%u\n", rrsig_count); - -dbg_zload_exec_detail( - char *name = knot_dname_to_str(owner); - dbg_zload_detail("zload: load_rrset: Loading RRSet owned by: %s.\n", - name); - free(name); -); + return size; +} - rrset = knot_rrset_new(owner, rrset_type, rrset_class, rrset_ttl); +static int add_rdata_to_rr(knot_rrset_t *rrset, const scanner_t *scanner) +{ if (rrset == NULL) { - dbg_zload("zload: load_rrset: Could not create rrset."); - knot_dname_free(&owner); - return NULL; + dbg_zp("zp: add_rdata_to_rr: No RRSet.\n"); + return KNOT_EINVAL; } - - if (!use_ids) { - /* Directly release if allocated locally. */ - knot_dname_release(owner); - owner = NULL; + + const rdata_descriptor_t *desc = + get_rdata_descriptor(knot_rrset_type(rrset)); + assert(desc); + + dbg_zp_detail("zp: add_rdata_to_rr: Adding type %d, RRSet has %d RRs.\n", + rrset->type, rrset->rdata_count); + + size_t rdlen = calculate_item_size(rrset, scanner); + size_t offset = 0; + uint8_t *rdata = knot_rrset_create_rdata(rrset, rdlen); + if (rdata == NULL) { + dbg_zp("zp: create_rdata: Could not create RR.\n"); + return KNOT_ENOMEM; } - - dbg_zload_detail("zload: load_rrset: RRSet type=%d\n", rrset->type); - - knot_rdata_t *tmp_rdata = NULL; - - for (int i = 0; i < rdata_count; i++) { - tmp_rdata = knot_load_rdata(rrset->type, f, - id_array, use_ids); - if (tmp_rdata) { - int ret = knot_rrset_add_rdata(rrset, tmp_rdata); - if (ret != KNOT_EOK) { - dbg_zload("zload: load_rrset: Cannot add " - "RDATA.\n"); - knot_rrset_deep_free(&rrset, 0, 1, 1); - return NULL; + + for (int i = 0; desc->block_types[i] != KNOT_RDATA_WF_END; i++) { + int item = desc->block_types[i]; + if (descriptor_item_is_dname(item)) { + /* TODO another function perhaps? */ + knot_dname_t *dname = + knot_dname_new_from_wire(scanner->r_data + + scanner->r_data_blocks[i], + scanner->r_data_blocks[i + 1] - scanner->r_data_blocks[i], + NULL); + if (dname == NULL) { + //TODO handle + return KNOT_ERROR; } +dbg_zp_exec_detail( + char *name = knot_dname_to_str(dname); + dbg_zp_detail("zp: arr_rdata_to_rr: " + "Offset=%d:Adding dname=%s (%p)\n", + offset, name, dname); + free(name); +); + memcpy(rdata + offset, &dname, sizeof(knot_dname_t *)); + offset += sizeof(knot_dname_t *); + //parse dname from binary + } else if (descriptor_item_is_fixed(item)) { + //copy the whole thing + // TODO check the size + assert(item == scanner->r_data_blocks[i + 1] - + scanner->r_data_blocks[i]); + memcpy(rdata + offset, + scanner->r_data + scanner->r_data_blocks[i], + item); + offset += item; + } else if (descriptor_item_is_remainder(item)) { + //copy the rest + memcpy(rdata + offset, + scanner->r_data + scanner->r_data_blocks[i], + scanner->r_data_blocks[i + 1] - + scanner->r_data_blocks[i]); + offset += scanner->r_data_blocks[i + 1] - + scanner->r_data_blocks[i]; } else { - dbg_zload("zload: load_rrset: Cannot load rdata.\n"); - knot_rrset_deep_free(&rrset, 0, 1, 1); - return NULL; - } - } - - knot_rrset_t *tmp_rrsig = NULL; - - dbg_zload_detail("zload: load_rrset: Reading: %d RRSIGs.\n", - rrsig_count); - if (rrsig_count) { - tmp_rrsig = knot_load_rrsig(f, id_array, use_ids); - if (tmp_rrsig == NULL) { - dbg_zload("zload: load_rrset: Cannot load RRSIG.\n"); - knot_rrset_deep_free(&rrset, 0, 1, 1); - return NULL; - } - if (!use_ids) { - knot_rrset_set_owner(tmp_rrsig, rrset->owner); + //NAPTR + assert(knot_rrset_type(rrset) == KNOT_RRTYPE_NAPTR); + assert(0); } } - - knot_rrset_set_rrsigs(rrset, tmp_rrsig); - - dbg_zload_detail("zload: load_rrset: Finished loading RRSet %p.\n", - rrset); - return rrset; + + return KNOT_EOK; } -/*! - * \brief Loads node from binary file. - * - * \param f File to read from. - * - * \return Pointer to created and read node on success, NULL otherwise. - */ -static knot_node_t *knot_load_node(FILE *f, knot_dname_t **id_array) +static void process_rr(const scanner_t *scanner) { - if (f == NULL || id_array == NULL) { - dbg_zload("zload: load_node: Wrong parameters.\n"); - return NULL; + dbg_zp_detail("Owner from parser=%s\n", + scanner->r_owner); + rr_count++; + char add = 0; + parser_context_t *parser = scanner->data; + knot_zone_contents_t *contents = parser->current_zone; + /* Create rrset. TODO will not be always needed. */ + knot_dname_t *current_owner = NULL; + knot_rrset_t *current_rrset = NULL; + if (parser->last_node && + (scanner->r_owner_length == parser->last_node->owner->size) && + (strncmp((char *)parser->last_node->owner->name, + (char *)scanner->r_owner, scanner->r_owner_length) == 0)) { + // no need to create new dname; + current_owner = parser->last_node->owner; + // what about RRSet, do we need a new one? + current_rrset = knot_node_get_rrset(parser->last_node, + scanner->r_type); + if (current_rrset == NULL) { + add = 1; + new_rr_count++ ; + current_rrset = + knot_rrset_new(current_owner, + scanner->r_type, + scanner->r_class, + scanner->r_ttl); + } + } else { + add = 1; +// if (strncmp((char *)parser->last_node->owner->name, +// (char *)scanner->r_owner, scanner->r_owner_length)) { +// new_dname_count++; +// current_owner = +// knot_dname_new_from_wire(scanner->r_owner, +// scanner->r_owner_length, +// NULL); +// } else { +// current_owner = parser->last_node->owner; +// } + current_owner = + knot_dname_new_from_wire(scanner->r_owner, + scanner->r_owner_length, + NULL); + new_rr_count++; + new_dname_count++; + current_rrset = + knot_rrset_new(current_owner, + scanner->r_type, + scanner->r_class, + scanner->r_ttl); + knot_dname_release(current_owner); } - int (*fread_wrapper)(void *dst, size_t size, size_t n, void *source); - fread_wrapper = fread_safe_from_file; + assert(current_owner); + parser->current_rrset = current_rrset; + assert(current_rrset); - uint8_t flags = 0; - knot_node_t *node = NULL; - uint32_t parent_id = 0; - uint32_t nsec3_node_id = 0; - uint16_t rrset_count = 0; - uint32_t dname_id = 0; + int ret = add_rdata_to_rr(current_rrset, scanner); + assert(ret == 0); + + dbg_zp_verb("zp: process_rr: Processing type: %s.\n", + knot_rrtype_to_string(parser->current_rrset->type)); + dbg_zp_verb("zp: process_rr: RDATA count: %d.\n",\ + parser->current_rrset->rdata->count); - /* At the beginning of node - just dname_id !!!.*/ - if (!fread_wrapper(&dname_id, sizeof(dname_id), 1, f)) { - dbg_zload("zload: load_node: Cannot read owner ID.\n"); - return NULL; - } + assert(current_rrset->rdata_count); - if (!fread_wrapper(&parent_id, sizeof(parent_id), 1, f)) { - dbg_zload("zload: load_node: Cannot read owner ID.\n"); - return NULL; - } + int (*node_add_func)(knot_zone_contents_t *, knot_node_t *, int, + uint8_t, int); + knot_node_t *(*node_get_func)(const knot_zone_contents_t *, + const knot_dname_t *); - if (!fread_wrapper(&flags, sizeof(flags), 1, f)) { - dbg_zload("zload: load_node: Cannot read node flags.\n"); - return NULL; - } - if (!fread_wrapper(&nsec3_node_id, sizeof(nsec3_node_id), 1, f)) { - dbg_zload("zload: load_node: Cannot read NSEC3 node.\n"); - return NULL; - } + /* If we have RRSIG of NSEC3 type first node will have + * to be created in NSEC3 part of the zone */ - if (!fread_wrapper(&rrset_count, sizeof(rrset_count), 1, f)) { - dbg_zload("zload: load_node: Cannot read rrset count.\n"); - return NULL; - } - knot_dname_t *owner = id_array[dname_id]; - if (owner == NULL) { - dbg_zload("zload: load_node: Wrong dname ID, cannot load.\n"); - return NULL; + uint16_t type_covered = 0; + if (current_rrset->type == KNOT_RRTYPE_RRSIG) { + type_covered = + knot_rrset_rdata_rrsig_type_covered(current_rrset); } - dbg_zload_detail("zload: load_node: Node owner id: %d.\n", dname_id); -dbg_zload_exec_detail( - char *name = knot_dname_to_str(owner); - dbg_zload_detail("zload: load_node: Node owned by: %s.\n", name); - free(name); -); - dbg_zload_detail("zload: load_node: Number of RRSets in a node: %d.\n", - rrset_count); - - node = owner->node; - - if (node == NULL) { - dbg_zload("zload: load_node: NULL node, cannot proceed.\n"); - return NULL; - } - /* XXX can it be 0, ever? I think not. */ - if (nsec3_node_id != 0) { - knot_node_set_nsec3_node(node, id_array[nsec3_node_id]->node); + if (current_rrset->type != KNOT_RRTYPE_NSEC3 && + type_covered != KNOT_RRTYPE_NSEC3) { + node_add_func = &knot_zone_contents_add_node; + node_get_func = &knot_zone_contents_get_node; } else { - knot_node_set_nsec3_node(node, NULL); + node_add_func = &knot_zone_contents_add_nsec3_node; + node_get_func = &knot_zone_contents_get_nsec3_node; + } + + if (current_rrset->type == KNOT_RRTYPE_SOA) { + if (knot_node_rrset(knot_zone_contents_apex(contents), + KNOT_RRTYPE_SOA) != NULL) { + /* Receiving another SOA. */ + if (!knot_rrset_equal(current_rrset, + knot_node_rrset(knot_zone_contents_apex(contents), + KNOT_RRTYPE_SOA), KNOT_RRSET_COMPARE_WHOLE)) { + log_zone_error("Extra SOA record in the " + "zone.\n"); + /*!< \todo consider a new error */ + parser->ret = KNOT_EBADZONE; + return; + } else { + log_zone_warning("encountered identical " + "extra SOA record"); + parser->ret = KNOT_EOK; + return; + } + } } - /* Retain new owner while releasing replaced owner. */ - knot_node_set_owner(node, owner); - node->flags = flags; - - //XXX will have to be set already...canonical order should do it + /*!< \todo Make sure the maximum RDLENGTH does not exceed 65535 bytes.*/ - if (parent_id != 0) { - knot_node_set_parent(node, id_array[parent_id]->node); - assert(knot_node_parent(node) != NULL); - } else { - knot_node_set_parent(node, NULL); + if (current_rrset->type == KNOT_RRTYPE_SOA) { + if (knot_dname_compare(current_rrset->owner, + parser->origin_from_config) != 0) { + log_zone_error("SOA record has a different " + "owner than the one specified " + "in config! \n"); + /* Such SOA cannot even be added, because + * it would not be in the zone apex. */ + /*!< \todo consider a new error */ + parser->ret = KNOT_EBADZONE; + return; + } } - knot_rrset_t *tmp_rrset = NULL; + if (current_rrset->type == KNOT_RRTYPE_RRSIG) { + knot_rrset_t *tmp_rrsig = current_rrset; - for (int i = 0; i < rrset_count; i++) { - if ((tmp_rrset = knot_load_rrset(f, id_array, 1)) == NULL) { - knot_node_free(&node); - /*!< \todo #1686 - * Refactor freeing, might not be enough. + if (parser->last_node && + knot_dname_compare(parser->last_node->owner, + current_rrset->owner) != 0) { + /* RRSIG is first in the node, so we have to create it + * before we return */ - dbg_zload("zload: load_node: Cannot load RRSet.\n"); - return NULL; - } - /* Retain new owner while releasing replaced owner. */ - knot_rrset_set_owner(tmp_rrset, node->owner); - if (tmp_rrset->rrsigs != NULL) { - knot_rrset_set_owner(tmp_rrset->rrsigs, node->owner); - } - if (knot_node_add_rrset(node, tmp_rrset, 0) < 0) { - dbg_zload("zload: load_node: Cannot add RRSet " - "to node.\n"); - return NULL; + if (parser->node_rrsigs != NULL) { + process_rrsigs_in_node(parser, + contents, + parser->last_node); + rrset_list_delete(&parser->node_rrsigs); + } + + /* The node might however been created previously. */ + parser->last_node = + knot_zone_contents_get_node(contents, + knot_rrset_owner(current_rrset)); + + if (parser->last_node == NULL) { + /* Try NSEC3 tree. */ + if (current_rrset->type == KNOT_RRTYPE_NSEC3 || + current_rrset->type == KNOT_RRTYPE_RRSIG) { + parser->last_node = + knot_zone_contents_get_nsec3_node( + contents, + knot_rrset_owner( + current_rrset)); + } + } + + if (parser->last_node == NULL) { + /* Still NULL, node has to be created. */ + if ((parser->last_node = create_node(contents, + current_rrset, node_add_func, + node_get_func)) == NULL) { + knot_rrset_free(&tmp_rrsig); + dbg_zp("zp: process_rr: Cannot " + "create new node.\n"); + log_zone_error("None cannot be created.\n"); + /*!< \todo consider a new error */ + parser->ret = KNOT_ERROR; + return; + } + } } - } - assert(node != NULL); - dbg_zload_detail("zload: load_node: Node loaded: %p\n", node); - return node; -} -/*! - * \brief Finds and sets wildcard child for given node's owner. - * - * \param zone Current zone. - * \param node Node to be used. - * \param nsec3 Is NSEC3 node. - */ -static void find_and_set_wildcard_child(knot_zone_contents_t *zone, - knot_node_t *node, int nsec3) -{ - if (zone == NULL || node == NULL) { - dbg_zload("zload: set_wc: Bad arguments.\n"); + if (rrset_list_add(&parser->node_rrsigs, tmp_rrsig) != 0) { + dbg_zp("zp: process_rr: Cannot " + "create new node.\n"); + parser->ret = KNOT_ERROR; + return; + } + + dbg_zp_verb("zp: process_rr: RRSIG proccesed successfully.\n"); + parser->ret = KNOT_EOK; return; } - knot_dname_t *chopped = knot_dname_left_chop(node->owner); - knot_node_t *wildcard_parent; - if (!nsec3) { - wildcard_parent = - knot_zone_contents_get_node(zone, chopped); - } else { - wildcard_parent = - knot_zone_contents_get_nsec3_node(zone, chopped); - } - - /* Directly discard. */ - knot_dname_free(&chopped); - - assert(wildcard_parent); /* it *has* to be there */ + + /*! \todo Move RRSIG and RRSet handling to funtions. */ + assert(current_rrset->type != KNOT_RRTYPE_RRSIG); - knot_node_set_wildcard_child(wildcard_parent, node); -} + knot_node_t *node = NULL; + /* \note this could probably be much simpler */ + if (parser->last_node && current_rrset->type != KNOT_RRTYPE_SOA && + knot_dname_compare(parser->last_node->owner, + current_rrset->owner) == + 0) { + node = parser->last_node; + } else { + if (parser->last_node && parser->node_rrsigs) { + process_rrsigs_in_node(parser, + contents, + parser->last_node); + } -/*! - * \brief Checks if magic string at the beginning of the file is the same - * as defined. - * - * \param f File to read magic string from. - * \param MAGIC Magic string. - * \param MAGIC_LENGTH Length of magic string. - * - * \retval 1 if magic is the same. - * \retval 0 otherwise. - */ -static int knot_check_magic(FILE *f, const uint8_t* MAGIC, uint MAGIC_LENGTH) -{ - uint8_t tmp_magic[MAGIC_LENGTH]; - - int (*fread_wrapper)(void *dst, size_t size, size_t n, void *source); - fread_wrapper = fread_safe_from_file; + rrset_list_delete(&parser->node_rrsigs); - if (!fread_wrapper(&tmp_magic, sizeof(uint8_t), MAGIC_LENGTH, f)) { - return 0; + /* new node */ + node = node_get_func(contents, current_rrset->owner); } - for (int i = 0; i < MAGIC_LENGTH; i++) { - if (tmp_magic[i] != MAGIC[i]) { - return 0; + if (node == NULL) { + if (parser->last_node && parser->node_rrsigs) { + process_rrsigs_in_node(parser, + contents, + parser->last_node); } - } - return 1; -} - -static unsigned long calculate_crc(FILE *f) -{ - crc_t crc = crc_init(); - /* Get file size. */ - fseek(f, 0L, SEEK_END); - size_t file_size = ftell(f); - fseek(f, 0L, SEEK_SET); - - int (*fread_wrapper)(void *dst, size_t size, size_t n, void *source); - fread_wrapper = fread_safe_from_file; - - const size_t chunk_size = 4096; - /* read chunks of 4 kB */ - size_t read_bytes = 0; - /* Prealocate chunk */ - unsigned char *chunk = malloc(sizeof(unsigned char) * chunk_size); - CHECK_ALLOC_LOG(chunk, 0); - while ((file_size - read_bytes) > chunk_size) { - if (!fread_wrapper(chunk, - sizeof(unsigned char), chunk_size, f)) { - dbg_zload("zload: calculate_crc: Failed to read " - "data chunk.\n"); - free(chunk); - return 0; + if ((node = create_node(contents, current_rrset, + node_add_func, + node_get_func)) == NULL) { + dbg_zp("zp: process_rr: Cannot " + "create new node.\n"); + /*!< \todo consider a new error */ + log_zone_error("Cannot create new node.\n"); + parser->ret = KNOT_ERROR; + return; } - crc = crc_update(crc, chunk, - sizeof(unsigned char) * chunk_size); - read_bytes += chunk_size; } - - /* Read the rest of the file */ - if (!fread_wrapper(chunk, sizeof(unsigned char), file_size - read_bytes, - f)) { - dbg_zload("zload: calculate_crc: Failed to read " - "data remainder.\n"); - free(chunk); - return 0; + +// rrset = knot_node_get_rrset(node, current_rrset->type); +// if (!rrset) { +// rrset = current_rrset; +// } else { +// merged = 1; +// } +/// if (!rrset) { +// int ret = knot_rrset_deep_copy(current_rrset, &rrset, 1); +// if (ret != KNOT_EOK) { +// dbg_zp("zp: Cannot copy RRSet.\n"); +// return ret; +// } +// rrset = knot_rrset_new(current_rrset->owner, +// current_rrset->type, +// current_rrset->rclass, +// current_rrset->ttl); +// if (rrset == NULL) { +// dbg_zp("zp: process_rr: Cannot " +// "create new RRSet.\n"); +// return KNOTDZCOMPILE_ENOMEM; +// } + +// if (knot_rrset_add_rdata(rrset, current_rrset->rdata) != 0) { +// knot_rrset_free(&rrset); +// dbg_zp("zp: process_rr: Cannot " +// "add RDATA to RRSet.\n"); +// return KNOTDZCOMPILE_EBRDATA; +// } + + /* Selected merge option does not really matter here. */ +// if (knot_zone_contents_add_rrset(contents, current_rrset, &node, +// KNOT_RRSET_DUPL_MERGE, 1) < 0) { +// knot_rrset_free(&rrset); +// dbg_zp("zp: process_rr: Cannot " +// "add RDATA to RRSet.\n"); +// return KNOTDZCOMPILE_EBRDATA; +// } +// } else { +// TODO needs solving +// if (current_rrset->type != +// KNOT_RRTYPE_RRSIG && rrset->ttl != +// current_rrset->ttl) { +// fprintf(stderr, +// "TTL does not match the TTL of the RRSet. " +// "Changing to %d.\n", rrset->ttl); +// } + + if (add) { + ret = knot_zone_contents_add_rrset(contents, current_rrset, + &node, + KNOT_RRSET_DUPL_MERGE, 1); + if (ret < 0) { + dbg_zp("zp: process_rr: Cannot " + "add RRSets.\n"); + /*!< \todo mixed error codes, has to be changed. */ + parser->ret = ret; + return; + } else if (ret > 0) { + knot_rrset_deep_free(¤t_rrset, 0, 0); + } } +// } - crc = crc_update(crc, chunk, - sizeof(unsigned char) * (file_size - read_bytes)); - free(chunk); - - fseek(f, 0L, SEEK_SET); - return (unsigned long)crc_finalize(crc); + parser->last_node = node; + + dbg_zp_verb("zp: process_rr: RRSet %p processed successfully.\n", + parser->current_rrset); + parser->ret = KNOT_EOK; } -int knot_zload_open(zloader_t **dst, const char *filename) +int knot_zload_open(zloader_t **dst, const char *source, const char *origin, + int semantic_checks) { - char crc_buf[65]; - - if (!dst || !filename) { + if (!dst || !source || !origin) { dbg_zload("zload: open: Bad arguments.\n"); return KNOT_EINVAL; } - int (*fread_wrapper)(void *dst, size_t size, size_t n, void *source); - fread_wrapper = fread_safe_from_file; - - *dst = 0; - - /* Open file for binary read. */ - FILE *f = fopen(filename, "rb"); - if (knot_unlikely(!f)) { - int reason = errno; - dbg_zload("knot_zload_open: failed to open '%s'\n", - filename); - switch (reason) { - case EACCES: return KNOT_EACCES; break; - case ENOENT: return KNOT_ENOENT; break; - case ENOMEM: return KNOT_ENOMEM; break; - default: break; - } - - return KNOT_EFEWDATA; // No such file or directory (POSIX.1) - } + *dst = NULL; + /* Create context. */ + parser_context_t *context = xmalloc(sizeof(parser_context_t)); + context->origin_from_config = knot_dname_new_from_str(origin, + strnlen((char *)origin, + 255), + NULL); + assert(context->origin_from_config); + context->last_node = knot_node_new(context->origin_from_config, + NULL, 0); + knot_zone_t *zone = knot_zone_new(context->last_node, 0, 0); + context->current_zone = knot_zone_get_contents(zone); + context->node_rrsigs = NULL; - /* Calculate file size. */ - fseek(f, 0L, SEEK_END); - size_t file_size = ftell(f); - fseek(f, 0L, SEEK_SET); - if (file_size < MAGIC_LENGTH) { - fclose(f); - return KNOT_EFEWDATA; - } - - /* Calculate CRC and compare with filename.crc file */ - unsigned long crc_calculated = calculate_crc(f); - - /* Read CRC from filename.crc file */ - char *crc_path = - malloc(sizeof(char) * - (strlen(filename) + 4 /* strlen(".crc") */ + 1)); - if (knot_unlikely(!crc_path)) { - fclose(f); - ERR_ALLOC_FAILED; - return KNOT_ENOMEM; - } - memcpy(crc_path, filename, strlen(filename)); - memcpy(crc_path + strlen(filename), ".crc", 4); - crc_path[strlen(filename) + 4] = '\0'; - - int f_crc = open(crc_path, O_RDONLY); - if (f_crc == -1) { - /* FIXME: Print strerror_r(errno) in dbg message */ - dbg_zload("knot_zload_open: failed to open '%s'\n", - crc_path); - free(crc_path); - fclose(f); - return KNOT_ECRC; - } - - ssize_t crc_read_bytes = 0; - crc_read_bytes = read(f_crc, crc_buf, 64); - if (crc_read_bytes == -1) { - /* FIXME: Print strerror_r(errno) in dbg message */ - dbg_zload("knot_zload_open: could not read " - "CRC from file '%s'\n", - crc_path); - free(crc_path); - close(f_crc); - fclose(f); - return KNOT_ECRC; - } - crc_buf[crc_read_bytes] = '\0'; - - unsigned long crc_from_file = 0; - errno = 0; - crc_from_file = strtoul(crc_buf, (char **) NULL, 10); - if (errno != 0) { - /* FIXME: Print strerror_r(errno) in dbg message */ - dbg_zload("knot_zload_open: could not convert " - "CRC from file '%s'\n", - crc_path); - close(f_crc); - fclose(f); - free(crc_path); - return KNOT_ERROR; - } - - /* Free some value and close the CRC file */ - free(crc_path); - close(f_crc); - - /* Check magic sequence. */ - static const uint8_t MAGIC[MAGIC_LENGTH] = MAGIC_BYTES; - if (!knot_check_magic(f, MAGIC, MAGIC_LENGTH)) { - fclose(f); - dbg_zload("knot_zload_open: magic bytes " - "in don't match '%*s' " - "(%s)\n", - (int)MAGIC_LENGTH, (const char*)MAGIC, filename); - return KNOT_EMALF; // Illegal byte sequence (POSIX.1, C99) - } - - /* Compare calculated and read CRCs. */ - if (crc_from_file != crc_calculated) { - dbg_zload("knot_zload_open: CRC failed for " - "file '%s'\n", - filename); - fclose(f); - return KNOT_ECRC; - } - - /* Read source file length. */ - uint32_t sflen = 0; - if (!fread_wrapper(&sflen, 1, sizeof(uint32_t), f)) { - dbg_zload("knot_zload_open: failed to read " - "sfile length\n"); - fclose(f); - return KNOT_ERROR; - } - - /* Read source file. */ - char *sfile = malloc(sflen); - if (!sfile) { - dbg_zload("knot_zload_open: invalid sfile " - "length %u\n", sflen); - fclose(f); - return KNOT_ENOMEM; - } - if (!fread_wrapper(sfile, 1, sflen, f)) { - dbg_zload("knot_zload_open: failed to read %uB " - "source file\n", - sflen); - free(sfile); - fclose(f); + /* Create file loader. */ + file_loader_t *loader = file_loader_create(source, origin, + KNOT_CLASS_IN, 3600, + process_rr, + process_error, + context); + if (loader == NULL) { + dbg_zload("Could not create file loader.\n"); return KNOT_ERROR; } /* Allocate new loader. */ - zloader_t *zl = malloc(sizeof(zloader_t)); - if (!zl) { - free(sfile); - fclose(f); - return KNOT_ENOMEM; - } - - dbg_zload("knot_zload_open: opened '%s' as fp %p " - "(source is '%s')\n", - filename, f, sfile); - zl->filename = strdup(filename); - zl->source = sfile; - zl->fp = f; + zloader_t *zl = xmalloc(sizeof(zloader_t)); + + zl->source = strdup(source); + zl->origin = strdup(origin); + zl->file_loader = loader; *dst = zl; return KNOT_EOK; } -static void cleanup_id_array(knot_dname_t **id_array, - const uint from, const uint to) -{ - if (id_array == NULL) { - dbg_zload("zload: cleanup_id_array: NULL arguments.\n"); - return; - } - - for (uint i = from; i < to; i++) { - if (id_array[i] != NULL) { - knot_dname_release(id_array[i]); - } - } - - free(id_array); -} - -static knot_dname_table_t *create_dname_table_from_array( - knot_dname_t **array, uint max_id) -{ - if (array == NULL) { - /* should I set errno or what ... ? */ - dbg_zload("zload: create_dname_table: No array passed.\n"); - return NULL; - } - - assert(array[0] == NULL); - - knot_dname_table_t *ret = knot_dname_table_new(); - CHECK_ALLOC_LOG(ret, NULL); - - /* Table will have max_id entries */ - for (uint i = 1; i < max_id; i++) { - assert(array[i]); - if (knot_dname_table_add_dname(ret, - array[i]) != KNOT_EOK) { -dbg_zload_exec_detail( - char *name = knot_dname_to_str(array[i]); - dbg_zload_detail("zload: create_dname_table: " - "Could not add dname: %s.\n", - name); - free(name); -); - dbg_zload("zload: create_dname_table: " - "Could not add dname.\n"); - knot_dname_table_deep_free(&ret); - return NULL; - } - } - - dbg_zload("zload: create_dname_table: Table loaded.\n"); - return ret; -} - -static knot_dname_t **create_dname_array(FILE *f, uint max_id) -{ - if (f == NULL) { - dbg_zload("zload: create_dname_array: Wrong arguments.\n"); - return NULL; - } - - knot_dname_t **array = - malloc(sizeof(knot_dname_t *) * ( max_id + 1)); - if (array == NULL) { - ERR_ALLOC_FAILED; - return NULL; - } - - memset(array, 0, sizeof(knot_dname_t *) * (max_id + 1)); - - for (uint i = 0; i < max_id - 1; i++) { - knot_dname_t *read_dname = read_dname_with_id(f, 1); - if (read_dname == NULL) { - dbg_zload("zload: create_dname_array: " - "Cannot read dname.\n" ); - cleanup_id_array(array, 0, i); - return NULL; - } - - if (read_dname->id < max_id) { - /* Create new node from dname. */ - read_dname->node = knot_node_new(read_dname, NULL, 0); - if (read_dname->node == NULL) { - dbg_zload("zload: create_dname_array: " - "Cannot create new node " - "from dname.\n"); - /* Release read dname. */ - knot_dname_release(read_dname); - cleanup_id_array(array, 0, i); - return NULL; - } - - /* Store reference to dname in array. */ - array[read_dname->id] = read_dname; - } else { - /* Release read dname. */ - dbg_zload("zload: create_dname_array: " - "dname id is out of range.\n"); - knot_dname_release(read_dname); - cleanup_id_array(array, 0, i); - return NULL; - } - - } - - dbg_zload("zload: create_dname_array: Array created.\n"); - return array; -} - knot_zone_t *knot_zload_load(zloader_t *loader) { dbg_zload("zload: load: Loading zone, loader: %p.\n", loader); @@ -1209,243 +674,37 @@ knot_zone_t *knot_zload_load(zloader_t *loader) dbg_zload("zload: load: NULL loader!\n"); return NULL; } - - FILE *f = loader->fp; - - knot_node_t *tmp_node; - - uint32_t node_count; - uint32_t nsec3_node_count; - uint32_t auth_node_count; - int (*fread_wrapper)(void *dst, size_t size, size_t n, void *source); - fread_wrapper = fread_safe_from_file; + parser_context_t *c = loader->context; - if (!fread_wrapper(&node_count, sizeof(node_count), 1, f)) { - dbg_zload("zload: load: Cannot read node count!\n"); - return NULL; - } - - if (!fread_wrapper(&nsec3_node_count, sizeof(nsec3_node_count), 1, f)) { - dbg_zload("zload: load: Cannot read NSEC3 node count!\n"); - return NULL; + file_loader_process(loader->file_loader); + if (c->last_node && c->node_rrsigs) { + process_rrsigs_in_node(c, c->current_zone, c->last_node); } - if (!fread_wrapper(&auth_node_count, - sizeof(auth_node_count), 1, f)) { - dbg_zload("zload: load: Cannot read authoritative " - "node count!\n"); + if (c->ret != KNOT_EOK) { + log_zone_error("Zone could not be loaded (%d).", c->ret); + /*!< \todo Depending on the error, free stuff. */ + rrset_list_delete(&c->node_rrsigs); return NULL; } + knot_zone_contents_adjust(c->current_zone); + rrset_list_delete(&c->node_rrsigs); - dbg_zload_verb("zload: load: Authoritative nodes: %u.\n", - auth_node_count); - dbg_zload_verb("zload: load: :oading %u nodes.\n", node_count); - - uint32_t total_dnames = 0; - /* First, read number of dnames in dname table. */ - if (!fread_wrapper(&total_dnames, sizeof(total_dnames), 1, f)) { - return NULL; - } - - dbg_zload_verb("zload: load: Total dname count: %d.\n", total_dnames); - - /* Create id array. */ - knot_dname_t **id_array = create_dname_array(f, total_dnames); - if (id_array == NULL) { - dbg_zload("zload: load: Cannot create ID array.\n"); - return NULL; - } - - knot_dname_table_t *dname_table = - create_dname_table_from_array(id_array, total_dnames); - if (dname_table == NULL) { - dbg_zload("zload: load: Cannot create ID array.\n"); - cleanup_id_array(id_array, 1, total_dnames); - free(dname_table); - return NULL; - } - - knot_node_t *apex = knot_load_node(f, id_array); - - if (!apex) { - dbg_zload("zone: Could not load apex node (in %s)\n", - loader->filename); - cleanup_id_array(id_array, 1, - node_count + nsec3_node_count + 1); - free(dname_table); - return NULL; - } - - dbg_zload_verb("zload: load: Apex node loaded: %p.\n", apex); - - knot_zone_t *zone = knot_zone_new(apex, auth_node_count, 0); - if (zone == NULL) { - cleanup_id_array(id_array, 1, - node_count + nsec3_node_count + 1); - dbg_zload("zload: load: Failed to create new " - "zone from apex!\n"); - knot_node_free(&apex); - free(dname_table); - return NULL; - } - - knot_zone_contents_t *contents = knot_zone_get_contents(zone); - assert(contents); - - /* Assign dname table to the new zone. */ - contents->dname_table = dname_table; - - knot_node_set_previous(apex, NULL); - knot_node_t *last_node = 0; - last_node = apex; - - int ret = 0; - - for (uint i = 1; i < node_count; i++) { - tmp_node = knot_load_node(f, id_array); - if (tmp_node != NULL) { - dbg_zload_detail("zload: load: Adding node owned by: " - "%s\n.", - knot_dname_to_str(tmp_node->owner)); - if ((ret = knot_zone_contents_add_node(contents, - tmp_node, - 0, 0, 0)) != 0) { - cleanup_id_array(id_array, 1, - node_count + - nsec3_node_count + 1); - knot_zone_deep_free(&zone, 0); - dbg_zload("zload: load: Failed to add node " - "to zone: %s.\n", knot_strerror(ret)); - return NULL; - } - - if (knot_dname_is_wildcard(tmp_node->owner)) { - find_and_set_wildcard_child(contents, - tmp_node, 0); - } - - knot_node_set_previous(tmp_node, last_node); - - if (tmp_node->rrset_count && - (knot_node_is_deleg_point(tmp_node) || - !knot_node_is_non_auth(tmp_node))) { - last_node = tmp_node; - } - - } else { - dbg_zload("zload: load: Node error (in %s).\n", - loader->filename); - knot_zone_deep_free(&zone, 0); - cleanup_id_array(id_array, node_count + 1, - nsec3_node_count + 1); - return NULL; - } - } - - assert(knot_node_previous(knot_zone_contents_apex(contents)) == NULL); - - knot_node_set_previous(knot_zone_contents_get_apex(contents), - last_node); - - dbg_zload_detail("zload: load: Loading %u nsec3 nodes\n", - nsec3_node_count); - - knot_node_t *nsec3_first = NULL; - - if (nsec3_node_count > 0) { - nsec3_first = knot_load_node(f, id_array); - if (nsec3_first == NULL) { - log_zone_error("Cannot load NSEC3 data, " - "zone database is probably corrupt.\n"); - } - - if ((ret = knot_zone_contents_add_nsec3_node(contents, - nsec3_first, - 0, 0, 0)) != 0) { - dbg_zload("zload: load: " - "cannot add first nsec3 node, " - "exiting: %s.\n", knot_strerror(ret)); - knot_zone_deep_free(&zone, 0); - cleanup_id_array(id_array, node_count + 1, - nsec3_node_count + 1); - log_zone_error("Cannot store NSEC3 data, " - "zone database is probably corrupt.\n"); - return NULL; - } - - knot_node_set_previous(nsec3_first, NULL); - last_node = nsec3_first; - } - - for (uint i = 1; i < nsec3_node_count; i++) { - tmp_node = knot_load_node(f, id_array); - - if (tmp_node != NULL) { - if ((ret = knot_zone_contents_add_nsec3_node(contents, - tmp_node, 0, 0, 0)) != 0) { - dbg_zload("zload: load: Cannot add " - "NSEC3 node: %s.\n", - knot_strerror(ret)); - knot_zone_deep_free(&zone, 0); - cleanup_id_array(id_array, node_count + 1, - nsec3_node_count + 1); - return NULL; - } - - knot_node_set_previous(tmp_node, last_node); - - last_node = tmp_node; - } else { - log_zone_error("Cannot load NSEC3 node. " - "Zone database is probably " - "currupted.\n"); - knot_zone_deep_free(&zone, 0); - cleanup_id_array(id_array, node_count + 1, - nsec3_node_count + 1); - return NULL; - } - } - - if (nsec3_node_count) { - assert(knot_node_previous(nsec3_first) == NULL); - knot_node_set_previous(nsec3_first, last_node); - } - - /* ID array is now useless */ - for (uint i = 1; i < total_dnames; i++) { - /* Added to table, may discard now. */ - knot_dname_release(id_array[i]); - } - free(id_array); - - dbg_zload("zload: load: Zone loaded, returning: %p,\n", zone); - return zone; + return c->current_zone->zone; } int knot_zload_needs_update(zloader_t *loader) { + assert(0); if (!loader) { return 1; } - /* Check if the source still exists. */ - struct stat st_src; - if (stat(loader->source, &st_src) != 0) { - return 1; - } - - /* Check if the compiled file still exists. */ - struct stat st_bin; - if (stat(loader->filename, &st_bin) != 0) { - return 1; - } - - /* Compare the mtime of the source and file. */ /*! \todo Inspect types on Linux. */ - if (timet_cmp(st_bin.st_mtime, st_src.st_mtime) < 0) { - return 1; - } +// if (timet_cmp(st_bin.st_mtime, st_src.st_mtime) < 0) { +// return 1; +// } return 0; } @@ -1455,37 +714,10 @@ void knot_zload_close(zloader_t *loader) if (!loader) { return; } + + file_loader_free(loader->file_loader); - free(loader->filename); free(loader->source); - fclose(loader->fp); + free(loader->origin); free(loader); } - -int knot_zload_rrset_deserialize(knot_rrset_t **rrset, - uint8_t *stream, size_t *size) -{ - if (stream == NULL || size == 0) { - dbg_zload("zload: rrset_deserialize: Bad arguments.\n"); - return KNOT_EINVAL; - } - - load_stream_t data; - data.stream = stream; - data.stream_remaining = *size; - data.stream_size = *size; - - knot_rrset_t *ret = knot_load_rrset(&data, NULL, 0); - if (ret == NULL) { - dbg_zload("zload: rrset_deserialize: Cannot load RRSet.\n"); - return KNOT_EMALF; - } - - *size = data.stream_remaining; - *rrset = ret; - - dbg_zload_detail("zload: rrset_deserialize: RRSet deserialized " - "successfully.\n"); - return KNOT_EOK; -} - diff --git a/src/knot/zone/zone-load.h b/src/knot/zone/zone-load.h index 837d5f267d9366a16be5dad2c6b6a144bc844aaf..763f406abd0e7ed01bc46f8b62ecf84e67673c87 100644 --- a/src/knot/zone/zone-load.h +++ b/src/knot/zone/zone-load.h @@ -16,11 +16,11 @@ /*! * \file zone-load.h * + * \author Marek Vavrusa <marek.vavrusa@nic.cz> * \author Jan Kadlec <jan.kadlec@nic.cz> * - * \brief Loader of previously parsed zone + * \brief Zone loading * - * \addtogroup zone-load-dump * @{ */ @@ -30,15 +30,44 @@ #include <stdio.h> #include "libknot/zone/zone.h" +#include "zscanner/file_loader.h" + +#define MAGIC_LENGTH 8 +#define MAGIC "knotv130" + +/* TODO this structure is highly redundant, remove. Maybe use oh-so-great BIRD lists. */ +/*! + * \brief One-purpose linked list holding pointers to RRSets. + */ +struct rrset_list { + knot_rrset_t *data; /*!< List data. */ + struct rrset_list *next; /*!< Next node. */ +}; + +typedef struct rrset_list rrset_list_t; + + +struct parser_context { + rrset_list_t *node_rrsigs; + knot_zone_contents_t *current_zone; + knot_rrset_t *current_rrset; + knot_dname_t *origin_from_config; + knot_node_t *last_node; + int ret; +}; + +typedef struct parser_context parser_context_t; /*! * \brief Zone loader structure. */ typedef struct zloader_t { - char *filename; /*!< Compiled zone filename. */ char *source; /*!< Zone source file. */ - FILE *fp; /*!< Open filepointer to compiled zone. */ + char *origin; /*!< Zone's origin string. */ + int semantic_checks; /*!< Wanted level of semantic checks. */ + file_loader_t *file_loader;/*!< Scanner's file loader. */ + parser_context_t *context;/*!< Loader context. */ } zloader_t; @@ -51,7 +80,8 @@ typedef struct zloader_t * \retval Initialized loader on success. * \retval NULL on error. */ -int knot_zload_open(zloader_t **loader, const char *filename); +int knot_zload_open(zloader_t **loader, const char *source, const char *origin, + int semantic_checks); /*! * \brief Loads zone from a compiled and serialized zone file. @@ -71,9 +101,9 @@ knot_zone_t *knot_zload_load(zloader_t *loader); * \retval 1 is if needs to be recompiled. * \retval 0 if it is up to date. */ +//TODO will not work, has to look at serials probably int knot_zload_needs_update(zloader_t *loader); - /*! * \brief Free zone loader. * @@ -81,24 +111,6 @@ int knot_zload_needs_update(zloader_t *loader); */ void knot_zload_close(zloader_t *loader); -/*! - * \brief Loads RRSet serialized by knot_zdump_rrset_serialize(). - * - * \param stream Stream containing serialized RRSet. - * \param size Size of stream. This variable will contain remaining length of - * stream, once the function has ended. - * \param rrset Place for created RRSet. - * - * \note If RRSet contains RRSIGs, their owners are not copies, but only links - * to the owner of RRSet. All RDATA dnames are copied. - * - * \retval KNOT_EOK on success. - * \retval KNOT_EBADAG on wrong arguments. - * \retval KNOT_EMALF when stream is malformed. - */ -int knot_zload_rrset_deserialize(knot_rrset_t **rrset, - uint8_t *stream, size_t *size); - #endif /* _KNOTD_ZONELOAD_H_ */ /*! @} */ diff --git a/src/libknot/nameserver/name-server.c b/src/libknot/nameserver/name-server.c index 27ad3255d9055fd5991b2fc2ae8e36a2ee02a044..86c289a00a2f3b942a91010c57a4eaf542ccdd7e 100644 --- a/src/libknot/nameserver/name-server.c +++ b/src/libknot/nameserver/name-server.c @@ -24,6 +24,8 @@ #include "updates/xfr-in.h" #include "libknot.h" +#include "common/errcode.h" +#include "common.h" #include "util/debug.h" #include "packet/packet.h" #include "packet/response.h" diff --git a/src/libknot/packet/packet.c b/src/libknot/packet/packet.c index c1823a8c9e7b5c201ca6ea3908e9e8d59838ae79..04a48ec15808a213f0afe762548b05f9716540b4 100644 --- a/src/libknot/packet/packet.c +++ b/src/libknot/packet/packet.c @@ -15,6 +15,7 @@ */ #include <assert.h> +#include <stdlib.h> #include "packet/packet.h" #include "util/debug.h" diff --git a/src/libknot/updates/ddns.c b/src/libknot/updates/ddns.c index 5f0473db90e5b185d57af9b13b000984de7ec9ed..5441e122148b9e65952386ae74b7424f8446b2a7 100644 --- a/src/libknot/updates/ddns.c +++ b/src/libknot/updates/ddns.c @@ -15,11 +15,13 @@ */ #include <assert.h> +#include <stdlib.h> #include "updates/ddns.h" #include "updates/changesets.h" #include "util/debug.h" #include "packet/packet.h" +#include "common.h" #include "consts.h" #include "common/mempattern.h" #include "nameserver/name-server.h" // ns_serial_compare() - TODO: extract diff --git a/src/libknot/updates/xfr-in.c b/src/libknot/updates/xfr-in.c index 18a3948773080d7e136c32ad856dab63cf2e97d0..d93e92a54f17e2f65bd19ecad5a969d70a726c1b 100644 --- a/src/libknot/updates/xfr-in.c +++ b/src/libknot/updates/xfr-in.c @@ -26,6 +26,7 @@ #include "dname.h" #include "zone/zone.h" #include "packet/query.h" +#include "common.h" #include "updates/changesets.h" #include "tsig.h" #include "tsig-op.h" @@ -1244,8 +1245,6 @@ static void xfrin_zone_contents_free(knot_zone_contents_t **contents) knot_zone_tree_deep_free(&(*contents)->nsec3_nodes); knot_nsec3_params_free(&(*contents)->nsec3_params); - - knot_dname_table_deep_free(&(*contents)->dname_table); free(*contents); *contents = NULL; @@ -2418,27 +2417,6 @@ static void xfrin_switch_nodes_in_node(knot_node_t *node, void *data) /*----------------------------------------------------------------------------*/ -static void xfrin_switch_node_in_hash_table(ck_hash_table_item_t *item, - void *data) -{ - UNUSED(data); - - if (item == NULL) { - return; - } - - knot_node_t *node = (knot_node_t *)item->value; - knot_node_t *new_node = knot_node_get_new_node(node); - - assert(new_node != NULL); - - if (new_node != NULL) { - item->value = new_node; - } -} - -/*----------------------------------------------------------------------------*/ - static void xfrin_switch_node_in_dname_table(knot_dname_t *dname, void *data) { UNUSED(data); @@ -2505,8 +2483,6 @@ static void xfrin_zone_contents_free2(knot_zone_contents_t **contents) knot_nsec3_params_free(&(*contents)->nsec3_params); - knot_dname_table_deep_free(&(*contents)->dname_table); - free(*contents); *contents = NULL; } @@ -3010,12 +2986,10 @@ static int xfrin_remove_empty_nodes(knot_zone_contents_t *contents, dbg_xfrin_verb("OLD NSEC3 NODES COUNT: %d\n", changes->old_nsec3_count); // remove these nodes from both hash table and the tree - ck_hash_table_item_t *hash_item = NULL; knot_zone_tree_node_t *zone_node = NULL; for (int i = 0; i < changes->old_nodes_count; ++i) { zone_node = NULL; - hash_item = NULL; dbg_xfrin_exec_detail( char *name = knot_dname_to_str(knot_node_owner( @@ -3026,15 +3000,12 @@ dbg_xfrin_exec_detail( ); ret = knot_zone_contents_remove_node( - contents, changes->old_nodes[i], &zone_node, - &hash_item); + contents, changes->old_nodes[i], &zone_node); if (ret != KNOT_EOK) { dbg_xfrin("Failed to remove node from zone!\n"); return KNOT_ENONODE; } - - free(hash_item); free(zone_node); } diff --git a/src/libknot/zone/zone-contents.c b/src/libknot/zone/zone-contents.c index 55aa19cd7b559344307e3ecf729be2f342d5d0a3..3a325aa6199767c643b8c89d1a9579afa6561d84 100644 --- a/src/libknot/zone/zone-contents.c +++ b/src/libknot/zone/zone-contents.c @@ -948,17 +948,6 @@ knot_zone_contents_t *knot_zone_contents_new(knot_node_t *apex, goto cleanup; } - if (use_domain_table) { - dbg_zone_verb("Creating domain name table.\n"); - contents->dname_table = knot_dname_table_new(); - if (contents->dname_table == NULL) { - ERR_ALLOC_FAILED; - goto cleanup; - } - } else { - contents->dname_table = NULL; - } - //contents->node_count = node_count; /* Initialize NSEC3 params */ @@ -996,7 +985,6 @@ knot_zone_contents_t *knot_zone_contents_new(knot_node_t *apex, cleanup: dbg_zone_verb("Cleaning up.\n"); - free(contents->dname_table); free(contents->nodes); free(contents->nsec3_nodes); free(contents); @@ -1490,8 +1478,7 @@ int knot_zone_contents_add_nsec3_rrset(knot_zone_contents_t *zone, /*----------------------------------------------------------------------------*/ int knot_zone_contents_remove_node(knot_zone_contents_t *contents, - const knot_node_t *node, knot_zone_tree_node_t **removed_tree, - ck_hash_table_item_t **removed_hash) + const knot_node_t *node, knot_zone_tree_node_t **removed_tree) { if (contents == NULL || node == NULL) { return KNOT_EINVAL; @@ -2210,14 +2197,6 @@ knot_zone_tree_t *knot_zone_contents_get_nsec3_nodes( /*----------------------------------------------------------------------------*/ -ck_hash_table_t *knot_zone_contents_get_hash_table( - knot_zone_contents_t *contents) -{ - return contents->table; -} - -/*----------------------------------------------------------------------------*/ - /*----------------------------------------------------------------------------*/ int knot_zone_contents_shallow_copy(const knot_zone_contents_t *from, @@ -2271,7 +2250,6 @@ int knot_zone_contents_shallow_copy(const knot_zone_contents_t *from, cleanup: knot_zone_tree_free(&contents->nodes); knot_zone_tree_free(&contents->nsec3_nodes); - free(contents->dname_table); free(contents); return ret; } @@ -2329,7 +2307,6 @@ int knot_zone_contents_shallow_copy2(const knot_zone_contents_t *from, cleanup: knot_zone_tree_free(&contents->nodes); knot_zone_tree_free(&contents->nsec3_nodes); - free(contents->dname_table); free(contents); return ret; } @@ -2348,8 +2325,6 @@ void knot_zone_contents_free(knot_zone_contents_t **contents) knot_nsec3_params_free(&(*contents)->nsec3_params); - knot_dname_table_free(&(*contents)->dname_table); - free(*contents); *contents = NULL; } diff --git a/src/libknot/zone/zone-contents.h b/src/libknot/zone/zone-contents.h index 67107566a8e18d21a18d98279feb027125184783..28e8ca7b21208d82a3f135d31f47ab0d20ed6c68 100644 --- a/src/libknot/zone/zone-contents.h +++ b/src/libknot/zone/zone-contents.h @@ -32,9 +32,7 @@ #include "zone/node.h" #include "dname.h" #include "nsec3.h" -#include "zone/dname-table.h" #include "common/tree.h" -#include "hash/cuckoo-hash-table.h" #include "zone-tree.h" @@ -45,12 +43,9 @@ struct knot_zone; typedef struct knot_zone_contents_t { knot_node_t *apex; /*!< Apex node of the zone (holding SOA) */ - ck_hash_table_t *table; /*!< Hash table for holding zone nodes. */ knot_zone_tree_t *nodes; knot_zone_tree_t *nsec3_nodes; - knot_dname_table_t *dname_table; - struct knot_zone *zone; knot_nsec3_params_t nsec3_params; @@ -58,7 +53,7 @@ typedef struct knot_zone_contents_t { /*! * \todo Unify the use of this field - authoritative nodes vs. all. */ - uint node_count; + size_t node_count; /*! \brief Various flags * @@ -80,7 +75,7 @@ typedef struct knot_zone_contents_t { /*----------------------------------------------------------------------------*/ knot_zone_contents_t *knot_zone_contents_new(knot_node_t *apex, - uint node_count, + size_t node_count, int use_domain_table, struct knot_zone *zone); @@ -181,8 +176,7 @@ int knot_zone_contents_add_nsec3_rrset(knot_zone_contents_t *contents, int use_domain_table); int knot_zone_contents_remove_node(knot_zone_contents_t *contents, - const knot_node_t *node, knot_zone_tree_node_t **removed_tree, - ck_hash_table_item_t **removed_hash); + const knot_node_t *node, knot_zone_tree_node_t **removed_tree); int knot_zone_contents_remove_nsec3_node(knot_zone_contents_t *contents, const knot_node_t *node, knot_zone_tree_node_t **removed); @@ -506,9 +500,6 @@ knot_zone_tree_t *knot_zone_contents_get_nodes( knot_zone_tree_t *knot_zone_contents_get_nsec3_nodes( knot_zone_contents_t *contents); -ck_hash_table_t *knot_zone_contents_get_hash_table( - knot_zone_contents_t *contents); - int knot_zone_contents_dname_table_apply(knot_zone_contents_t *contents, void (*function)(knot_dname_t *, void *), diff --git a/src/libknot/zone/zone-diff.c b/src/libknot/zone/zone-diff.c index 16a9c108db6bc39f90fab2033ab8fea3f72d85dc..0da8277c756383c5203116cbb2a7dd3af038a898 100644 --- a/src/libknot/zone/zone-diff.c +++ b/src/libknot/zone/zone-diff.c @@ -16,8 +16,10 @@ #include <assert.h> #include <config.h> +#include <stdlib.h> #include "libknot/util/debug.h" +#include "common/errcode.h" #include "zone-diff.h" #include "libknot/nameserver/name-server.h" #include "common/descriptor_new.h" diff --git a/src/libknot/zone/zone.c b/src/libknot/zone/zone.c index 40ac3ceed02c55881d29b3c6d991af54d7b04382..5783c5b025ced25eee8d93bfe530a77cc0cb356f 100644 --- a/src/libknot/zone/zone.c +++ b/src/libknot/zone/zone.c @@ -27,7 +27,6 @@ #include "dname.h" #include "util/debug.h" #include "util/utils.h" -#include "hash/cuckoo-hash-table.h" #include "zone/zone-contents.h" /*! \brief Adaptor for knot_zone_deep_free() */ diff --git a/src/libknot/zone/zone.h b/src/libknot/zone/zone.h index 31ff2ac40a2ae4a378338a5fcb99fd94857f6106..1fd564cd7b80711934164f396474460355aa6d18 100644 --- a/src/libknot/zone/zone.h +++ b/src/libknot/zone/zone.h @@ -32,10 +32,8 @@ #include "zone/node.h" #include "dname.h" #include "nsec3.h" -#include "zone/dname-table.h" #include "common/tree.h" #include "common/ref.h" -#include "hash/cuckoo-hash-table.h" #include "zone-tree.h" @@ -109,7 +107,7 @@ knot_zone_t *knot_zone_new_empty(knot_dname_t *name); * * \return The initialized zone structure or NULL if an error occured. */ -knot_zone_t *knot_zone_new(knot_node_t *apex, uint node_count, +knot_zone_t *knot_zone_new(knot_node_t *apex, size_t node_count, int use_domain_table); knot_zone_contents_t *knot_zone_get_contents( diff --git a/src/zcompile/parser-descriptor.c b/src/zcompile/parser-descriptor.c deleted file mode 100644 index 26e1eb0bfe6b5aadbe23c0e3491eba38e3adbb45..0000000000000000000000000000000000000000 --- a/src/zcompile/parser-descriptor.c +++ /dev/null @@ -1,539 +0,0 @@ -/*! - * \file parser-descriptor.c - * - * \author Modifications by Jan Kadlec <jan.kadlec@nic.cz>, - * most of the work by NLnet Labs. - * Copyright (c) 2001-2011, NLnet Labs. All rights reserved. - * - * \brief Contains resource record descriptor and its API - * - * \addtogroup zoneparser - * @{ - */ - -/* - * Copyright (c) 2001-2011, NLnet Labs. All rights reserved. - * - * This software is open source. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * - * Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * - * Neither the name of the NLNET LABS nor the names of its contributors may - * be used to endorse or promote products derived from this software without - * specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED - * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - */ - -#include <config.h> -#include <stdlib.h> -#include <string.h> -#include <stdio.h> -#include <ctype.h> -#include <assert.h> -#include <string.h> -#include <sys/types.h> - -//#include "common.h" -#include "zcompile/parser-descriptor.h" -/* TODO this has to be removed - move tokens to separate file - but can it be done?) */ -#include "zcompile/zcompile.h" -/* FIXME: Generate .y and .l to zoneparser/ */ -#include "zparser.h" - -enum desclen { PARSER_RRTYPE_DESCRIPTORS_LENGTH = 65536 }; // used to be 101 - -/* Taken from RFC 1035, section 3.2.4. */ -static knot_lookup_table_t dns_rrclasses[] = { - { PARSER_CLASS_IN, "IN" }, /* the Internet */ - { PARSER_CLASS_CS, "CS" }, /* the CSNET class (Obsolete) */ - { PARSER_CLASS_CH, "CH" }, /* the CHAOS class */ - { PARSER_CLASS_HS, "HS" }, /* Hesiod */ - { 0, NULL } -}; -static parser_rrtype_descriptor_t - knot_rrtype_descriptors[PARSER_RRTYPE_DESCRIPTORS_LENGTH] = { - /* 0 */ - { 0, 0, NULL, 1, { PARSER_RDATA_WF_BINARY }, true }, - /* 1 */ - { PARSER_RRTYPE_A, T_A, "A", 1, { PARSER_RDATA_WF_A }, true }, - /* 2 */ - { PARSER_RRTYPE_NS, T_NS, "NS", 1, - { PARSER_RDATA_WF_COMPRESSED_DNAME }, true }, - /* 3 */ - { PARSER_RRTYPE_MD, T_MD, "MD", 1, - { PARSER_RDATA_WF_UNCOMPRESSED_DNAME }, true }, - /* 4 */ - { PARSER_RRTYPE_MF, T_MF, "MF", 1, - { PARSER_RDATA_WF_UNCOMPRESSED_DNAME }, true }, - /* 5 */ - { PARSER_RRTYPE_CNAME, T_CNAME, "CNAME", 1, - { PARSER_RDATA_WF_COMPRESSED_DNAME }, true }, - /* 6 */ - { PARSER_RRTYPE_SOA, T_SOA, "SOA", 7, - { PARSER_RDATA_WF_COMPRESSED_DNAME, PARSER_RDATA_WF_COMPRESSED_DNAME, - PARSER_RDATA_WF_LONG, PARSER_RDATA_WF_LONG, PARSER_RDATA_WF_LONG, - PARSER_RDATA_WF_LONG, PARSER_RDATA_WF_LONG }, true }, - /* 7 */ - { PARSER_RRTYPE_MB, T_MB, "MB", 1, - { PARSER_RDATA_WF_COMPRESSED_DNAME }, true }, - /* 8 */ - { PARSER_RRTYPE_MG, T_MG, "MG", 1, - { PARSER_RDATA_WF_COMPRESSED_DNAME }, true }, - /* 9 */ - { PARSER_RRTYPE_MR, T_MR, "MR", 1, - { PARSER_RDATA_WF_COMPRESSED_DNAME }, true }, - /* 10 */ - { PARSER_RRTYPE_NULL, T_NULL, NULL, 1, - { PARSER_RDATA_WF_BINARY }, true }, - /* 11 */ - { PARSER_RRTYPE_WKS, T_WKS, "WKS", 2, - { PARSER_RDATA_WF_A, PARSER_RDATA_WF_BINARY }, true }, - /* 12 */ - { PARSER_RRTYPE_PTR, T_PTR, "PTR", 1, - { PARSER_RDATA_WF_COMPRESSED_DNAME }, true }, - /* 13 */ - { PARSER_RRTYPE_HINFO, T_HINFO, "HINFO", 2, - { PARSER_RDATA_WF_TEXT, PARSER_RDATA_WF_TEXT }, true }, - /* 14 */ - { PARSER_RRTYPE_MINFO, T_MINFO, "MINFO", 2, - { PARSER_RDATA_WF_COMPRESSED_DNAME, - PARSER_RDATA_WF_COMPRESSED_DNAME }, true }, - /* 15 */ - { PARSER_RRTYPE_MX, T_MX, "MX", 2, - { PARSER_RDATA_WF_SHORT, PARSER_RDATA_WF_COMPRESSED_DNAME }, true }, - /* 16 */ /* This is obscure, but I guess there's no other way */ - { PARSER_RRTYPE_TXT, T_TXT, "TXT", PARSER_MAX_RDATA_ITEMS, - { PARSER_RDATA_WF_TEXT, PARSER_RDATA_WF_TEXT, - PARSER_RDATA_WF_TEXT, PARSER_RDATA_WF_TEXT, - PARSER_RDATA_WF_TEXT, PARSER_RDATA_WF_TEXT, - PARSER_RDATA_WF_TEXT, PARSER_RDATA_WF_TEXT, - PARSER_RDATA_WF_TEXT, PARSER_RDATA_WF_TEXT, - PARSER_RDATA_WF_TEXT, PARSER_RDATA_WF_TEXT, - PARSER_RDATA_WF_TEXT, PARSER_RDATA_WF_TEXT, - PARSER_RDATA_WF_TEXT, PARSER_RDATA_WF_TEXT, - PARSER_RDATA_WF_TEXT, PARSER_RDATA_WF_TEXT, - PARSER_RDATA_WF_TEXT, PARSER_RDATA_WF_TEXT, - PARSER_RDATA_WF_TEXT, PARSER_RDATA_WF_TEXT, - PARSER_RDATA_WF_TEXT, PARSER_RDATA_WF_TEXT, - PARSER_RDATA_WF_TEXT, PARSER_RDATA_WF_TEXT, - PARSER_RDATA_WF_TEXT, PARSER_RDATA_WF_TEXT, - PARSER_RDATA_WF_TEXT, PARSER_RDATA_WF_TEXT, - PARSER_RDATA_WF_TEXT, PARSER_RDATA_WF_TEXT, - PARSER_RDATA_WF_TEXT, PARSER_RDATA_WF_TEXT, - PARSER_RDATA_WF_TEXT, PARSER_RDATA_WF_TEXT, - PARSER_RDATA_WF_TEXT, PARSER_RDATA_WF_TEXT, - PARSER_RDATA_WF_TEXT, PARSER_RDATA_WF_TEXT, - PARSER_RDATA_WF_TEXT, PARSER_RDATA_WF_TEXT, - PARSER_RDATA_WF_TEXT, PARSER_RDATA_WF_TEXT, - PARSER_RDATA_WF_TEXT, PARSER_RDATA_WF_TEXT, - PARSER_RDATA_WF_TEXT, PARSER_RDATA_WF_TEXT, - PARSER_RDATA_WF_TEXT, PARSER_RDATA_WF_TEXT, - PARSER_RDATA_WF_TEXT, PARSER_RDATA_WF_TEXT, - PARSER_RDATA_WF_TEXT, PARSER_RDATA_WF_TEXT, - PARSER_RDATA_WF_TEXT, PARSER_RDATA_WF_TEXT, - PARSER_RDATA_WF_TEXT, PARSER_RDATA_WF_TEXT, - PARSER_RDATA_WF_TEXT, PARSER_RDATA_WF_TEXT, - PARSER_RDATA_WF_TEXT, PARSER_RDATA_WF_TEXT, - PARSER_RDATA_WF_TEXT, PARSER_RDATA_WF_TEXT }, false }, - /* 17 */ - { PARSER_RRTYPE_RP, T_RP, "RP", 2, - { PARSER_RDATA_WF_COMPRESSED_DNAME, - PARSER_RDATA_WF_COMPRESSED_DNAME }, true }, - /* 18 */ - { PARSER_RRTYPE_AFSDB, T_AFSDB, "AFSDB", 2, - { PARSER_RDATA_WF_SHORT, PARSER_RDATA_WF_COMPRESSED_DNAME }, true }, - /* 19 */ - { PARSER_RRTYPE_X25, T_X25, "X25", 1, - { PARSER_RDATA_WF_TEXT }, true }, - /* 20 */ - { PARSER_RRTYPE_ISDN, T_ISDN, "ISDN", 2, - { PARSER_RDATA_WF_TEXT, PARSER_RDATA_WF_TEXT }, false }, - /* 21 */ - { PARSER_RRTYPE_RT, T_RT, "RT", 2, - { PARSER_RDATA_WF_SHORT, PARSER_RDATA_WF_COMPRESSED_DNAME }, true }, - /* 22 */ - { PARSER_RRTYPE_NSAP, T_NSAP, "NSAP", 1, - { PARSER_RDATA_WF_BINARY }, true }, - /* 23 */ - { 23, 0, NULL, 1, { PARSER_RDATA_WF_BINARY }, true }, - /* 24 */ - { PARSER_RRTYPE_SIG, T_SIG, "SIG", 9, - { PARSER_RDATA_WF_SHORT, PARSER_RDATA_WF_BYTE, PARSER_RDATA_WF_BYTE, - PARSER_RDATA_WF_LONG, PARSER_RDATA_WF_LONG, PARSER_RDATA_WF_LONG, - PARSER_RDATA_WF_SHORT,PARSER_RDATA_WF_UNCOMPRESSED_DNAME, - PARSER_RDATA_WF_BINARY }, true }, - /* 25 */ - { PARSER_RRTYPE_KEY, T_KEY, "KEY", 4, - { PARSER_RDATA_WF_SHORT, PARSER_RDATA_WF_BYTE, - PARSER_RDATA_WF_BYTE, PARSER_RDATA_WF_BINARY }, true }, - /* 26 */ - { PARSER_RRTYPE_PX, T_PX, "PX", 3, - { PARSER_RDATA_WF_SHORT, PARSER_RDATA_WF_UNCOMPRESSED_DNAME, - PARSER_RDATA_WF_UNCOMPRESSED_DNAME }, true }, - /* 27 */ - { 27, 0, NULL, 1, { PARSER_RDATA_WF_BINARY }, true }, - /* 28 */ - { PARSER_RRTYPE_AAAA, T_AAAA, "AAAA", 1, - { PARSER_RDATA_WF_AAAA }, true }, - /* 29 */ - { PARSER_RRTYPE_LOC, T_LOC, "LOC", 1, - { PARSER_RDATA_WF_BINARY }, true }, - /* 30 */ - { PARSER_RRTYPE_NXT, T_NXT, "NXT", 2, - { PARSER_RDATA_WF_UNCOMPRESSED_DNAME, - PARSER_RDATA_WF_BINARY }, true }, - /* 31 */ - { 31, 0, NULL, 1, { PARSER_RDATA_WF_BINARY }, true }, - /* 32 */ - { 32, 0, NULL, 1, { PARSER_RDATA_WF_BINARY }, true }, - /* 33 */ - { PARSER_RRTYPE_SRV, T_SRV, "SRV", 4, - { PARSER_RDATA_WF_SHORT, PARSER_RDATA_WF_SHORT, - PARSER_RDATA_WF_SHORT, PARSER_RDATA_WF_UNCOMPRESSED_DNAME }, - true }, - /* 34 */ - { 34, 0, NULL, 1, { PARSER_RDATA_WF_BINARY }, true }, - /* 35 */ - { PARSER_RRTYPE_NAPTR, T_NAPTR, "NAPTR", 6, - { PARSER_RDATA_WF_SHORT, PARSER_RDATA_WF_SHORT, PARSER_RDATA_WF_TEXT, - PARSER_RDATA_WF_TEXT, PARSER_RDATA_WF_TEXT, - PARSER_RDATA_WF_UNCOMPRESSED_DNAME }, true }, - /* 36 */ - { PARSER_RRTYPE_KX, T_KX, "KX", 2, - { PARSER_RDATA_WF_SHORT, - PARSER_RDATA_WF_UNCOMPRESSED_DNAME }, true }, - /* 37 */ - { PARSER_RRTYPE_CERT, T_CERT, "CERT", 4, - { PARSER_RDATA_WF_SHORT, PARSER_RDATA_WF_SHORT, - PARSER_RDATA_WF_BYTE, PARSER_RDATA_WF_BINARY }, true }, - /* 38 */ - { PARSER_RRTYPE_A6, T_A6, NULL, 1, { PARSER_RDATA_WF_BINARY }, true }, - /* 39 */ - { PARSER_RRTYPE_DNAME, T_DNAME, "DNAME", 1, - { PARSER_RDATA_WF_UNCOMPRESSED_DNAME }, true }, - /* 40 */ - { 40, 0, NULL, 1, { PARSER_RDATA_WF_BINARY }, true }, - /* 41 */ - /* OPT has its parser token, but should never be in zone file... */ - { PARSER_RRTYPE_OPT, T_OPT, "OPT", 1, - { PARSER_RDATA_WF_BINARY }, true }, - /* 42 */ - { PARSER_RRTYPE_APL, T_APL, "APL", PARSER_MAX_RDATA_ITEMS, - { PARSER_RDATA_WF_APL, PARSER_RDATA_WF_APL, - PARSER_RDATA_WF_APL, PARSER_RDATA_WF_APL, - PARSER_RDATA_WF_APL, PARSER_RDATA_WF_APL, - PARSER_RDATA_WF_APL, PARSER_RDATA_WF_APL, - PARSER_RDATA_WF_APL, PARSER_RDATA_WF_APL, - PARSER_RDATA_WF_APL, PARSER_RDATA_WF_APL, - PARSER_RDATA_WF_APL, PARSER_RDATA_WF_APL, - PARSER_RDATA_WF_APL, PARSER_RDATA_WF_APL, - PARSER_RDATA_WF_APL, PARSER_RDATA_WF_APL, - PARSER_RDATA_WF_APL, PARSER_RDATA_WF_APL, - PARSER_RDATA_WF_APL, PARSER_RDATA_WF_APL, - PARSER_RDATA_WF_APL, PARSER_RDATA_WF_APL, - PARSER_RDATA_WF_APL, PARSER_RDATA_WF_APL, - PARSER_RDATA_WF_APL, PARSER_RDATA_WF_APL, - PARSER_RDATA_WF_APL, PARSER_RDATA_WF_APL, - PARSER_RDATA_WF_APL, PARSER_RDATA_WF_APL, - PARSER_RDATA_WF_APL, PARSER_RDATA_WF_APL, - PARSER_RDATA_WF_APL, PARSER_RDATA_WF_APL, - PARSER_RDATA_WF_APL, PARSER_RDATA_WF_APL, - PARSER_RDATA_WF_APL, PARSER_RDATA_WF_APL, - PARSER_RDATA_WF_APL, PARSER_RDATA_WF_APL, - PARSER_RDATA_WF_APL, PARSER_RDATA_WF_APL, - PARSER_RDATA_WF_APL, PARSER_RDATA_WF_APL, - PARSER_RDATA_WF_APL, PARSER_RDATA_WF_APL, - PARSER_RDATA_WF_APL, PARSER_RDATA_WF_APL, - PARSER_RDATA_WF_APL, PARSER_RDATA_WF_APL, - PARSER_RDATA_WF_APL, PARSER_RDATA_WF_APL, - PARSER_RDATA_WF_APL, PARSER_RDATA_WF_APL, - PARSER_RDATA_WF_APL, PARSER_RDATA_WF_APL, - PARSER_RDATA_WF_APL, PARSER_RDATA_WF_APL, - PARSER_RDATA_WF_APL, PARSER_RDATA_WF_APL, - PARSER_RDATA_WF_APL, PARSER_RDATA_WF_APL }, false }, - /* 43 */ - { PARSER_RRTYPE_DS, T_DS, "DS", 4, - { PARSER_RDATA_WF_SHORT, PARSER_RDATA_WF_BYTE, - PARSER_RDATA_WF_BYTE, PARSER_RDATA_WF_BINARY }, true }, - /* 44 */ - { PARSER_RRTYPE_SSHFP, T_SSHFP, "SSHFP", 3, - { PARSER_RDATA_WF_BYTE, PARSER_RDATA_WF_BYTE, - PARSER_RDATA_WF_BINARY }, true }, - /* 45 */ - { PARSER_RRTYPE_IPSECKEY, T_IPSECKEY, "IPSECKEY", 5, - { PARSER_RDATA_WF_BYTE, PARSER_RDATA_WF_BYTE, - PARSER_RDATA_WF_BYTE, PARSER_RDATA_WF_IPSECGATEWAY, - PARSER_RDATA_WF_BINARY }, false }, - /* 46 */ - { PARSER_RRTYPE_RRSIG, T_RRSIG, "RRSIG", 9, - { PARSER_RDATA_WF_SHORT, PARSER_RDATA_WF_BYTE, - PARSER_RDATA_WF_BYTE, PARSER_RDATA_WF_LONG, - PARSER_RDATA_WF_LONG, PARSER_RDATA_WF_LONG, - PARSER_RDATA_WF_SHORT, PARSER_RDATA_WF_BINARY, - PARSER_RDATA_WF_BINARY }, true }, - /* 47 */ - { PARSER_RRTYPE_NSEC, T_NSEC, "NSEC", 2, - { PARSER_RDATA_WF_BINARY, PARSER_RDATA_WF_BINARY }, true }, - /* 48 */ - { PARSER_RRTYPE_DNSKEY, T_DNSKEY, "DNSKEY", 4, - { PARSER_RDATA_WF_SHORT, PARSER_RDATA_WF_BYTE, - PARSER_RDATA_WF_BYTE, PARSER_RDATA_WF_BINARY }, true }, - /* 49 */ - { PARSER_RRTYPE_DHCID, T_DHCID, "DHCID", 1, { PARSER_RDATA_WF_BINARY }, true }, - /* 50 */ - { PARSER_RRTYPE_NSEC3, T_NSEC3, "NSEC3", 6, - { PARSER_RDATA_WF_BYTE, /* hash type */ - PARSER_RDATA_WF_BYTE, /* flags */ - PARSER_RDATA_WF_SHORT, /* iterations */ - PARSER_RDATA_WF_BINARYWITHLENGTH, /* salt */ - PARSER_RDATA_WF_BINARYWITHLENGTH, /* next hashed name */ - PARSER_RDATA_WF_BINARY /* type bitmap */ }, true }, - /* 51 */ - { PARSER_RRTYPE_NSEC3PARAM, T_NSEC3PARAM, "NSEC3PARAM", 4, - { PARSER_RDATA_WF_BYTE, /* hash type */ - PARSER_RDATA_WF_BYTE, /* flags */ - PARSER_RDATA_WF_SHORT, /* iterations */ - PARSER_RDATA_WF_BINARYWITHLENGTH /* salt */ }, true }, - /* 52 TLSA */ - { PARSER_RRTYPE_TLSA, T_TLSA, "TLSA", 3, - { PARSER_RDATA_WF_BYTE, - PARSER_RDATA_WF_BYTE, - PARSER_RDATA_WF_BYTE, - PARSER_RDATA_WF_BINARY}, true }, - - - /* In NSD they have indices between 52 and 99 filled with - unknown types. TODO add here if it's really needed? */ - /* it is indeed needed, in rrtype_from_string */ - - /* There's a GNU extension that works like this: [first ... last] = value */ - - [53 ... 98] = { PARSER_RRTYPE_TYPEXXX, T_UTYPE, NULL, 1, { PARSER_RDATA_WF_BINARY }}, - - /* 99 */ - [99] = { PARSER_RRTYPE_SPF, T_SPF, "SPF", PARSER_MAX_RDATA_ITEMS, - { PARSER_RDATA_WF_TEXT, PARSER_RDATA_WF_TEXT, - PARSER_RDATA_WF_TEXT, PARSER_RDATA_WF_TEXT, - PARSER_RDATA_WF_TEXT, PARSER_RDATA_WF_TEXT, - PARSER_RDATA_WF_TEXT, PARSER_RDATA_WF_TEXT, - PARSER_RDATA_WF_TEXT, PARSER_RDATA_WF_TEXT, - PARSER_RDATA_WF_TEXT, PARSER_RDATA_WF_TEXT, - PARSER_RDATA_WF_TEXT, PARSER_RDATA_WF_TEXT, - PARSER_RDATA_WF_TEXT, PARSER_RDATA_WF_TEXT, - PARSER_RDATA_WF_TEXT, PARSER_RDATA_WF_TEXT, - PARSER_RDATA_WF_TEXT, PARSER_RDATA_WF_TEXT, - PARSER_RDATA_WF_TEXT, PARSER_RDATA_WF_TEXT, - PARSER_RDATA_WF_TEXT, PARSER_RDATA_WF_TEXT, - PARSER_RDATA_WF_TEXT, PARSER_RDATA_WF_TEXT, - PARSER_RDATA_WF_TEXT, PARSER_RDATA_WF_TEXT, - PARSER_RDATA_WF_TEXT, PARSER_RDATA_WF_TEXT, - PARSER_RDATA_WF_TEXT, PARSER_RDATA_WF_TEXT, - PARSER_RDATA_WF_TEXT, PARSER_RDATA_WF_TEXT, - PARSER_RDATA_WF_TEXT, PARSER_RDATA_WF_TEXT, - PARSER_RDATA_WF_TEXT, PARSER_RDATA_WF_TEXT, - PARSER_RDATA_WF_TEXT, PARSER_RDATA_WF_TEXT, - PARSER_RDATA_WF_TEXT, PARSER_RDATA_WF_TEXT, - PARSER_RDATA_WF_TEXT, PARSER_RDATA_WF_TEXT, - PARSER_RDATA_WF_TEXT, PARSER_RDATA_WF_TEXT, - PARSER_RDATA_WF_TEXT, PARSER_RDATA_WF_TEXT, - PARSER_RDATA_WF_TEXT, PARSER_RDATA_WF_TEXT, - PARSER_RDATA_WF_TEXT, PARSER_RDATA_WF_TEXT, - PARSER_RDATA_WF_TEXT, PARSER_RDATA_WF_TEXT, - PARSER_RDATA_WF_TEXT, PARSER_RDATA_WF_TEXT, - PARSER_RDATA_WF_TEXT, PARSER_RDATA_WF_TEXT, - PARSER_RDATA_WF_TEXT, PARSER_RDATA_WF_TEXT, - PARSER_RDATA_WF_TEXT, PARSER_RDATA_WF_TEXT, - PARSER_RDATA_WF_TEXT, PARSER_RDATA_WF_TEXT }, false }, - [100 ... 32768] = { PARSER_RRTYPE_TYPEXXX, T_UTYPE, NULL, 1, { PARSER_RDATA_WF_BINARY }}, - /* 32769 */ - [32769] = { PARSER_RRTYPE_DLV, T_DLV, "DLV", 4, - { PARSER_RDATA_WF_SHORT, PARSER_RDATA_WF_BYTE, - PARSER_RDATA_WF_BYTE, PARSER_RDATA_WF_BINARY }}, - [32770 ... 65535] = { PARSER_RRTYPE_TYPEXXX, T_UTYPE, NULL, 1, { PARSER_RDATA_WF_BINARY }} -}; - -parser_rrtype_descriptor_t *parser_rrtype_descriptor_by_type(uint16_t type) -{ - return &knot_rrtype_descriptors[type]; -} - -/* I see a lot of potential here to speed up zone parsing - this is O(n) * - * could be better */ -parser_rrtype_descriptor_t *parser_rrtype_descriptor_by_name(const char *name) -{ - if (!name) { - return NULL; - } - - if (strcasecmp(name, "IN") == 0) { - return NULL; - } - - if (isdigit((int)name[0])) { - return NULL; - } - -// /* The most common - A and NS. */ -// if (strcasecmp(name, "NS") == 0) { -// return &knot_rrtype_descriptors[2]; -// } - -// if (strcasecmp(name, "A") == 0) { -// return &knot_rrtype_descriptors[1]; -// } - -// /* Then RRSIG */ -// if (strcasecmp(name, "RRSIG") == 0) { -// return &knot_rrtype_descriptors[46]; -// } - -// /* Then DS */ -// if (strcasecmp(name, "DS") == 0) { -// return &knot_rrtype_descriptors[43]; -// } -// /* Then NSEC3 */ -// if (strcasecmp(name, "NSEC3") == 0) { -// return &knot_rrtype_descriptors[50]; -// } -// /* Then NSEC */ -// if (strcasecmp(name, "NSEC") == 0) { -// return &knot_rrtype_descriptors[47]; -// } - - int i; - - for (i = 0; i < PARSER_RRTYPE_LAST + 1; ++i) { - if (knot_rrtype_descriptors[i].name && - strcasecmp(knot_rrtype_descriptors[i].name, name) == 0) { - return &knot_rrtype_descriptors[i]; - } - } - - if (knot_rrtype_descriptors[PARSER_RRTYPE_DLV].name && - strcasecmp(knot_rrtype_descriptors[PARSER_RRTYPE_DLV].name, - name) == 0) { - return &knot_rrtype_descriptors[PARSER_RRTYPE_DLV]; - } - - return NULL; -} - -const char *parser_rrtype_to_string(uint16_t rrtype) -{ - static char buf[20]; - parser_rrtype_descriptor_t *descriptor = - parser_rrtype_descriptor_by_type(rrtype); - if (descriptor->name) { - return descriptor->name; - } else { - snprintf(buf, sizeof(buf), "TYPE%d", (int) rrtype); - return buf; - } -} - -uint16_t parser_rrtype_from_string(const char *name) -{ - char *end; - long rrtype; - parser_rrtype_descriptor_t *entry; - - entry = parser_rrtype_descriptor_by_name(name); - if (entry) { - return entry->type; - } - - if (strlen(name) < 5) { - return 0; - } - - if (strncasecmp(name, "TYPE", 4) != 0) { - return 0; - } - - if (!isdigit((int)name[4])) { - return 0; - } - - /* The rest from the string must be a number. */ - rrtype = strtol(name + 4, &end, 10); - if (*end != '\0') { - return 0; - } - if (rrtype < 0 || rrtype > 65535L) { - return 0; - } - - return (uint16_t) rrtype; -} - -const char *parser_rrclass_to_string(uint16_t rrclass) -{ - static char buf[20]; - knot_lookup_table_t *entry = knot_lookup_by_id(dns_rrclasses, - rrclass); - if (entry) { - assert(strlen(entry->name) < sizeof(buf)); - knot_strlcpy(buf, entry->name, sizeof(buf)); - } else { - snprintf(buf, sizeof(buf), "CLASS%d", (int) rrclass); - } - return buf; -} - -uint16_t parser_rrclass_from_string(const char *name) -{ - char *end; - long rrclass; - knot_lookup_table_t *entry; - - entry = knot_lookup_by_name(dns_rrclasses, name); - if (entry) { - return (uint16_t) entry->id; - } - - if (strlen(name) < 6) { - return 0; - } - - if (strncasecmp(name, "CLASS", 5) != 0) { - return 0; - } - - if (!isdigit((int)name[5])) { - return 0; - } - - // The rest from the string must be a number. - rrclass = strtol(name + 5, &end, 10); - if (*end != '\0') { - return 0; - } - if (rrclass < 0 || rrclass > 65535L) { - return 0; - } - - return (uint16_t) rrclass; -} - -/*! @} */ diff --git a/src/zcompile/parser-descriptor.h b/src/zcompile/parser-descriptor.h deleted file mode 100644 index 48c6f021c623f48531ca2b89f94480f01d69ea19..0000000000000000000000000000000000000000 --- a/src/zcompile/parser-descriptor.h +++ /dev/null @@ -1,279 +0,0 @@ -/*! - * \file parser-descriptor.h - * - * \author Modifications by Jan Kadlec <jan.kadlec@nic.cz>, - * most of the work by NLnet Labs. - * Copyright (c) 2001-2011, NLnet Labs. All rights reserved. - * - * \brief Contains resource record descriptor and its API - * - * \addtogroup zoneparser - * @{ - */ - -/* - * Copyright (c) 2001-2011, NLnet Labs. All rights reserved. - * - * This software is open source. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * - * Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * - * Neither the name of the NLNET LABS nor the names of its contributors may - * be used to endorse or promote products derived from this software without - * specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED - * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - */ - -#ifndef _KNOTD_PARSER_DESCRIPTOR_H_ -#define _KNOTD_PARSER_DESCRIPTOR_H_ - -#include <stdint.h> -#include <stdbool.h> - -#include "libknot/util/utils.h" - -enum parser_mxrdtln { - PARSER_MAX_RDATA_ITEMS = 64, - PARSER_MAX_RDATA_ITEM_SIZE = 255, - PARSER_MAX_RDATA_WIRE_SIZE = - PARSER_MAX_RDATA_ITEMS * PARSER_MAX_RDATA_ITEM_SIZE -}; -//#define MAXRDATALEN 64 - -/* 64 is in NSD. Seems a little too much, but I'd say it's not a real issue. */ - -/*! - * \brief Enum containing RR class codes. - */ -enum parser_rr_class { - PARSER_CLASS_IN = 1, - PARSER_CLASS_CS, - PARSER_CLASS_CH, - PARSER_CLASS_HS, - PARSER_CLASS_NONE = 254, - PARSER_CLASS_ANY = 255 -}; - -typedef enum parser_rr_class parser_rr_class_t; - -enum parser_rr_type { - PARSER_RRTYPE_UNKNOWN, /*!< 0 - an unknown type */ - PARSER_RRTYPE_A, /*!< 1 - a host address */ - PARSER_RRTYPE_NS, /*!< 2 - an authoritative name server */ - PARSER_RRTYPE_MD, /*!< 3 - a mail destination (Obsolete - use MX) */ - PARSER_RRTYPE_MF, /*!< 4 - a mail forwarder (Obsolete - use MX) */ - PARSER_RRTYPE_CNAME, /*!< 5 - the canonical name for an alias */ - PARSER_RRTYPE_SOA, /*!< 6 - marks the start of a zone of authority */ - PARSER_RRTYPE_MB, /*!< 7 - a mailbox domain name (EXPERIMENTAL) */ - PARSER_RRTYPE_MG, /*!< 8 - a mail group member (EXPERIMENTAL) */ - PARSER_RRTYPE_MR, /*!< 9 - a mail rename domain name (EXPERIMENTAL) */ - PARSER_RRTYPE_NULL, /*!< 10 - a null RR (EXPERIMENTAL) */ - PARSER_RRTYPE_WKS, /*!< 11 - a well known service description */ - PARSER_RRTYPE_PTR, /*!< 12 - a domain name pointer */ - PARSER_RRTYPE_HINFO, /*!< 13 - host information */ - PARSER_RRTYPE_MINFO, /*!< 14 - mailbox or mail list information */ - PARSER_RRTYPE_MX, /*!< 15 - mail exchange */ - PARSER_RRTYPE_TXT, /*!< 16 - text strings */ - PARSER_RRTYPE_RP, /*!< 17 - RFC1183 */ - PARSER_RRTYPE_AFSDB, /*!< 18 - RFC1183 */ - PARSER_RRTYPE_X25, /*!< 19 - RFC1183 */ - PARSER_RRTYPE_ISDN, /*!< 20 - RFC1183 */ - PARSER_RRTYPE_RT, /*!< 21 - RFC1183 */ - PARSER_RRTYPE_NSAP, /*!< 22 - RFC1706 */ - - PARSER_RRTYPE_SIG = 24, /*!< 24 - 2535typecode */ - PARSER_RRTYPE_KEY, /*!< 25 - 2535typecode */ - PARSER_RRTYPE_PX, /*!< 26 - RFC2163 */ - - PARSER_RRTYPE_AAAA = 28, /*!< 28 - ipv6 address */ - PARSER_RRTYPE_LOC, /*!< 29 - LOC record RFC1876 */ - PARSER_RRTYPE_NXT, /*!< 30 - 2535typecode */ - - PARSER_RRTYPE_SRV = 33, /*!< 33 - SRV record RFC2782 */ - - PARSER_RRTYPE_NAPTR = 35, /*!< 35 - RFC2915 */ - PARSER_RRTYPE_KX, /*!< 36 - RFC2230 Key Exchange Delegation Record */ - PARSER_RRTYPE_CERT, /*!< 37 - RFC2538 */ - PARSER_RRTYPE_A6, /*!< 38 - RFC2874 */ - PARSER_RRTYPE_DNAME, /*!< 39 - RFC2672 */ - - PARSER_RRTYPE_OPT = 41, /*!< 41 - Pseudo OPT record... */ - PARSER_RRTYPE_APL, /*!< 42 - RFC3123 */ - PARSER_RRTYPE_DS, /*!< 43 - RFC 4033, 4034, and 4035 */ - PARSER_RRTYPE_SSHFP, /*!< 44 - SSH Key Fingerprint */ - PARSER_RRTYPE_IPSECKEY, /*!< 45 - public key for ipsec use. RFC 4025 */ - PARSER_RRTYPE_RRSIG, /*!< 46 - RFC 4033, 4034, and 4035 */ - PARSER_RRTYPE_NSEC, /*!< 47 - RFC 4033, 4034, and 4035 */ - PARSER_RRTYPE_DNSKEY, /*!< 48 - RFC 4033, 4034, and 4035 */ - PARSER_RRTYPE_DHCID, /*!< 49 - RFC4701 DHCP information */ - /*! - * \brief 50 - NSEC3, secure denial, prevents zonewalking - */ - PARSER_RRTYPE_NSEC3, - /*! - * \brief 51 - NSEC3PARAM at zone apex nsec3 parameters - */ - PARSER_RRTYPE_NSEC3PARAM, - PARSER_RRTYPE_TLSA = 52, - - /* TODO consider some better way of doing this, indices too high */ - - PARSER_RRTYPE_SPF = 99, /*!< RFC 4408 */ - - // not designating any RRs - PARSER_RRTYPE_TSIG = 250, - PARSER_RRTYPE_IXFR = 251, - PARSER_RRTYPE_AXFR = 252, - /*! - * \brief A request for mailbox-related records (MB, MG or MR) - */ - PARSER_RRTYPE_MAILB = 253, - /*! - * \brief A request for mail agent RRs (Obsolete - see MX) - */ - PARSER_RRTYPE_MAILA = 254, - PARSER_RRTYPE_ANY = 255, /*!< any type (wildcard) */ - - // totally weird numbers (cannot use for indexing) - PARSER_RRTYPE_TA = 32768, /*!< DNSSEC Trust Authorities */ - PARSER_RRTYPE_DLV = 32769, /*!< RFC 4431 */ - PARSER_RRTYPE_TYPEXXX = 32770 -}; - -/*! - * \brief Enum containing RR type codes. - * - * \todo Not all indices can be used for indexing. - */ -typedef enum parser_rr_type parser_rr_type_t; - -static uint const PARSER_RRTYPE_LAST = PARSER_RRTYPE_SPF; - -enum parser_rdata_wireformat { - /*! - * \brief Possibly compressed domain name. - */ - PARSER_RDATA_WF_COMPRESSED_DNAME = 50, - PARSER_RDATA_WF_UNCOMPRESSED_DNAME = 51, /*!< Uncompressed domain name. */ - PARSER_RDATA_WF_LITERAL_DNAME = 52, /*!< Literal (not downcased) dname. */ - PARSER_RDATA_WF_BYTE = 1, /*!< 8-bit integer. */ - PARSER_RDATA_WF_SHORT = 2, /*!< 16-bit integer. */ - PARSER_RDATA_WF_LONG = 4, /*!< 32-bit integer. */ - PARSER_RDATA_WF_TEXT = 53, /*!< Text string. */ - PARSER_RDATA_WF_A = 58, /*!< 32-bit IPv4 address. */ - PARSER_RDATA_WF_AAAA = 16, /*!< 128-bit IPv6 address. */ - PARSER_RDATA_WF_BINARY = 54, /*!< Binary data (unknown length). */ - /*! - * \brief Binary data preceded by 1 byte length - */ - PARSER_RDATA_WF_BINARYWITHLENGTH = 55, - PARSER_RDATA_WF_APL = 56, /*!< APL data. */ - PARSER_RDATA_WF_IPSECGATEWAY = 57 /*!< IPSECKEY gateway ip4, ip6 or dname. */ -}; - -/*! - * \brief Enum containing wireformat codes. Taken from NSD's "dns.h" - */ -typedef enum parser_rdatawireformat parser_rdata_wireformat_t; - -struct parser_rrtype_descriptor { - uint16_t type; /*!< RR type */ - int token; /*< Token used in zoneparser */ - const char *name; /*!< Textual name. */ - uint8_t length; /*!< Maximum number of RDATA items. */ - /*! - * \brief rdata_wireformat_type - */ - uint8_t wireformat[PARSER_MAX_RDATA_ITEMS]; - bool fixed_items; /*!< Has fixed number of RDATA items? */ -}; - -/*! - * \brief Structure holding RR descriptor - */ -typedef struct parser_rrtype_descriptor parser_rrtype_descriptor_t; - -/*! - * \brief Gets RR descriptor for given RR type. - * - * \param type Code of RR type whose descriptor should be returned. - * - * \return RR descriptor for given type code, NULL descriptor if - * unknown type. - * - * \todo Change return value to const. - */ -parser_rrtype_descriptor_t *parser_rrtype_descriptor_by_type(uint16_t type); - -/*! - * \brief Gets RR descriptor for given RR name. - * - * \param name Mnemonic of RR type whose descriptor should be returned. - * - * \return RR descriptor for given name, NULL descriptor if - * unknown type. - * - * \todo Change return value to const. - */ -parser_rrtype_descriptor_t *parser_rrtype_descriptor_by_name(const char *name); - -/*! - * \brief Converts numeric type representation to mnemonic string. - * - * \param rrtype Type RR type code to be converted. - * - * \return Mnemonic string if found, str(TYPE[rrtype]) otherwise. - */ -const char *parser_rrtype_to_string(uint16_t rrtype); - -/*! - * \brief Converts mnemonic string representation of a type to numeric one. - * - * \param name Mnemonic string to be converted. - * - * \return Correct code if found, 0 otherwise. - */ -uint16_t parser_rrtype_from_string(const char *name); - -/*! - * \brief Converts numeric class representation to string one. - * - * \param rrclass Class code to be converted. - * - * \return String represenation of class if found, - * str(CLASS[rrclass]) otherwise. - */ -const char *parser_rrclass_to_string(uint16_t rrclass); - -/*! - * \brief Converts string representation of a class to numeric one. - * - * \param name Class string to be converted. - * - * \return Correct code if found, 0 otherwise. - */ -uint16_t parser_rrclass_from_string(const char *name); - -#endif /* _KNOTD_PARSER_DESCRIPTOR_H_ */ - -/*! @} */ diff --git a/src/zcompile/parser-util.c b/src/zcompile/parser-util.c deleted file mode 100644 index 9616ca29714d9609ac23aae4e956274e96cd0417..0000000000000000000000000000000000000000 --- a/src/zcompile/parser-util.c +++ /dev/null @@ -1,2474 +0,0 @@ -/*! - * \file parser-util.c - * - * \author NLnet Labs - * Copyright (c) 2001-2011, NLnet Labs. All rights reserved. - * - * \brief utility functions for zone parser. - * - * \addtogroup zoneparser - * @{ - */ - -/* - * Copyright (c) 2001-2011, NLnet Labs. All rights reserved. - * - * This software is open source. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * - * Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * - * Neither the name of the NLNET LABS nor the names of its contributors may - * be used to endorse or promote products derived from this software without - * specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED - * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - */ - -#include <config.h> -#include <assert.h> -#include <fcntl.h> -#include <ctype.h> -#include <errno.h> -#include <limits.h> -#include <stdio.h> -#include <string.h> -#include <unistd.h> -#include <stdlib.h> -#include <time.h> -#include <netinet/in.h> -#include <sys/socket.h> -#include <netdb.h> - -//#include "common.h" -#include "common/base32hex.h" -#include "zcompile/parser-util.h" -#include "zcompile/zcompile.h" -#include "parser-descriptor.h" -#include "libknot/util/utils.h" -#include "zcompile/zcompile-error.h" - -#define IP6ADDRLEN (128/8) -#define NS_INT16SZ 2 -#define NS_INADDRSZ 4 -#define NS_IN6ADDRSZ 16 -#define APL_NEGATION_MASK 0x80U - -/* int - * inet_pton(af, src, dst) - * convert from presentation format (which usually means ASCII printable) - * to network format (which is usually some kind of binary format). - * return: - * 1 if the address was valid for the specified address family - * 0 if the address wasn't valid (`dst' is untouched in this case) - * -1 if some other error occurred (`dst' is untouched in this case, too) - * author: - * Paul Vixie, 1996. - */ -int inet_pton(int af, const char *src, void *dst) -{ - switch (af) { - case AF_INET: - return (inet_pton4(src, dst)); - case AF_INET6: - return (inet_pton6(src, dst)); - default: - errno = EAFNOSUPPORT; - return (-1); - } - /* NOTREACHED */ -} - -//int my_b32_pton(const char *src, uint8_t *target, size_t tsize) -//{ -// char ch; -// size_t p = 0; - -// memset(target, '\0', tsize); -// while ((ch = *src++)) { -// uint8_t d; -// size_t b; -// size_t n; - -// if (p + 5 >= tsize * 8) { -// return -1; -// } - -// if (isspace(ch)) { -// continue; -// } - -// if (ch >= '0' && ch <= '9') { -// d = ch - '0'; -// } else if (ch >= 'A' && ch <= 'V') { -// d = ch - 'A' + 10; -// } else if (ch >= 'a' && ch <= 'v') { -// d = ch - 'a' + 10; -// } else { -// return -1; -// } - -// b = 7 - p % 8; -// n = p / 8; - -// if (b >= 4) { -// target[n] |= d << (b - 4); -// } else { -// target[n] |= d >> (4 - b); -// target[n+1] |= d << (b + 4); -// } -// p += 5; -// } -// return (p + 7) / 8; -//} - - -#define Assert(Cond) if (!(Cond)) abort() - -static const char Base64[] = - "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; -static const char Pad64 = '='; - -/* int - * inet_pton4(src, dst) - * like inet_aton() but without all the hexadecimal and shorthand. - * return: - * 1 if `src' is a valid dotted quad, else 0. - * notice: - * does not touch `dst' unless it's returning 1. - * author: - * Paul Vixie, 1996. - */ -int inet_pton4(const char *src, uint8_t *dst) -{ - static const char digits[] = "0123456789"; - int saw_digit, octets, ch; - uint8_t tmp[NS_INADDRSZ], *tp; - - saw_digit = 0; - octets = 0; - *(tp = tmp) = 0; - while ((ch = *src++) != '\0') { - const char *pch; - - if ((pch = strchr(digits, ch)) != NULL) { - uint32_t new = *tp * 10 + (pch - digits); - - if (new > 255) { - return (0); - } - *tp = new; - if (! saw_digit) { - if (++octets > 4) { - return (0); - } - saw_digit = 1; - } - } else if (ch == '.' && saw_digit) { - if (octets == 4) { - return (0); - } - *++tp = 0; - saw_digit = 0; - } else { - return (0); - } - } - if (octets < 4) { - return (0); - } - - memcpy(dst, tmp, NS_INADDRSZ); - return (1); -} - -/* int - * inet_pton6(src, dst) - * convert presentation level address to network order binary form. - * return: - * 1 if `src' is a valid [RFC1884 2.2] address, else 0. - * notice: - * (1) does not touch `dst' unless it's returning 1. - * (2) :: in a full address is silently ignored. - * credit: - * inspired by Mark Andrews. - * author: - * Paul Vixie, 1996. - */ -int inet_pton6(const char *src, uint8_t *dst) -{ - static const char xdigits_l[] = "0123456789abcdef", - xdigits_u[] = "0123456789ABCDEF"; - uint8_t tmp[NS_IN6ADDRSZ], *tp, *endp, *colonp; - const char *xdigits, *curtok; - int ch, saw_xdigit; - uint32_t val; - - memset((tp = tmp), '\0', NS_IN6ADDRSZ); - endp = tp + NS_IN6ADDRSZ; - colonp = NULL; - /* Leading :: requires some special handling. */ - if (*src == ':') - if (*++src != ':') { - return (0); - } - curtok = src; - saw_xdigit = 0; - val = 0; - while ((ch = *src++) != '\0') { - const char *pch; - - if ((pch = strchr((xdigits = xdigits_l), ch)) == NULL) { - pch = strchr((xdigits = xdigits_u), ch); - } - if (pch != NULL) { - val <<= 4; - val |= (pch - xdigits); - if (val > 0xffff) { - return (0); - } - saw_xdigit = 1; - continue; - } - if (ch == ':') { - curtok = src; - if (!saw_xdigit) { - if (colonp) { - return (0); - } - colonp = tp; - continue; - } - if (tp + NS_INT16SZ > endp) { - return (0); - } - *tp++ = (uint8_t)(val >> 8) & 0xff; - *tp++ = (uint8_t) val & 0xff; - saw_xdigit = 0; - val = 0; - continue; - } - if (ch == '.' && ((tp + NS_INADDRSZ) <= endp) && - inet_pton4(curtok, tp) > 0) { - tp += NS_INADDRSZ; - saw_xdigit = 0; - break; /* '\0' was seen by inet_pton4(). */ - } - return (0); - } - if (saw_xdigit) { - if (tp + NS_INT16SZ > endp) { - return (0); - } - *tp++ = (uint8_t)(val >> 8) & 0xff; - *tp++ = (uint8_t) val & 0xff; - } - if (colonp != NULL) { - /* - * Since some memmove()'s erroneously fail to handle - * overlapping regions, we'll do the shift by hand. - */ - const int n = tp - colonp; - int i; - - for (i = 1; i <= n; i++) { - endp[- i] = colonp[n - i]; - colonp[n - i] = 0; - } - tp = endp; - } - if (tp != endp) { - return (0); - } - memcpy(dst, tmp, NS_IN6ADDRSZ); - return (1); -} - - -#ifndef IN6ADDRSZ -#define IN6ADDRSZ 16 /* IPv6 T_AAAA */ -#endif - -#ifndef INT16SZ -#define INT16SZ 2 /* for systems without 16-bit ints */ -#endif - -/* - * WARNING: Don't even consider trying to compile this on a system where - * sizeof(int) < 4. sizeof(int) > 4 is fine; all the world's not a VAX. - */ - - -/* char * - * inet_ntop(af, src, dst, size) - * convert a network format address to presentation format. - * return: - * pointer to presentation format address (`dst'), or NULL (see errno). - * author: - * Paul Vixie, 1996. - */ -//const char *inet_ntop(int af, const void *src, char *dst, size_t size) -//{ -// switch (af) { -// case AF_INET: -// return (inet_ntop4(src, dst, size)); -// case AF_INET6: -// return (inet_ntop6(src, dst, size)); -// default: -// errno = EAFNOSUPPORT; -// return (NULL); -// } -// /* NOTREACHED */ -//} - -/* const char * - * inet_ntop4(src, dst, size) - * format an IPv4 address, more or less like inet_ntoa() - * return: - * `dst' (as a const) - * notes: - * (1) uses no statics - * (2) takes a u_char* not an in_addr as input - * author: - * Paul Vixie, 1996. - */ -const char *inet_ntop4(const u_char *src, char *dst, size_t size) -{ - static const char fmt[] = "%u.%u.%u.%u"; - char tmp[sizeof "255.255.255.255"]; - int l; - - l = snprintf(tmp, size, fmt, src[0], src[1], src[2], src[3]); - if (l <= 0 || l >= (int)size) { - errno = ENOSPC; - return (NULL); - } - knot_strlcpy(dst, tmp, size); - return (dst); -} - -/* const char * - * inet_ntop6(src, dst, size) - * convert IPv6 binary address into presentation (printable) format - * author: - * Paul Vixie, 1996. - */ -const char *inet_ntop6(const u_char *src, char *dst, size_t size) -{ - /* - * Note that int32_t and int16_t need only be "at least" large enough - * to contain a value of the specified size. On some systems, like - * Crays, there is no such thing as an integer variable with 16 bits. - * Keep this in mind if you think this function should have been coded - * to use pointer overlays. All the world's not a VAX. - */ - char tmp[sizeof "ffff:ffff:ffff:ffff:ffff:ffff:255.255.255.255"]; - char *tp, *ep; - struct { - int base, len; - } best, cur; - best.base = cur.base =-1; - best.len = cur.len = 0; - u_int words[IN6ADDRSZ / INT16SZ]; - int i; - int advance; - - /* - * Preprocess: - * Copy the input (bytewise) array into a wordwise array. - * Find the longest run of 0x00's in src[] for :: shorthanding. - */ - memset(words, '\0', sizeof words); - for (i = 0; i < IN6ADDRSZ; i++) { - words[i / 2] |= (src[i] << ((1 - (i % 2)) << 3)); - } - - for (i = 0; i < (IN6ADDRSZ / INT16SZ); i++) { - if (words[i] == 0) { - if (cur.base == -1) { - cur.base = i, cur.len = 1; - } else { - cur.len++; - } - } else { - if (cur.base != -1) { - if (best.base == -1 || cur.len > best.len) { - best = cur; - } - cur.base = -1; - } - } - } - if (cur.base != -1) { - if (best.base == -1 || cur.len > best.len) { - best = cur; - } - } - if (best.base != -1 && best.len < 2) { - best.base = -1; - } - - /* - * Format the result. - */ - tp = tmp; - ep = tmp + sizeof(tmp); - for (i = 0; i < (IN6ADDRSZ / INT16SZ) && tp < ep; i++) { - /* Are we inside the best run of 0x00's? */ - if (best.base != -1 && i >= best.base && - i < (best.base + best.len)) { - if (i == best.base) { - if (tp + 1 >= ep) { - return (NULL); - } - *tp++ = ':'; - } - continue; - } - /* Are we following an initial run of 0x00s or any real hex? */ - if (i != 0) { - if (tp + 1 >= ep) { - return (NULL); - } - *tp++ = ':'; - } - /* Is this address an encapsulated IPv4? */ - if (i == 6 && best.base == 0 && - (best.len == 6 || - (best.len == 5 && words[5] == 0xffff))) { - if (!inet_ntop4(src + 12, tp, (size_t)(ep - tp))) { - return (NULL); - } - tp += strlen(tp); - break; - } - advance = snprintf(tp, ep - tp, "%x", words[i]); - if (advance <= 0 || advance >= ep - tp) { - return (NULL); - } - tp += advance; - } - /* Was it a trailing run of 0x00's? */ - if (best.base != -1 && (best.base + best.len) == - (IN6ADDRSZ / INT16SZ)) { - if (tp + 1 >= ep) { - return (NULL); - } - *tp++ = ':'; - } - if (tp + 1 >= ep) { - return (NULL); - } - *tp++ = '\0'; - - /* - * Check for overflow, copy, and we're done. - */ - if ((size_t)(tp - tmp) > size) { - errno = ENOSPC; - return (NULL); - } - knot_strlcpy(dst, tmp, size); - return (dst); -} - - -static int b64rmap_initialized = 0; -static uint8_t b64rmap[256]; - -static const uint8_t b64rmap_special = 0xf0; -static const uint8_t b64rmap_end = 0xfd; -static const uint8_t b64rmap_space = 0xfe; -static const uint8_t b64rmap_invalid = 0xff; - -/** - * Initializing the reverse map is not thread safe. - * Which is fine for NSD. For now... - **/ -void b64_initialize_rmap() -{ - int i; - char ch; - - /* Null: end of string, stop parsing */ - b64rmap[0] = b64rmap_end; - - for (i = 1; i < 256; ++i) { - ch = (char)i; - /* Whitespaces */ - if (isspace(ch)) { - b64rmap[i] = b64rmap_space; - } - /* Padding: stop parsing */ - else if (ch == Pad64) { - b64rmap[i] = b64rmap_end; - } - /* Non-base64 char */ - else { - b64rmap[i] = b64rmap_invalid; - } - } - - /* Fill reverse mapping for base64 chars */ - for (i = 0; Base64[i] != '\0'; ++i) { - b64rmap[(uint8_t)Base64[i]] = i; - } - - b64rmap_initialized = 1; -} - -int b64_pton_do(char const *src, uint8_t *target, size_t targsize) -{ - int tarindex, state, ch; - uint8_t ofs; - - state = 0; - tarindex = 0; - - while (1) { - ch = *src++; - ofs = b64rmap[ch]; - - if (ofs >= b64rmap_special) { - /* Ignore whitespaces */ - if (ofs == b64rmap_space) { - continue; - } - /* End of base64 characters */ - if (ofs == b64rmap_end) { - break; - } - /* A non-base64 character. */ - return (-1); - } - - switch (state) { - case 0: - if ((size_t)tarindex >= targsize) { - return (-1); - } - target[tarindex] = ofs << 2; - state = 1; - break; - case 1: - if ((size_t)tarindex + 1 >= targsize) { - return (-1); - } - target[tarindex] |= ofs >> 4; - target[tarindex+1] = (ofs & 0x0f) - << 4 ; - tarindex++; - state = 2; - break; - case 2: - if ((size_t)tarindex + 1 >= targsize) { - return (-1); - } - target[tarindex] |= ofs >> 2; - target[tarindex+1] = (ofs & 0x03) - << 6; - tarindex++; - state = 3; - break; - case 3: - if ((size_t)tarindex >= targsize) { - return (-1); - } - target[tarindex] |= ofs; - tarindex++; - state = 0; - break; - default: - abort(); - } - } - - /* - * We are done decoding Base-64 chars. Let's see if we ended - * on a byte boundary, and/or with erroneous trailing characters. - */ - - if (ch == Pad64) { /* We got a pad char. */ - ch = *src++; /* Skip it, get next. */ - switch (state) { - case 0: /* Invalid = in first position */ - case 1: /* Invalid = in second position */ - return (-1); - - case 2: /* Valid, means one byte of info */ - /* Skip any number of spaces. */ - for ((void)NULL; ch != '\0'; ch = *src++) - if (b64rmap[ch] != b64rmap_space) { - break; - } - /* Make sure there is another trailing = sign. */ - if (ch != Pad64) { - return (-1); - } - ch = *src++; /* Skip the = */ - /* Fall through to "single trailing =" case. */ - /* FALLTHROUGH */ - - case 3: /* Valid, means two bytes of info */ - /* - * We know this char is an =. Is there anything but - * whitespace after it? - */ - for ((void)NULL; ch != '\0'; ch = *src++) - if (b64rmap[ch] != b64rmap_space) { - return (-1); - } - - /* - * Now make sure for cases 2 and 3 that the "extra" - * bits that slopped past the last full byte were - * zeros. If we don't check them, they become a - * subliminal channel. - */ - if (target[tarindex] != 0) { - return (-1); - } - } - } else { - /* - * We ended by seeing the end of the string. Make sure we - * have no partial bytes lying around. - */ - if (state != 0) { - return (-1); - } - } - - return (tarindex); -} - - -int b64_pton_len(char const *src) -{ - int tarindex, state, ch; - uint8_t ofs; - - state = 0; - tarindex = 0; - - while (1) { - ch = *src++; - ofs = b64rmap[ch]; - - if (ofs >= b64rmap_special) { - /* Ignore whitespaces */ - if (ofs == b64rmap_space) { - continue; - } - /* End of base64 characters */ - if (ofs == b64rmap_end) { - break; - } - /* A non-base64 character. */ - return (-1); - } - - switch (state) { - case 0: - state = 1; - break; - case 1: - tarindex++; - state = 2; - break; - case 2: - tarindex++; - state = 3; - break; - case 3: - tarindex++; - state = 0; - break; - default: - abort(); - } - } - - /* - * We are done decoding Base-64 chars. Let's see if we ended - * on a byte boundary, and/or with erroneous trailing characters. - */ - - if (ch == Pad64) { /* We got a pad char. */ - ch = *src++; /* Skip it, get next. */ - switch (state) { - case 0: /* Invalid = in first position */ - case 1: /* Invalid = in second position */ - return (-1); - - case 2: /* Valid, means one byte of info */ - /* Skip any number of spaces. */ - for ((void)NULL; ch != '\0'; ch = *src++) - if (b64rmap[ch] != b64rmap_space) { - break; - } - /* Make sure there is another trailing = sign. */ - if (ch != Pad64) { - return (-1); - } - ch = *src++; /* Skip the = */ - /* Fall through to "single trailing =" case. */ - /* FALLTHROUGH */ - - case 3: /* Valid, means two bytes of info */ - /* - * We know this char is an =. Is there anything but - * whitespace after it? - */ - for ((void)NULL; ch != '\0'; ch = *src++) - if (b64rmap[ch] != b64rmap_space) { - return (-1); - } - - } - } else { - /* - * We ended by seeing the end of the string. Make sure we - * have no partial bytes lying around. - */ - if (state != 0) { - return (-1); - } - } - - return (tarindex); -} - -int b64_pton(char const *src, uint8_t *target, size_t targsize) -{ - if (!b64rmap_initialized) { - b64_initialize_rmap(); - } - - if (target) { - return b64_pton_do(src, target, targsize); - } else { - return b64_pton_len(src); - } -} - -void set_bit(uint8_t bits[], size_t index) -{ - /* - * The bits are counted from left to right, so bit #0 is the - * left most bit. - */ - bits[index / 8] |= (1 << (7 - index % 8)); -} - -uint32_t strtoserial(const char *nptr, const char **endptr) -{ - uint32_t i = 0; - uint32_t serial = 0; - - for (*endptr = nptr; **endptr; (*endptr)++) { - switch (**endptr) { - case ' ': - case '\t': - break; - case '0': - case '1': - case '2': - case '3': - case '4': - case '5': - case '6': - case '7': - case '8': - case '9': - i *= 10; - i += (**endptr - '0'); - break; - default: - break; - } - } - serial += i; - return serial; -} - -inline void write_uint32(void *dst, uint32_t data) -{ -/*!< \todo Check what this means and delete if obsolete. */ -#ifdef ALLOW_UNALIGNED_ACCESSES - *(uint32_t *) dst = htonl(data); -#else - uint8_t *p = (uint8_t *) dst; - p[0] = (uint8_t)((data >> 24) & 0xff); - p[1] = (uint8_t)((data >> 16) & 0xff); - p[2] = (uint8_t)((data >> 8) & 0xff); - p[3] = (uint8_t)(data & 0xff); -#endif -} - -uint32_t strtottl(const char *nptr, const char **endptr) -{ - uint32_t i = 0; - uint32_t seconds = 0; - - for (*endptr = nptr; **endptr; (*endptr)++) { - switch (**endptr) { - case ' ': - case '\t': - break; - case 's': - case 'S': - seconds += i; - i = 0; - break; - case 'm': - case 'M': - seconds += i * 60; - i = 0; - break; - case 'h': - case 'H': - seconds += i * 60 * 60; - i = 0; - break; - case 'd': - case 'D': - seconds += i * 60 * 60 * 24; - i = 0; - break; - case 'w': - case 'W': - seconds += i * 60 * 60 * 24 * 7; - i = 0; - break; - case '0': - case '1': - case '2': - case '3': - case '4': - case '5': - case '6': - case '7': - case '8': - case '9': - i *= 10; - i += (**endptr - '0'); - break; - default: - seconds += i; - return seconds; - } - } - seconds += i; - return seconds; -} - -/* Number of days per month (except for February in leap years). */ -static const int mdays[] = { - 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 -}; - -static int is_leap_year(int year) -{ - return year % 4 == 0 && (year % 100 != 0 || year % 400 == 0); -} - -static int leap_days(int y1, int y2) -{ - --y1; - --y2; - return (y2/4 - y1/4) - (y2/100 - y1/100) + (y2/400 - y1/400); -} - -/* - * Code adapted from Python 2.4.1 sources (Lib/calendar.py). - */ -time_t mktime_from_utc(const struct tm *tm) -{ - int year = 1900 + tm->tm_year; - time_t days = 365 * (year - 1970) + leap_days(1970, year); - time_t hours; - time_t minutes; - time_t seconds; - int i; - - for (i = 0; i < tm->tm_mon; ++i) { - days += mdays[i]; - } - if (tm->tm_mon > 1 && is_leap_year(year)) { - ++days; - } - days += tm->tm_mday - 1; - - hours = days * 24 + tm->tm_hour; - minutes = hours * 60 + tm->tm_min; - seconds = minutes * 60 + tm->tm_sec; - - return seconds; -} - -/*!< Following functions are conversions from text to wire. */ -//#define DEBUG_UNKNOWN_RDATA - -#ifdef DEBUG_UNKNOWN_RDATA -#define dbg_rdata(msg...) fprintf(stderr, msg) -#define DBG_RDATA(cmds) do { cmds } while (0) -#else -#define dbg_rdata(msg...) -#define DBG_RDATA(cmds) -#endif - - - -#define IP6ADDRLEN (128/8) -#define NS_INT16SZ 2 -#define NS_INADDRSZ 4 -#define NS_IN6ADDRSZ 16 -#define APL_NEGATION_MASK 0x80U -#define APL_LENGTH_MASK (~APL_NEGATION_MASK) - -//#define ZP_DEBUG - -#ifdef ZP_DEBUG -#define dbg_zp(msg...) fprintf(stderr, msg) -#else -#define dbg_zp(msg...) -#endif - - -/*! - * \brief Return data of raw data item. - * - * \param item Item. - * \return uint16_t * Raw data. - */ -static inline uint16_t * rdata_atom_data(knot_rdata_item_t item) -{ - return (uint16_t *)(item.raw_data + 1); -} - -/*! - * \brief Return type of RRSet covered by given RRSIG. - * - * \param rrset RRSIG. - * \return uint16_t Type covered. - */ -uint16_t rrsig_type_covered(knot_rrset_t *rrset) -{ - assert(rrset->rdata->items[0].raw_data[0] == sizeof(uint16_t)); - - return ntohs(*(uint16_t *) rdata_atom_data(rrset->rdata->items[0])); -} - -/*! - * \brief Checks if item contains domain. - * - * \param type Type of RRSet. - * \param index Index to check. - * - * \return > 1 if item is domain, 0 otherwise. - */ -static inline int rdata_atom_is_domain(uint16_t type, size_t index) -{ - const knot_rrtype_descriptor_t *descriptor - = knot_rrtype_descriptor_by_type(type); - return (index < descriptor->length - && (descriptor->wireformat[index] == - KNOT_RDATA_WF_COMPRESSED_DNAME || - descriptor->wireformat[index] == - KNOT_RDATA_WF_LITERAL_DNAME || - descriptor->wireformat[index] == - KNOT_RDATA_WF_UNCOMPRESSED_DNAME)); -} - -/*! - * \brief Returns which wireformat type is on given index. - * - * \param type Type of RRSet. - * \param index Index. - * - * \return uint8_t Wireformat type. - */ -static inline uint8_t rdata_atom_wireformat_type(uint16_t type, size_t index) -{ - const knot_rrtype_descriptor_t *descriptor = - knot_rrtype_descriptor_by_type(type); - assert(index < descriptor->length); - return descriptor->wireformat[index]; -} - -typedef int (*printf_t)(const char *fmt, ...); - -/*! - * \brief Converts rdata wireformat to rdata items. - * - * \param wireformat Wireformat/. - * \param rrtype RR type. - * \param data_size Size of wireformat. - * \param items created rdata items. - * - * \return Number of items converted. - */ -static ssize_t rdata_wireformat_to_rdata_atoms(const uint16_t *wireformat, - uint16_t rrtype, - const uint16_t data_size, - knot_rdata_item_t **items) -{ - /*!< \todo This is so ugly, it makes me wanna puke. */ - uint16_t const *end = - (uint16_t *)((uint8_t *)wireformat + (data_size)); - dbg_rdata("set end pointer: %p which means length: %d\n", end, - (uint8_t *)end - (uint8_t *)wireformat); - dbg_rdata("Parsing following wf: "); - size_t i; - knot_rdata_item_t *temp_rdatas = - malloc(sizeof(*temp_rdatas) * MAXRDATALEN); - if (temp_rdatas == NULL) { - ERR_ALLOC_FAILED; - return KNOTDZCOMPILE_ENOMEM; - } - memset(temp_rdatas, 0, sizeof(*temp_rdatas) * MAXRDATALEN); - - knot_rrtype_descriptor_t *descriptor = - knot_rrtype_descriptor_by_type(rrtype); - - assert(descriptor->length <= MAXRDATALEN); - - dbg_rdata("will be parsing %d items, total size: %d\n", - descriptor->length, data_size); - - for (i = 0; i < descriptor->length; ++i) { - dbg_rdata("this particular item is type %d.\n", - rdata_atom_wireformat_type(rrtype, i)); - int is_domain = 0; - int is_wirestore = 0; - size_t length = 0; - length = 0; - bool required = descriptor->fixed_items; - - switch (rdata_atom_wireformat_type(rrtype, i)) { - case KNOT_RDATA_WF_COMPRESSED_DNAME: - case KNOT_RDATA_WF_UNCOMPRESSED_DNAME: - dbg_rdata("Parsed item is a dname.\n"); - is_domain = 1; - break; - case KNOT_RDATA_WF_LITERAL_DNAME: - dbg_rdata("Parsed item is a literal dname.\n"); - is_domain = 1; - is_wirestore = 1; - break; - case KNOT_RDATA_WF_BYTE: - dbg_rdata("Parsed item is a byte.\n"); - length = sizeof(uint8_t); - break; - case KNOT_RDATA_WF_SHORT: - dbg_rdata("Parsed item is a short.\n"); - length = sizeof(uint16_t); - break; - case KNOT_RDATA_WF_LONG: - dbg_rdata("Parsed item is a long.\n"); - length = sizeof(uint32_t); - break; - case KNOT_RDATA_WF_APL: - dbg_rdata("APL data.\n"); - case KNOT_RDATA_WF_TEXT_SINGLE: - case KNOT_RDATA_WF_TEXT: - dbg_rdata("TEXT rdata.\n"); - case KNOT_RDATA_WF_BINARYWITHLENGTH: - dbg_rdata("BINARYWITHLENGTH rdata.\n"); - /* Length is stored in the first byte. */ - length = data_size; - break; - case KNOT_RDATA_WF_A: - dbg_rdata("Parsed item is an IPv4 address.\n"); - length = sizeof(in_addr_t); - break; - case KNOT_RDATA_WF_AAAA: - dbg_rdata("Parsed item is an IPv6 address.\n"); - length = IP6ADDRLEN; - break; - case KNOT_RDATA_WF_BINARY: - /* Remaining RDATA is binary. */ - dbg_rdata("BINARY: item %d: guessing length from pointers: %p %p. ", - i, - wireformat, end); - length = (uint8_t *)end - (uint8_t *)wireformat; - dbg_rdata("Result: %d.\n", - length); - break; -// case KNOT_RDATA_WF_APL: -// length = (sizeof(uint16_t) /* address family */ -// + sizeof(uint8_t) /* prefix */ -// + sizeof(uint8_t)); /* length */ -// if ((uint8_t *)wireformat + length <= (uint8_t *)end) { -// /* Mask out negation bit. */ -// dbg_rdata("APL: length was %d. ", length); -// length += (wireformat[data_size - 1] -// & APL_LENGTH_MASK); -// dbg_rdata("APL: after masking: %d.\n", length); -// } -// break; - case KNOT_RDATA_WF_IPSECGATEWAY: - dbg_rdata("Parsed item is an IPSECGATEWAY address.\n"); - dbg_rdata("Gateway type: %d\n", - ((uint8_t *)rdata_atom_data(temp_rdatas[1]))[0]); - switch (((uint8_t *)rdata_atom_data(temp_rdatas[1]))[0]) { - /* gateway type */ - case IPSECKEY_NOGATEWAY: - dbg_rdata("NOGATEWAY\n"); - length = 0; - break; - case IPSECKEY_IP4: - dbg_rdata("IPv4\n"); - length = 4; - break; - case IPSECKEY_IP6: - dbg_rdata("IPv6\n"); - length = IP6ADDRLEN; - break; - case IPSECKEY_DNAME: - dbg_rdata("DNAME\n"); - is_domain = 1; - is_wirestore = 1; - break; - default: - dbg_rdata("Unknown IPSECKEY gateway!\n"); - free(temp_rdatas); - return -1; - } // switch - } - - if (is_domain) { - knot_dname_t *dname = NULL; - /* - * Since we don't know how many dnames there are - * in the whole wireformat we have to search for next - * '\0'. - */ - for (length = 0; - (length < ((uint8_t *)end - (uint8_t *)wireformat)) - && (((uint8_t *)wireformat)[length] != '\0'); - length++) { - ; - } - length++; - dbg_rdata("item %d: length derived from position of " - "0: %d\n", i, length); - - if (!required && (wireformat == end)) { - break; - } - - dname = knot_dname_new_from_wire((uint8_t *)wireformat, - length, - NULL); - - if (dname == NULL) { - dbg_rdata("malformed dname!\n"); - /*! \todo rdata purge */ - free(temp_rdatas); - return KNOTDZCOMPILE_EBRDATA; - } - - dbg_rdata("item %d: created dname: %s, length: %d\n", i, - knot_dname_to_str(dname), length); - - if (is_wirestore) { - /*temp_rdatas[i].raw_data = - (uint16_t *) region_alloc( - region, sizeof(uint16_t) + dname->name_size); - temp_rdatas[i].data[0] = dname->name_size; - memcpy(temp_rdatas[i].data+1, dname_name(dname), - dname->name_size); */ - temp_rdatas[i].raw_data = - malloc(sizeof(uint16_t) + - sizeof(uint8_t) * dname->size); - if (temp_rdatas[i].raw_data == NULL) { - ERR_ALLOC_FAILED; - free(temp_rdatas); - knot_dname_free(&dname); - return KNOTDZCOMPILE_ENOMEM; - } - - temp_rdatas[i].raw_data[0] = dname->size; - memcpy(temp_rdatas[i].raw_data + 1, - dname->name, dname->size); - - knot_dname_release(dname); - } else { - temp_rdatas[i].dname = dname; - } - - } else { - /*!< \todo This calculated length makes no sense! */ - dbg_rdata("item %d :length: %d calculated: %d (%p %p)\n", i, length, - end - wireformat, - wireformat, end); - if ((uint8_t *)wireformat + length > (uint8_t *)end) { - if (required) { - /* Truncated RDATA. */ - free(temp_rdatas); - dbg_rdata("truncated rdata, end pointer is exceeded by %d octets.\n", - (wireformat + length) - end); - return KNOTDZCOMPILE_EBRDATA; - } else { - break; - } - } - - assert(wireformat <= end); /*!< \todo remove! */ - dbg_rdata("calling init with: %p and length : %d\n", - wireformat, length); - temp_rdatas[i].raw_data = alloc_rdata_init(wireformat, - length); - if (temp_rdatas[i].raw_data == NULL) { - ERR_ALLOC_FAILED; - free(temp_rdatas); - return -1; - } - - } - dbg_rdata("%d: adding length: %d (remaining: %d)\n", i, length, - (uint8_t *)end - ((uint8_t *)wireformat + length)); - wireformat = (uint16_t *)((uint8_t *)wireformat + length); - dbg_rdata("wire: %p\n", wireformat); - dbg_rdata("remaining now: %d\n", - end - wireformat); - } - - dbg_rdata("%p %p\n", wireformat, (uint8_t *)wireformat); - - if (wireformat < end) { - /* Trailing garbage. */ - dbg_rdata("Garbage: w: %p e: %p %d\n", wireformat, end, end - wireformat); - free(temp_rdatas); - return KNOTDZCOMPILE_EBRDATA; - } - - *items = temp_rdatas; - /* *rdatas = (rdata_atom_type *) region_alloc_init( - region, temp_rdatas, i * sizeof(rdata_atom_type)); */ - dbg_rdata("wf_to_rdata_atoms: Succesfully converted %d items.\n", - i); - return (ssize_t)i; -} - -/* Taken from RFC 2535, section 7. */ -knot_lookup_table_t dns_algorithms[] = { - { 1, "RSAMD5" }, /* RFC 2537 */ - { 2, "DH" }, /* RFC 2539 */ - { 3, "DSA" }, /* RFC 2536 */ - { 4, "ECC" }, - { 5, "RSASHA1" }, /* RFC 3110 */ - { 252, "INDIRECT" }, - { 253, "PRIVATEDNS" }, - { 254, "PRIVATEOID" }, - { 0, NULL } -}; - -/* Taken from RFC 4398, section 2.1. */ -knot_lookup_table_t dns_certificate_types[] = { - /* 0 Reserved */ - { 1, "PKIX" }, /* X.509 as per PKIX */ - { 2, "SPKI" }, /* SPKI cert */ - { 3, "PGP" }, /* OpenPGP packet */ - { 4, "IPKIX" }, /* The URL of an X.509 data object */ - { 5, "ISPKI" }, /* The URL of an SPKI certificate */ - { 6, "IPGP" }, /* The fingerprint and URL of an OpenPGP packet */ - { 7, "ACPKIX" }, /* Attribute Certificate */ - { 8, "IACPKIX" }, /* The URL of an Attribute Certificate */ - { 253, "URI" }, /* URI private */ - { 254, "OID" }, /* OID private */ - /* 255 Reserved */ - /* 256-65279 Available for IANA assignment */ - /* 65280-65534 Experimental */ - /* 65535 Reserved */ - { 0, NULL } -}; - -/* Imported from lexer. */ -extern int hexdigit_to_int(char ch); - -extern uint8_t nsecbits[NSEC_WINDOW_COUNT][NSEC_WINDOW_BITS_SIZE]; -extern uint16_t nsec_highest_rcode; - -/*! - * \brief Allocate SIZE+sizeof(uint16_t) bytes and store SIZE in the first - * element. Return a pointer to the allocation. - * - * \param size How many bytes to allocate. - */ -static uint16_t * alloc_rdata(size_t size) -{ - uint16_t *result = malloc(sizeof(uint16_t) + size); - *result = size; - return result; -} - -uint16_t *alloc_rdata_init(const void *data, size_t size) -{ - uint16_t *result = malloc(sizeof(uint16_t) + size); - if (result == NULL) { - return NULL; - } - *result = size; - memcpy(result + 1, data, size); - return result; -} - -/* - * These are parser function for generic zone file stuff. - */ -uint16_t * zparser_conv_hex(const char *hex, size_t len) -{ - /* convert a hex value to wireformat */ - uint16_t *r = NULL; - uint8_t *t; - int i; - - if (len % 2 != 0) { - zc_error_prev_line("number of hex digits " - "must be a multiple of 2"); - parser->error_occurred = KNOTDZCOMPILE_EBRDATA; - } else if (len > MAX_RDLENGTH * 2) { - zc_error_prev_line("hex data exceeds maximum rdata length (%d)", - MAX_RDLENGTH); - parser->error_occurred = KNOTDZCOMPILE_EBRDATA; - } else { - /* the length part */ - - r = alloc_rdata(len / 2); - if (r == NULL) { - ERR_ALLOC_FAILED; - parser->error_occurred = KNOTDZCOMPILE_ENOMEM; - return NULL; - } - t = (uint8_t *)(r + 1); - - /* Now process octet by octet... */ - while (*hex) { - *t = 0; - for (i = 16; i >= 1; i -= 15) { - if (isxdigit((int)*hex)) { - *t += hexdigit_to_int(*hex) * i; - } else { - zc_error_prev_line( - "illegal hex character '%c'", - (int) *hex); - parser->error_occurred = - KNOTDZCOMPILE_EBRDATA; - free(r); - return NULL; - } - ++hex; - } - ++t; - } - } - - return r; -} - -/* convert hex, precede by a 1-byte length */ -uint16_t * zparser_conv_hex_length(const char *hex, size_t len) -{ - uint16_t *r = NULL; - uint8_t *t; - int i; - if (len % 2 != 0) { - zc_error_prev_line("number of hex digits must be a " - "multiple of 2"); - parser->error_occurred = KNOTDZCOMPILE_EBRDATA; - } else if (len > 255 * 2) { - zc_error_prev_line("hex data exceeds 255 bytes"); - parser->error_occurred = KNOTDZCOMPILE_EBRDATA; - } else { - uint8_t *l; - - /* the length part */ - r = alloc_rdata(len / 2 + 1); - if (r == NULL) { - ERR_ALLOC_FAILED; - parser->error_occurred = KNOTDZCOMPILE_ENOMEM; - return NULL; - } - - t = (uint8_t *)(r + 1); - - l = t++; - *l = '\0'; - - /* Now process octet by octet... */ - while (*hex) { - *t = 0; - for (i = 16; i >= 1; i -= 15) { - if (isxdigit((int)*hex)) { - *t += hexdigit_to_int(*hex) * i; - } else { - zc_error_prev_line( - "illegal hex character '%c'", - (int) *hex); - parser->error_occurred = - KNOTDZCOMPILE_EBRDATA; - free(r); - return NULL; - } - ++hex; - } - ++t; - ++*l; - } - } - return r; -} - -uint16_t * zparser_conv_time(const char *time) -{ - /* convert a time YYHM to wireformat */ - uint16_t *r = NULL; - struct tm tm; - - /* Try to scan the time... */ - if (!strptime(time, "%Y%m%d%H%M%S", &tm)) { - zc_error_prev_line("date and time is expected"); - parser->error_occurred = KNOTDZCOMPILE_EBRDATA; - } else { - uint32_t l = htonl(mktime_from_utc(&tm)); - r = alloc_rdata_init(&l, sizeof(l)); - if (r == NULL) { - ERR_ALLOC_FAILED; - parser->error_occurred = KNOTDZCOMPILE_ENOMEM; - return NULL; - } - } - return r; -} - -uint16_t * zparser_conv_services(const char *protostr, char *servicestr) -{ - /* - * Convert a protocol and a list of service port numbers - * (separated by spaces) in the rdata to wireformat - */ - uint16_t *r = NULL; - uint8_t *p; - uint8_t bitmap[65536/8]; - char sep[] = " "; - char *word; - int max_port = -8; - /* convert a protocol in the rdata to wireformat */ - struct protoent *proto; - - memset(bitmap, 0, sizeof(bitmap)); - - proto = getprotobyname(protostr); - if (!proto) { - proto = getprotobynumber(atoi(protostr)); - } - if (!proto) { - zc_error_prev_line("unknown protocol '%s'", protostr); - parser->error_occurred = KNOTDZCOMPILE_EBRDATA; - return NULL; - } - - char *sp = 0; - while ((word = strtok_r(servicestr, sep, &sp))) { - struct servent *service = NULL; - int port; - - service = getservbyname(word, proto->p_name); - if (service) { - /* Note: ntohs not ntohl! Strange but true. */ - port = ntohs((uint16_t) service->s_port); -// printf("assigned port %d\n", port); - } else { -// printf("else\n"); - char *end; - port = strtol(word, &end, 10); - if (*end != '\0') { - zc_error_prev_line( - "unknown service '%s' for" - " protocol '%s'", - word, protostr); - parser->error_occurred = KNOTDZCOMPILE_EBRDATA; - return NULL; - } - } - - if (port < 0 || port > 65535) { - zc_error_prev_line("bad port number %d", port); - } else { - set_bit(bitmap, port); - if (port > max_port) { - max_port = port; - } - } - servicestr = NULL; - } - - r = alloc_rdata(sizeof(uint8_t) + max_port / 8 + 1); - if (r == NULL) { - ERR_ALLOC_FAILED; - parser->error_occurred = KNOTDZCOMPILE_ENOMEM; - return NULL; - } - - p = (uint8_t *)(r + 1); - *p = proto->p_proto; - memcpy(p + 1, bitmap, *r - 1); - - return r; -} - -uint16_t * zparser_conv_serial(const char *serialstr) -{ - uint16_t *r = NULL; - uint32_t serial; - const char *t; - - serial = strtoserial(serialstr, &t); - if (*t != '\0') { - zc_error_prev_line("serial is expected"); - parser->error_occurred = KNOTDZCOMPILE_EBRDATA; - } else { - serial = htonl(serial); - r = alloc_rdata_init(&serial, sizeof(serial)); - if (r == NULL) { - ERR_ALLOC_FAILED; - parser->error_occurred = KNOTDZCOMPILE_ENOMEM; - return NULL; - } - } - return r; -} - -uint16_t * zparser_conv_period(const char *periodstr) -{ - /* convert a time period (think TTL's) to wireformat) */ - uint16_t *r = NULL; - uint32_t period; - const char *end; - - /* Allocate required space... */ - period = strtottl(periodstr, &end); - if (*end != '\0') { - zc_error_prev_line("time period is expected"); - parser->error_occurred = KNOTDZCOMPILE_EBRDATA; - } else { - period = htonl(period); - r = alloc_rdata_init(&period, sizeof(period)); - if (r == NULL) { - ERR_ALLOC_FAILED; - parser->error_occurred = KNOTDZCOMPILE_ENOMEM; - return NULL; - } - } - return r; -} - -uint16_t * zparser_conv_short(const char *text) -{ - uint16_t *r = NULL; - uint16_t value; - char *end; - - value = htons((uint16_t) strtol(text, &end, 10)); - if (*end != '\0') { - zc_error_prev_line("integer value is expected"); - parser->error_occurred = KNOTDZCOMPILE_EBRDATA; - } else { - r = alloc_rdata_init(&value, sizeof(value)); - if (r == NULL) { - ERR_ALLOC_FAILED; - parser->error_occurred = KNOTDZCOMPILE_ENOMEM; - return NULL; - } - } - return r; -} - -uint16_t * zparser_conv_byte(const char *text) -{ - uint16_t *r = NULL; - uint8_t value; - char *end; - - value = (uint8_t) strtol(text, &end, 10); - if (*end != '\0') { - zc_error_prev_line("integer value is expected"); - parser->error_occurred = KNOTDZCOMPILE_EBRDATA; - } else { - r = alloc_rdata_init(&value, sizeof(value)); - if (r == NULL) { - ERR_ALLOC_FAILED; - parser->error_occurred = KNOTDZCOMPILE_ENOMEM; - return NULL; - } - } - return r; -} - -uint16_t * zparser_conv_algorithm(const char *text) -{ - const knot_lookup_table_t *alg; - uint8_t id; - - alg = knot_lookup_by_name(dns_algorithms, text); - if (alg) { - id = (uint8_t) alg->id; - } else { - char *end; - id = (uint8_t) strtol(text, &end, 10); - if (*end != '\0') { - zc_error_prev_line("algorithm is expected"); - parser->error_occurred = KNOTDZCOMPILE_EBRDATA; - return NULL; - } - } - - uint16_t *r = alloc_rdata_init(&id, sizeof(id)); - if (r == NULL) { - ERR_ALLOC_FAILED; - parser->error_occurred = KNOTDZCOMPILE_ENOMEM; - return NULL; - } - - return r; -} - -uint16_t * zparser_conv_certificate_type(const char *text) -{ - /* convert a algoritm string to integer */ - const knot_lookup_table_t *type; - uint16_t id; - - type = knot_lookup_by_name(dns_certificate_types, text); - if (type) { - id = htons((uint16_t) type->id); - } else { - char *end; - id = htons((uint16_t) strtol(text, &end, 10)); - if (*end != '\0') { - zc_error_prev_line("certificate type is expected"); - parser->error_occurred = KNOTDZCOMPILE_EBRDATA; - return NULL; - } - } - - uint16_t *r = alloc_rdata_init(&id, sizeof(id)); - if (r == NULL) { - ERR_ALLOC_FAILED; - parser->error_occurred = KNOTDZCOMPILE_ENOMEM; - return NULL; - } - - return r; -} - -uint16_t * zparser_conv_a(const char *text) -{ - in_addr_t address; - uint16_t *r = NULL; - - if (inet_pton(AF_INET, text, &address) != 1) { - zc_error_prev_line("invalid IPv4 address '%s'", text); - parser->error_occurred = KNOTDZCOMPILE_EBRDATA; - } else { - r = alloc_rdata_init(&address, sizeof(address)); - if (r == NULL) { - ERR_ALLOC_FAILED; - parser->error_occurred = KNOTDZCOMPILE_ENOMEM; - return NULL; - } - } - - return r; -} - -uint16_t * zparser_conv_aaaa(const char *text) -{ - uint8_t address[IP6ADDRLEN]; - uint16_t *r = NULL; - - if (inet_pton(AF_INET6, text, address) != 1) { - zc_error_prev_line("invalid IPv6 address '%s'", text); - parser->error_occurred = KNOTDZCOMPILE_EBRDATA; - } else { - r = alloc_rdata_init(address, sizeof(address)); - if (r == NULL) { - ERR_ALLOC_FAILED; - parser->error_occurred = KNOTDZCOMPILE_ENOMEM; - return NULL; - } - } - return r; -} - -uint16_t * zparser_conv_text(const char *text, size_t len) -{ - uint16_t *r = NULL; - - dbg_zp("Converting text: %s\n", text); - - if (len > 255) { - zc_error_prev_line("text string is longer than 255 characters," - " try splitting it into multiple parts"); - parser->error_occurred = KNOTDZCOMPILE_EBRDATA; - } else { - uint8_t *p; - r = alloc_rdata(len + 1); - if (r == NULL) { - ERR_ALLOC_FAILED; - parser->error_occurred = KNOTDZCOMPILE_ENOMEM; - return NULL; - } - p = (uint8_t *)(r + 1); - *p = len; - memcpy(p + 1, text, len); - } - return r; -} - -uint16_t * zparser_conv_dns_name(const uint8_t *name, size_t len) -{ - uint16_t *r = NULL; - uint8_t *p = NULL; - r = alloc_rdata(len); - if (r == NULL) { - ERR_ALLOC_FAILED; - parser->error_occurred = KNOTDZCOMPILE_ENOMEM; - return NULL; - } - p = (uint8_t *)(r + 1); - memcpy(p, name, len); - - return r; -} - -uint16_t * zparser_conv_b32(const char *b32) -{ - uint8_t buffer[B64BUFSIZE]; - uint16_t *r = NULL; - size_t i = B64BUFSIZE - 1; - - if (strcmp(b32, "-") == 0) { - r = alloc_rdata_init("", 1); - if (r == NULL) { - ERR_ALLOC_FAILED; - parser->error_occurred = KNOTDZCOMPILE_ENOMEM; - return NULL; - } - return r; - } - - /*!< \todo BLEEDING EYES! */ - - char b32_copy[strlen(b32) + 1]; - - for (int i = 0; i < strlen(b32); i++) { - b32_copy[i] = toupper(b32[i]); - } - - /*!< \todo BLEEDING EYES! */ - b32_copy[strlen(b32)] = '\0'; - - int32_t b32_ret = base32hex_decode((uint8_t *)b32_copy, strlen(b32_copy), - buffer + 1, i); - - i = b32_ret; - - if (b32_ret <= 0) { - zc_error_prev_line("invalid base32 data"); - parser->error_occurred = 1; - } else { - buffer[0] = i; /* store length byte */ - r = alloc_rdata_init(buffer, i + 1); - if (r == NULL) { - ERR_ALLOC_FAILED; - parser->error_occurred = KNOTDZCOMPILE_ENOMEM; - return NULL; - } - } - return r; -} - -uint16_t * zparser_conv_b64(const char *b64) -{ - uint8_t buffer[B64BUFSIZE]; - uint16_t *r = NULL; - int i; - - i = b64_pton(b64, buffer, B64BUFSIZE); - if (i == -1) { - zc_error_prev_line("invalid base64 data\n"); - parser->error_occurred = KNOTDZCOMPILE_EBRDATA; - } else { - r = alloc_rdata_init(buffer, i); - if (r == NULL) { - ERR_ALLOC_FAILED; - parser->error_occurred = KNOTDZCOMPILE_ENOMEM; - return NULL; - } - } - return r; -} - -uint16_t * zparser_conv_rrtype(const char *text) -{ - uint16_t *r = NULL; - uint16_t type = knot_rrtype_from_string(text); - - if (type == 0) { - zc_error_prev_line("unrecognized RR type '%s'", text); - parser->error_occurred = KNOTDZCOMPILE_EBRDATA; - } else { - type = htons(type); - r = alloc_rdata_init(&type, sizeof(type)); - if (r == NULL) { - ERR_ALLOC_FAILED; - parser->error_occurred = KNOTDZCOMPILE_ENOMEM; - return NULL; - } - } - return r; -} - -uint16_t * zparser_conv_nxt(uint8_t nxtbits[]) -{ - /* nxtbits[] consists of 16 bytes with some zero's in it - * copy every byte with zero to r and write the length in - * the first byte - */ - uint16_t i; - uint16_t last = 0; - - for (i = 0; i < 16; i++) { - if (nxtbits[i] != 0) { - last = i + 1; - } - } - - uint16_t *r = alloc_rdata_init(nxtbits, last); - if (r == NULL) { - ERR_ALLOC_FAILED; - parser->error_occurred = KNOTDZCOMPILE_ENOMEM; - return NULL; - } - - return r; -} - - -/* we potentially have 256 windows, each one is numbered. empty ones - * should be discarded - */ -uint16_t * zparser_conv_nsec(uint8_t nsecbits[NSEC_WINDOW_COUNT] - [NSEC_WINDOW_BITS_SIZE]) -{ - /* nsecbits contains up to 64K of bits which represent the - * types available for a name. Walk the bits according to - * nsec++ draft from jakob - */ - uint16_t *r; - uint8_t *ptr; - size_t i, j; - uint16_t window_count = 0; - uint16_t total_size = 0; - uint16_t window_max = 0; - - /* The used windows. */ - int used[NSEC_WINDOW_COUNT]; - /* The last byte used in each the window. */ - int size[NSEC_WINDOW_COUNT]; - - window_max = 1 + (nsec_highest_rcode / 256); - - /* used[i] is the i-th window included in the nsec - * size[used[0]] is the size of window 0 - */ - - /* walk through the 256 windows */ - for (i = 0; i < window_max; ++i) { - int empty_window = 1; - /* check each of the 32 bytes */ - for (j = 0; j < NSEC_WINDOW_BITS_SIZE; ++j) { - if (nsecbits[i][j] != 0) { - size[i] = j + 1; - empty_window = 0; - } - } - if (!empty_window) { - used[window_count] = i; - window_count++; - } - } - - for (i = 0; i < window_count; ++i) { - total_size += sizeof(uint16_t) + size[used[i]]; - } - - r = alloc_rdata(total_size); - if (r == NULL) { - ERR_ALLOC_FAILED; - parser->error_occurred = KNOTDZCOMPILE_EBRDATA; - return NULL; - } - ptr = (uint8_t *)(r + 1); - - /* now walk used and copy it */ - for (i = 0; i < window_count; ++i) { - ptr[0] = used[i]; - ptr[1] = size[used[i]]; - memcpy(ptr + 2, &nsecbits[used[i]], size[used[i]]); - ptr += size[used[i]] + 2; - } - - return r; -} - -/* Parse an int terminated in the specified range. */ -static int parse_int(const char *str, - char **end, - int *result, - const char *name, - int min, - int max) -{ - long value; - value = strtol(str, end, 10); - if (value < min || value > max) { - zc_error_prev_line("%s must be within the range [%d .. %d]", - name, - min, - max); - return 0; - } else { - *result = (int) value; - return 1; - } -} - -/* RFC1876 conversion routines */ -static uint32_t poweroften[10] = {1, 10, 100, 1000, 10000, 100000, - 1000000, 10000000, 100000000, 1000000000 - }; - -/* - * Converts ascii size/precision X * 10**Y(cm) to 0xXY. - * Sets the given pointer to the last used character. - * - */ -static uint8_t precsize_aton(char *cp, char **endptr) -{ - unsigned int mval = 0, cmval = 0; - uint8_t retval = 0; - int exponent; - int mantissa; - - while (isdigit((int)*cp)) { - mval = mval * 10 + hexdigit_to_int(*cp++); - } - - if (*cp == '.') { /* centimeters */ - cp++; - if (isdigit((int)*cp)) { - cmval = hexdigit_to_int(*cp++) * 10; - if (isdigit((int)*cp)) { - cmval += hexdigit_to_int(*cp++); - } - } - } - - if (mval >= poweroften[7]) { - /* integer overflow possible for *100 */ - mantissa = mval / poweroften[7]; - exponent = 9; /* max */ - } else { - cmval = (mval * 100) + cmval; - - for (exponent = 0; exponent < 9; exponent++) - if (cmval < poweroften[exponent+1]) { - break; - } - - mantissa = cmval / poweroften[exponent]; - } - if (mantissa > 9) { - mantissa = 9; - } - - retval = (mantissa << 4) | exponent; - - if (*cp == 'm') { - cp++; - } - - *endptr = cp; - - return (retval); -} - -/* - * Parses a specific part of rdata. - * - * Returns: - * - * number of elements parsed - * zero on error - * - */ -uint16_t * zparser_conv_loc(char *str) -{ - uint16_t *r; - uint32_t *p; - int i; - int deg, min, secs; /* Secs is stored times 1000. */ - uint32_t lat = 0, lon = 0, alt = 0; - /* encoded defaults: version=0 sz=1m hp=10000m vp=10m */ - uint8_t vszhpvp[4] = {0, 0x12, 0x16, 0x13}; - char *start; - double d; - - for (;;) { - deg = min = secs = 0; - - /* Degrees */ - if (*str == '\0') { - zc_error_prev_line("unexpected end of LOC data"); - return NULL; - } - - if (!parse_int(str, &str, °, "degrees", 0, 180)) { - return NULL; - } - if (!isspace((int)*str)) { - zc_error_prev_line("space expected after degrees"); - return NULL; - } - ++str; - - /* Minutes? */ - if (isdigit((int)*str)) { - if (!parse_int(str, &str, &min, "minutes", 0, 60)) { - return NULL; - } - if (!isspace((int)*str)) { - zc_error_prev_line("space expected after minutes"); - return NULL; - } - ++str; - } - - /* Seconds? */ - if (isdigit((int)*str)) { - start = str; - if (!parse_int(str, &str, &i, "seconds", 0, 60)) { - return NULL; - } - - if (*str == '.' && !parse_int(str + 1, &str, &i, - "seconds fraction", - 0, 999)) { - return NULL; - } - - if (!isspace((int)*str)) { - zc_error_prev_line("space expected after seconds"); - return NULL; - } - - d = strtod(start, &start); - if (errno != 0) { - zc_error_prev_line("error parsing seconds"); - } - - if (d < 0.0 || d > 60.0) { - zc_error_prev_line( - "seconds not in range 0.0 .. 60.0"); - } - - secs = (int)(d * 1000.0 + 0.5); - ++str; - } - - switch (*str) { - case 'N': - case 'n': - lat = ((uint32_t)1 << 31) + - (deg * 3600000 + min * 60000 + secs); - break; - case 'E': - case 'e': - lon = ((uint32_t)1 << 31) + - (deg * 3600000 + min * 60000 + secs); - break; - case 'S': - case 's': - lat = ((uint32_t)1 << 31) - - (deg * 3600000 + min * 60000 + secs); - break; - case 'W': - case 'w': - lon = ((uint32_t)1 << 31) - - (deg * 3600000 + min * 60000 + secs); - break; - default: - zc_error_prev_line( - "invalid latitude/longtitude: '%c'", *str); - return NULL; - } - ++str; - - if (lat != 0 && lon != 0) { - break; - } - - if (!isspace((int)*str)) { - zc_error_prev_line("space expected after" - " latitude/longitude"); - return NULL; - } - ++str; - } - - /* Altitude */ - if (*str == '\0') { - zc_error_prev_line("unexpected end of LOC data"); - return NULL; - } - - if (!isspace((int)*str)) { - zc_error_prev_line("space expected before altitude"); - return NULL; - } - ++str; - - start = str; - - /* Sign */ - if (*str == '+' || *str == '-') { - ++str; - } - - /* Meters of altitude... */ - int ret = strtol(str, &str, 10); - UNUSED(ret); // Result checked in following switch - - switch (*str) { - case ' ': - case '\0': - case 'm': - break; - case '.': - if (!parse_int(str + 1, &str, &i, "altitude fraction", 0, 99)) { - return NULL; - } - if (!isspace((int)*str) && *str != '\0' && *str != 'm') { - zc_error_prev_line("altitude fraction must be a number"); - return NULL; - } - break; - default: - zc_error_prev_line("altitude must be expressed in meters"); - return NULL; - } - if (!isspace((int)*str) && *str != '\0') { - ++str; - } - - d = strtod(start, &start); - if (errno != 0) { - zc_error_prev_line("error parsing altitued"); - } - - alt = (uint32_t)(10000000.0 + d * 100 + 0.5); - - if (!isspace((int)*str) && *str != '\0') { - zc_error_prev_line("unexpected character after altitude"); - return NULL; - } - - /* Now parse size, horizontal precision and vertical precision if any */ - for (i = 1; isspace((int)*str) && i <= 3; i++) { - vszhpvp[i] = precsize_aton(str + 1, &str); - - if (!isspace((int)*str) && *str != '\0') { - zc_error_prev_line("invalid size or precision"); - return NULL; - } - } - - /* Allocate required space... */ - r = alloc_rdata(16); - if (r == NULL) { - ERR_ALLOC_FAILED; - return NULL; - } - p = (uint32_t *)(r + 1); - - memmove(p, vszhpvp, 4); - write_uint32(p + 1, lat); - write_uint32(p + 2, lon); - write_uint32(p + 3, alt); - - return r; -} - -/* - * Convert an APL RR RDATA element. - */ -uint16_t * zparser_conv_apl_rdata(char *str) -{ - int negated = 0; - uint16_t address_family; - uint8_t prefix; - uint8_t maximum_prefix; - uint8_t length; - uint8_t address[IP6ADDRLEN]; - char *colon = strchr(str, ':'); - char *slash = strchr(str, '/'); - int af; - int rc; - uint16_t rdlength; - uint16_t *r; - uint8_t *t; - char *end; - long p; - - if (!colon) { - zc_error_prev_line("address family separator is missing"); - return NULL; - } - if (!slash) { - zc_error_prev_line("prefix separator is missing"); - return NULL; - } - - *colon = '\0'; - *slash = '\0'; - - if (*str == '!') { - negated = 1; - ++str; - } - - if (strcmp(str, "1") == 0) { - address_family = htons(1); - af = AF_INET; - length = sizeof(in_addr_t); - maximum_prefix = length * 8; - } else if (strcmp(str, "2") == 0) { - address_family = htons(2); - af = AF_INET6; - length = IP6ADDRLEN; - maximum_prefix = length * 8; - } else { - zc_error_prev_line("invalid address family '%s'", str); - return NULL; - } - - rc = inet_pton(af, colon + 1, address); - if (rc == 0) { - zc_error_prev_line("invalid address '%s'", colon + 1); - return NULL; - } else if (rc == -1) { - char ebuf[256] = {0}; - strerror_r(errno, ebuf, sizeof(ebuf)); - zc_error_prev_line("inet_pton failed: %s", ebuf); - return NULL; - } - - /* Strip trailing zero octets. */ - while (length > 0 && address[length - 1] == 0) { - --length; - } - - - p = strtol(slash + 1, &end, 10); - if (p < 0 || p > maximum_prefix) { - zc_error_prev_line("prefix not in the range 0 .. %d", - maximum_prefix); - return NULL; - } else if (*end != '\0') { - zc_error_prev_line("invalid prefix '%s'", slash + 1); - return NULL; - } - prefix = (uint8_t) p; - - rdlength = (sizeof(address_family) + sizeof(prefix) + sizeof(length) - + length); - r = alloc_rdata(rdlength); - if (r == NULL) { - ERR_ALLOC_FAILED; - return NULL; - } - t = (uint8_t *)(r + 1); - - memcpy(t, &address_family, sizeof(address_family)); - t += sizeof(address_family); - memcpy(t, &prefix, sizeof(prefix)); - t += sizeof(prefix); - memcpy(t, &length, sizeof(length)); - if (negated) { - *t |= APL_NEGATION_MASK; - } - t += sizeof(length); - memcpy(t, address, length); - - return r; -} - -/* - * Below some function that also convert but not to wireformat - * but to "normal" (int,long,char) types - */ - -uint32_t zparser_ttl2int(const char *ttlstr, int *error) -{ - /* convert a ttl value to a integer - * return the ttl in a int - * -1 on error - */ - - uint32_t ttl; - const char *t; - - ttl = strtottl(ttlstr, &t); - if (*t != 0) { - zc_error_prev_line("invalid TTL value: %s", ttlstr); - *error = 1; - } - - return ttl; -} - -void zadd_rdata_wireformat(uint16_t *data) -{ - parser->temporary_items[parser->rdata_count].raw_data = data; - parser->rdata_count++; -} - -/** - * Used for TXT RR's to grow with undefined number of strings. - */ -void zadd_rdata_txt_wireformat(uint16_t *data, int first) -{ - if (data == NULL) { - parser->error_occurred = KNOTDZCOMPILE_EBRDATA; - return; - } - dbg_zp("Adding text!\n"); - knot_rdata_item_t *rd; - - /* First STR in str_seq, allocate 65K in first unused rdata - * else find last used rdata */ - if (first) { - rd = &parser->temporary_items[parser->rdata_count]; - rd->raw_data = alloc_rdata(65535 * sizeof(uint8_t)); - if (rd->raw_data == NULL) { - parser->error_occurred = KNOTDZCOMPILE_ENOMEM; - } - parser->rdata_count++; - rd->raw_data[0] = 0; - } else { - rd = &parser->temporary_items[parser->rdata_count-1]; - } - - if (rd == NULL || rd->raw_data == NULL) { - return; - } - - if ((size_t)rd->raw_data[0] + (size_t)data[0] > 65535) { - zc_error_prev_line("too large rdata element"); - return; - } - - memcpy((uint8_t *)rd->raw_data + 2 + rd->raw_data[0], - data + 1, data[0]); - rd->raw_data[0] += data[0]; - free(data); - dbg_zp("Item after add\n"); -// hex_print(rd->raw_data + 1, rd->raw_data[0]); -} - -void zadd_rdata_domain(knot_dname_t *dname) -{ - knot_dname_retain(dname); -// printf("Adding rdata name: %s %p\n", dname->name, dname); - parser->temporary_items[parser->rdata_count].dname = dname; - parser->rdata_count++; -} - -void parse_unknown_rdata(uint16_t type, uint16_t *wireformat) -{ - dbg_rdata("parsing unknown rdata for type: %u\n", type); - uint16_t size; - ssize_t rdata_count; - ssize_t i; - knot_rdata_item_t *items = NULL; - - if (wireformat) { - size = *wireformat; - } else { - return; - } - - rdata_count = rdata_wireformat_to_rdata_atoms(wireformat + 1, type, - size, &items); - dbg_rdata("got %d items\n", rdata_count); - if (rdata_count < 0) { - dbg_rdata("wf to items returned error: %s (%d)\n", - error_to_str(knot_zcompile_error_msgs, rdata_count), - rdata_count); - zc_error_prev_line("bad unknown RDATA\n"); - /*!< \todo leaks */ - return; - } - - for (i = 0; i < rdata_count; ++i) { - if (rdata_atom_is_domain(type, i)) { - zadd_rdata_domain(items[i].dname); - } else { - //XXX won't this create size two times? - zadd_rdata_wireformat((uint16_t *)items[i].raw_data); - } - } - free(items); - /* Free wireformat */ - free(wireformat); - - dbg_rdata("parse_unknown_rdata: Successfuly parsed unknown rdata.\n"); -} - -void set_bitnsec(uint8_t bits[NSEC_WINDOW_COUNT][NSEC_WINDOW_BITS_SIZE], - uint16_t index) -{ - /* - * The bits are counted from left to right, so bit #0 is the - * left most bit. - */ - uint8_t window = index / 256; - uint8_t bit = index % 256; - - bits[window][bit / 8] |= (1 << (7 - bit % 8)); -} - -/*! @} */ diff --git a/src/zcompile/parser-util.h b/src/zcompile/parser-util.h deleted file mode 100644 index 57258dc52bc385f8e3bbd4ea3799597107b33e04..0000000000000000000000000000000000000000 --- a/src/zcompile/parser-util.h +++ /dev/null @@ -1,357 +0,0 @@ -/*! - * \file parser-util.h - * - * \author NLnet Labs - * Copyright (c) 2001-2011, NLnet Labs. All rights reserved. - * Minor modifications by CZ.NIC, z.s.p.o. - * - * \brief Zone compiler utility functions. - * - * \addtogroup zoneparser - * @{ - */ - -/* - * Copyright (c) 2001-2011, NLnet Labs. All rights reserved. - * - * This software is open source. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * - * Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * - * Neither the name of the NLNET LABS nor the names of its contributors may - * be used to endorse or promote products derived from this software without - * specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED - * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - */ - -#ifndef _KNOTD_PARSER_UTIL_H_ -#define _KNOTD_PARSER_UTIL_H_ - -#include <assert.h> -#include <fcntl.h> -#include <ctype.h> -#include <errno.h> -#include <limits.h> -#include <stdio.h> -#include <string.h> -#include <unistd.h> -#include <stdlib.h> -#include <time.h> -#include <netinet/in.h> -#include <netdb.h> - -#include "zcompile/zcompile.h" -#include "libknot/util/descriptor.h" - -int inet_pton4(const char *src, uint8_t *dst); -int inet_pton6(const char *src, uint8_t *dst); -//int my_b32_pton(const char *src, uint8_t *target, size_t tsize); -const char *inet_ntop4(const u_char *src, char *dst, size_t size); -const char *inet_ntop6(const u_char *src, char *dst, size_t size); -int inet_pton(int af, const char *src, void *dst); -void b64_initialize_rmap(); -int b64_pton_do(char const *src, uint8_t *target, size_t targsize); -int b64_pton_len(char const *src); -int b64_pton(char const *src, uint8_t *target, size_t targsize); -void set_bit(uint8_t bits[], size_t index); -uint32_t strtoserial(const char *nptr, const char **endptr); -void write_uint32(void *dst, uint32_t data); -uint32_t strtottl(const char *nptr, const char **endptr); -time_t mktime_from_utc(const struct tm *tm); - -/*!< Conversions from text to wire. */ -/*! - * \brief Converts hex text format to wireformat. - * - * \param hex String to be converted. - * \param len Length of string. - * - * \return Converted wireformat. - */ -uint16_t *zparser_conv_hex(const char *hex, size_t len); - -/*! - * \brief Converts hex text format with length to wireformat. - * - * \param hex String to be converted/. - * \param len Length of string. - * - * \return Converted wireformat. - */ -uint16_t *zparser_conv_hex_length(const char *hex, size_t len); - -/*! - * \brief Converts time string to wireformat. - * - * \param time Time string to be converted. - * - * \return Converted wireformat. - */ -uint16_t *zparser_conv_time(const char *time); -/*! - * \brief Converts a protocol and a list of service port numbers - * (separated by spaces) in the rdata to wireformat - * - * \param protostr Protocol string. - * \param servicestr Service string. - * - * \return Converted wireformat. - */ -uint16_t *zparser_conv_services(const char *protostr, char *servicestr); - -/*! - * \brief Converts serial to wireformat. - * - * \param serialstr Serial string. - * - * \return Converted wireformat. - */ -uint16_t *zparser_conv_serial(const char *serialstr); -/*! - * \brief Converts period to wireformat. - * - * \param periodstr Period string. - * - * \return Converted wireformat. - */ -uint16_t *zparser_conv_period(const char *periodstr); - -/*! - * \brief Converts short int to wireformat. - * - * \param text String containing short int. - * - * \return Converted wireformat. - */ -uint16_t *zparser_conv_short(const char *text); - -/*! - * \brief Converts long int to wireformat. - * - * \param text String containing long int. - * - * \return Converted wireformat. - */ -uint16_t *zparser_conv_long(const char *text); - -/*! - * \brief Converts byte to wireformat. - * - * \param text String containing byte. - * - * \return Converted wireformat. - */ -uint16_t *zparser_conv_byte(const char *text); - -/*! - * \brief Converts A rdata string to wireformat. - * - * \param text String containing A rdata. - * - * \return Converted wireformat. - */ -uint16_t *zparser_conv_a(const char *text); - -/*! - * \brief Converts AAAA rdata string to wireformat. - * - * \param text String containing AAAA rdata. - * - * \return Converted wireformat. - */ -uint16_t *zparser_conv_aaaa(const char *text); - -/*! - * \brief Converts text string to wireformat. - * - * \param text Text string. - * \param len Length of string. - * - * \return Converted wireformat. - */ -uint16_t *zparser_conv_text(const char *text, size_t len); - -/*! - * \brief Converts domain name string to wireformat. - * - * \param name Domain name string. - * \param len Length of string. - * - * \return Converted wireformat. - */ -uint16_t *zparser_conv_dns_name(const uint8_t* name, size_t len); - -/*! - * \brief Converts base32 encoded string to wireformat. - * TODO consider replacing with our implementation. - * - * \param b32 Base32 encoded string. - * - * \return Converted wireformat. - */ -uint16_t *zparser_conv_b32(const char *b32); - -/*! - * \brief Converts base64 encoded string to wireformat. - * TODO consider replacing with our implementation. - * - * \param b64 Base64 encoded string. - * - * \return Converted wireformat. - */ -uint16_t *zparser_conv_b64(const char *b64); - -/*! - * \brief Converts RR type string to wireformat. - * - * \param rr RR type string. - * - * \return Converted wireformat. - */ -uint16_t *zparser_conv_rrtype(const char *rr); - -/*! - * \brief Converts NXT string to wireformat. - * - * \param nxtbits NXT string. - * - * \return Converted wireformat. - */ -uint16_t *zparser_conv_nxt(uint8_t *nxtbits); - -/*! - * \brief Converts NSEC bitmap to wireformat. - * - * \param nsecbits[][] NSEC bits. - * - * \return Converted wireformat. - */ -uint16_t *zparser_conv_nsec(uint8_t nsecbits[NSEC_WINDOW_COUNT] - [NSEC_WINDOW_BITS_SIZE]); -/*! - * \brief Converts LOC string to wireformat. - * - * \param str LOC string. - * - * \return Converted wireformat. - */ -uint16_t *zparser_conv_loc(char *str); - -/*! - * \brief Converts algorithm string to wireformat. - * - * \param algstr Algorithm string. - * - * \return Converted wireformat. - */ -uint16_t *zparser_conv_algorithm(const char *algstr); - -/*! - * \brief Converts certificate type string to wireformat. - * - * \param typestr Certificate type mnemonic string. - * - * \return Converted wireformat. - */ -uint16_t *zparser_conv_certificate_type(const char *typestr); - -/*! - * \brief Converts APL data to wireformat. - * - * \param str APL data string. - * - * \return Converted wireformat. - */ -uint16_t *zparser_conv_apl_rdata(char *str); - -/*! - * \brief Parses unknown rdata. - * - * \param type Type of data. - * \param wireformat Wireformat of data. - * - * \return Converted wireformat. - */ -void parse_unknown_rdata(uint16_t type, uint16_t *wireformat); - -/*! - * \brief Converts TTL string to int. - * - * \param ttlstr String - * \param error Error code. - * - * \return Converted wireformat. - */ -uint32_t zparser_ttl2int(const char *ttlstr, int* error); - -/*! - * \brief Adds wireformat to temporary list of rdata items. - * - * \param data Wireformat to be added. - */ -void zadd_rdata_wireformat(uint16_t *data); - -/*! - * \brief Adds TXT wireformat to temporary list of rdata items. - * - * \param data Wireformat to be added. - * \param first This is first text to be added. - */ -void zadd_rdata_txt_wireformat(uint16_t *data, int first); - -/*! - * \brief Cleans after using zadd_rdata_txt_wireformat(). - */ -void zadd_rdata_txt_clean_wireformat(); - -/*! - * \brief Adds domain name to temporary list of rdata items. - * - * \param domain Domain name to be added. - */ -void zadd_rdata_domain(knot_dname_t *domain); - -/*! - * \brief Sets bit in NSEC bitmap. - * - * \param bits[][] NSEC bitmaps. - * \param index Index on which bit is to be set. - */ -void set_bitnsec(uint8_t bits[NSEC_WINDOW_COUNT][NSEC_WINDOW_BITS_SIZE], - uint16_t index); - -/*! - * \brief Allocate and init wireformat. - * - * \param data Data to be copied into newly created wireformat. - * \param size Size of data. - * - * \return Allocated wireformat. - */ -uint16_t *alloc_rdata_init(const void *data, size_t size); -uint16_t rrsig_type_covered(knot_rrset_t *rrset); - - -#endif /* _KNOTD_PARSER_UTIL_H_ */ - -/*! @} */ diff --git a/src/zcompile/tests/unittests_zp_main.c b/src/zcompile/tests/unittests_zp_main.c deleted file mode 100644 index 5d8c5e9166248e6a849e2e86e42f42012d71573c..0000000000000000000000000000000000000000 --- a/src/zcompile/tests/unittests_zp_main.c +++ /dev/null @@ -1,62 +0,0 @@ -/* Copyright (C) 2011 CZ.NIC, z.s.p.o. <knot-dns@labs.nic.cz> - - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see <http://www.gnu.org/licenses/>. - */ - -#include <config.h> -#include "knot/common.h" -#include "common/libtap/tap_unit.h" - -// Units to test -#include "zcompile_tests.c" - -// Run all loaded units -int main(int argc, char *argv[]) -{ - // Open log - //log_init(LOG_UPTO(LOG_ERR), LOG_MASK(LOG_ERR) | LOG_MASK(LOG_WARNING)); - - // Build test set - unit_api *tests[] = { - &zoneparser_tests_api, //! Zoneparser unit - NULL - }; - - // Plan number of tests - int id = 0; - int test_count = 0; - note("Units:"); - while (tests[id] != NULL) { - note("- %s : %d tests", tests[id]->name, - tests[id]->count(argc, argv)); - test_count += tests[id]->count(argc, argv); - ++id; - } - - plan(test_count); - - // Run tests - id = 0; - while (tests[id] != NULL) { - diag("Testing unit: %s", tests[id]->name); - tests[id]->run(argc, argv); - ++id; - } - - //log_close(); - - // Evaluate - return exit_status(); -} - diff --git a/src/zcompile/tests/zcompile_tests.c b/src/zcompile/tests/zcompile_tests.c deleted file mode 100644 index 5d3dce6e1b4ad23904198742f8a4d781a1427c9c..0000000000000000000000000000000000000000 --- a/src/zcompile/tests/zcompile_tests.c +++ /dev/null @@ -1,425 +0,0 @@ -/* Copyright (C) 2011 CZ.NIC, z.s.p.o. <knot-dns@labs.nic.cz> - - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see <http://www.gnu.org/licenses/>. - */ - -#include <assert.h> - -#include "libknot/zone/zone.h" -#include "knot/zone/zone-load.h" -#include "knot/common.h" -#include "libknot/rrset.h" -#include "libknot/util/descriptor.h" -#include "zcompile/zcompile.h" - -#ifdef TEST_WITH_LDNS -#include "ldns/ldns.h" -#endif - -static int zoneparser_tests_count(int argc, char *argv[]); -static int zoneparser_tests_run(int argc, char *argv[]); - -/* - * Unit API. - */ -unit_api zoneparser_tests_api = { - "Zoneparser", - &zoneparser_tests_count, - &zoneparser_tests_run -}; - -#ifdef TEST_WITH_LDNS -/* - * Unit implementation. - */static int compare_wires_simple_zp(uint8_t *wire1, - uint8_t *wire2, uint count) -{ - int i = 0; - while (i < count && - wire1[i] == wire2[i]) { - i++; - } - return (!(count == i)); -} - -/* compares only one rdata */ -static int compare_rr_rdata_silent(knot_rdata_t *rdata, ldns_rr *rr, - uint16_t type) -{ - knot_rrtype_descriptor_t *desc = - knot_rrtype_descriptor_by_type(type); - for (int i = 0; i < rdata->count; i++) { - /* TODO check for ldns "descriptors" as well */ - if (desc->wireformat[i] == KNOT_RDATA_WF_COMPRESSED_DNAME || - desc->wireformat[i] == KNOT_RDATA_WF_LITERAL_DNAME || - desc->wireformat[i] == KNOT_RDATA_WF_UNCOMPRESSED_DNAME) { - assert(ldns_rr_rdf(rr, i)); - if (rdata->items[i].dname->size != - ldns_rdf_size(ldns_rr_rdf(rr, i))) { - return 1; - } - if (compare_wires_simple_zp(rdata->items[i].dname->name, - ldns_rdf_data(ldns_rr_rdf(rr, i)), - rdata->items[i].dname->size) != 0) { - return 1; - } - } else { - if (ldns_rr_rdf(rr, i) == NULL && - rdata->items[i].raw_data[0] != 0) { - return 1; - } else { - continue; - } - if (rdata->items[i].raw_data[0] != - ldns_rdf_size(ldns_rr_rdf(rr, i))) { - - /* ldns stores the size including the - * length, dnslib does not */ - if (abs(rdata->items[i].raw_data[0] - - ldns_rdf_size(ldns_rr_rdf(rr, i))) != 1) { - return 1; - } - } - if (compare_wires_simple_zp((uint8_t *) - (rdata->items[i].raw_data + 1), - ldns_rdf_data(ldns_rr_rdf(rr, i)), - rdata->items[i].raw_data[0]) != 0) { - return 1; - } - } - } - return 0; -} - -static int compare_rrset_w_ldns_rrset(const knot_rrset_t *rrset, - ldns_rr_list *rrs, - char check_rdata, char verbose) -{ - /* We should have only one rrset from ldns, although it is - * represented as rr_list ... */ - - /* TODO errors */ - - assert(rrs); - assert(rrset); - - ldns_rr_list_sort(rrs); - - /* compare headers */ - - ldns_rr *rr = ldns_rr_list_rr(rrs, 0); - - if (rrset->owner->size != ldns_rdf_size(ldns_rr_owner(rr))) { - diag("RRSet owner names differ in length"); - if (!verbose) { - return 1; - } - diag("ldns: %d, dnslib: %d", ldns_rdf_size(ldns_rr_owner(rr)), - rrset->owner->size); - diag("%s", knot_dname_to_str(rrset->owner)); - diag("%s", ldns_rdf_data(ldns_rr_owner(rr))); - return 1; - } - - if (compare_wires_simple_zp(rrset->owner->name, - ldns_rdf_data(ldns_rr_owner(rr)), - rrset->owner->size) != 0) { - diag("RRSet owner wireformats differ"); - return 1; - } - - if (rrset->type != ldns_rr_get_type(rr)) { - diag("RRset types differ"); - if (!verbose) { - return 1; - } - diag("Dnslib type: %d Ldns type: %d", rrset->type, - ldns_rr_get_type(rr)); - return 1; - } - - if (rrset->rclass != ldns_rr_get_class(rr)) { - diag("RRset classes differ"); - return 1; - } - - if (rrset->ttl != ldns_rr_ttl(rr)) { - diag("RRset TTLs differ"); - if (!verbose) { - return 1; - } - diag("dnslib: %d ldns: %d", rrset->ttl, ldns_rr_ttl(rr)); - return 1; - } - - if (!check_rdata) { - return 0; - } - - /* compare rdatas */ - - /* sort dnslib rdata */ - - knot_rdata_t *tmp_rdata = rrset->rdata; - - rr = ldns_rr_list_pop_rr(rrs); - - char found; - - while (rr != NULL) { - found = 0; - tmp_rdata = rrset->rdata; - while (!found && - tmp_rdata->next != rrset->rdata) { - if (compare_rr_rdata_silent(tmp_rdata, rr, - rrset->type) == 0) { - found = 1; - } - tmp_rdata = tmp_rdata->next; - } - - if (!found && - compare_rr_rdata_silent(tmp_rdata, rr, rrset->type) == 0) { - found = 1; - } - - /* remove the found rdata from list */ - if (!found) { - diag("RRsets rdata differ"); - return 1; - } - ldns_rr_free(rr); - - rr = ldns_rr_list_pop_rr(rrs); - } - - return 0; -} - -int compare_zones(knot_zone_contents_t *zone, - ldns_rr_list *ldns_list, char verbose) -{ - /* TODO currently test fail when encountering first error - - * it should finish going through the zone */ - knot_rrset_t *tmp_rrset = NULL; - - knot_dname_t *tmp_dname = NULL; - - knot_node_t *node = NULL; - - ldns_rr_list *ldns_rrset = ldns_rr_list_pop_rrset(ldns_list); - - if (ldns_rrset == NULL) { - diag("Error: empty node"); - return 1; - } - - ldns_rr *rr = NULL; - - /* - * Following cycle works like this: First, we get RR from ldns rrset, - * then we search for the node containing the rrset, then we get the - * rrset, which is then compared with whole ldns rrset. - */ - - /* ldns_rr_list_pop_rrset should pop the first rrset */ - while (ldns_rrset != NULL) { - rr = ldns_rr_list_rr(ldns_rrset, 0); - tmp_dname = - knot_dname_new_from_wire(ldns_rdf_data(ldns_rr_owner(rr)), - ldns_rdf_size(ldns_rr_owner(rr)), - NULL); - - node = knot_zone_contents_get_node(zone, tmp_dname); - - if (node == NULL) { - node = knot_zone_contents_get_nsec3_node(zone, - tmp_dname); - } - - if (node == NULL) { - diag("Could not find node"); - diag("%s", knot_dname_to_str(tmp_dname)); - return 1; - } - - knot_dname_free(&tmp_dname); - - tmp_rrset = knot_node_get_rrset(node, - ldns_rr_get_type(ldns_rr_list_rr(ldns_rrset, - 0))); - - if (tmp_rrset == NULL && - (uint)(ldns_rr_get_type(ldns_rr_list_rr(ldns_rrset, 0))) != - (uint)KNOT_RRTYPE_RRSIG) { - diag("Could not find rrset"); - if (!verbose) { - return 1; - } - ldns_rr_list_print(stdout, ldns_rrset); - diag("%s", knot_dname_to_str(node->owner)); - return 1; - } else if ((uint)(ldns_rr_get_type(ldns_rr_list_rr(ldns_rrset, - 0))) == - (uint)KNOT_RRTYPE_RRSIG) { - knot_rrset_t *rrsigs = NULL; - /* read type covered from ldns rrset */ - for (int i = 0; i < ldns_rrset->_rr_count; i++) { - uint16_t type_covered = - ldns_rdf_data(ldns_rr_rdf( - ldns_rr_list_rr(ldns_rrset, i), 0))[1]; - - /* - * Dnslib stores RRSIGs separately - - * we have to find get it from its "parent" - * rrset. - */ - - tmp_rrset = knot_node_get_rrset(node, - type_covered); - - if (tmp_rrset == NULL) { - if (!verbose) { - return 1; - } - diag("following rrset " - "could not be found"); - ldns_rr_list_print(stdout, ldns_rrset); - return 1; - } - - if (rrsigs == NULL) { - rrsigs = tmp_rrset->rrsigs; - } else { - knot_rrset_merge((void *)&rrsigs, - (void *)&(tmp_rrset->rrsigs)); - } - } - tmp_rrset = rrsigs; - } - -/* diag("dnslib type: %d", tmp_rrset->type); - diag("dnslib dname: %s", tmp_rrset->owner->name); - - diag("ldns type: %d", - ldns_rr_get_type(ldns_rr_list_rr(ldns_rrset, 0))); - diag("ldns dname : %s", ldns_rdf_data(ldns_rr_owner( - ldns_rr_list_rr(ldns_rrset, 0)))); */ - -// knot_rrset_dump(tmp_rrset, 1); - - if (compare_rrset_w_ldns_rrset(tmp_rrset, ldns_rrset, - 1, 0) != 0) { - diag("RRSets did not match"); -// knot_rrset_dump(tmp_rrset, 1); - return 1; - } - - ldns_rr_list_deep_free(ldns_rrset); - - ldns_rrset = ldns_rr_list_pop_rrset(ldns_list); - - if (ldns_rrset == NULL) { - ldns_rrset = ldns_rr_list_pop_rrset(ldns_list); - } - } - - return 0; -} - -#endif - -static int test_zoneparser_zone_read(const char *origin, const char *filename, - const char *outfile) -{ -#ifndef TEST_WITH_LDNS - diag("Zoneparser tests without usage of ldns are not implemented"); - return 0; -#endif - -#ifdef TEST_WITH_LDNS - /* Calls zcompile. */ - parser = zparser_create(); - int ret = zone_read(origin, filename, outfile, 0); - if (ret != 0) { - diag("Could not load zone from file: %s", filename); - return 0; - } - - knot_zone_t *dnsl_zone = NULL; - zloader_t *loader = NULL; - if (knot_zload_open(&loader, outfile) != 0) { - diag("Could not create zone loader.\n"); - return 0; - } - dnsl_zone = knot_zload_load(loader); - remove(outfile); - if (!dnsl_zone) { - diag("Could not load dumped zone.\n"); - return 0; - } - - ldns_zone *ldns_zone = NULL; - FILE *f = fopen(filename, "r"); - if (ldns_zone_new_frm_fp(&ldns_zone, f, NULL, - 0, LDNS_RR_CLASS_IN) != LDNS_STATUS_OK) { - diag("Could not load zone from file: %s (ldns)", filename); - return 0; - } - -// ldns_zone_sort(ldns_zone); - - /* - * LDNS stores SOA record independently - create a list with all - * records in it. - */ - - ldns_rr_list *ldns_list = ldns_zone_rrs(ldns_zone); - - ldns_rr_list_push_rr(ldns_list, ldns_zone_soa(ldns_zone)); - - if (compare_zones(dnsl_zone->contents, ldns_list, 0) != 0) { - return 0; - } - - knot_zone_deep_free(&dnsl_zone, 0); - ldns_zone_free(ldns_zone); - fclose(f); - return 1; -#endif -} - -static const int ZONEPARSER_TEST_COUNT = 1; - -/*! API: return number of tests. */ -static int zoneparser_tests_count(int argc, char *argv[]) -{ - return ZONEPARSER_TEST_COUNT; -} - -/*! API: run tests. */ -static int zoneparser_tests_run(int argc, char *argv[]) -{ - if (argc == 3) { - ok(test_zoneparser_zone_read(argv[1], argv[2], - "foo_test_zone"), - "zoneparser: read (%s)", - argv[2]); - } else { - diag("Wrong parameters\n usage: " - "knot-zcompile-unittests origin zonefile"); - return 0; - } - return 1; -} diff --git a/src/zcompile/zcompile-error.h b/src/zcompile/zcompile-error.h deleted file mode 100644 index c6d999c2aec7c193eb50ac3f762dfa882bf88f70..0000000000000000000000000000000000000000 --- a/src/zcompile/zcompile-error.h +++ /dev/null @@ -1,90 +0,0 @@ -/*! - * \file zcompile-error.h - * - * \author Lubos Slovak <lubos.slovak@nic.cz> - * \author Marek Vavrusa <marek.vavrusa@nic.cz> - * \author Jan Kadlec <jan.kadlec@nic.cz> - * - * \brief Error codes and function for getting error message. - * - * \addtogroup zoneparser - * @{ - */ -/* Copyright (C) 2011 CZ.NIC, z.s.p.o. <knot-dns@labs.nic.cz> - - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see <http://www.gnu.org/licenses/>. - */ - -#ifndef _KNOTD_ZCOMPILE_ERROR_H_ -#define _KNOTD_ZCOMPILE_ERROR_H_ - -#include "common/errors.h" - -/*! - * \brief Error codes used in the server. - * - * Some viable errors are directly mapped - * to libc errno codes. - */ -enum knot_zcompile_error { - - /* Directly mapped error codes. */ - KNOTDZCOMPILE_EOK = 0, - KNOTDZCOMPILE_ENOMEM = -ENOMEM, /*!< \brief Out of memory. */ - KNOTDZCOMPILE_EINVAL = -EINVAL, /*!< \brief Invalid parameter passed. */ - /*! - * \brief Parameter not supported. - */ - KNOTDZCOMPILE_ENOTSUP = -ENOTSUP, - KNOTDZCOMPILE_EBUSY = -EBUSY, /*!< \brief Requested resource is busy. */ - /*! - * \brief OS lacked necessary resources. - */ - KNOTDZCOMPILE_EAGAIN = -EAGAIN, - KNOTDZCOMPILE_EACCES = -EACCES, /*!< \brief Permission is denied. */ - /*! - * \brief Connection is refused. - */ - KNOTDZCOMPILE_ECONNREFUSED = -ECONNREFUSED, - KNOTDZCOMPILE_EISCONN = -EISCONN, /*!< \brief Already connected. */ - /*! - * \brief Address already in use. - */ - KNOTDZCOMPILE_EADDRINUSE = -EADDRINUSE, - KNOTDZCOMPILE_ENOENT = -ENOENT, /*!< \brief Resource not found. */ - KNOTDZCOMPILE_ERANGE = -ERANGE, /*!< \brief Value is out of range. */ - - /* Custom error codes. */ - KNOTDZCOMPILE_ERROR = -16384, /*!< \brief Generic error. */ - KNOTDZCOMPILE_ESYNT, /*!< \brief Syntax error. */ - KNOTDZCOMPILE_EBADNODE, /*!< \brief Node error. */ - KNOTDZCOMPILE_EBRDATA, /*!< \brief RDATA error. */ - KNOTDZCOMPILE_EBADSOA, /*!< \brief SOA owner error. */ - KNOTDZCOMPILE_ESOA, /*!< \brief Multiple SOA records. */ - - KNOTDZCOMPILE_EZONEINVAL, /*!< \brief Invalid zone file. */ - KNOTDZCOMPILE_EPARSEFAIL, /*!< \brief Parser fail. */ - KNOTDZCOMPILE_ENOIPV6, /*! \brief No IPv6 support. */ - - KNOTDZCOMPILE_ERROR_COUNT = 22 -}; - -typedef enum knot_zcompile_error knot_zcompile_error_t; - -/*! \brief Table linking error messages to error codes. */ -extern const error_table_t knot_zcompile_error_msgs[KNOTDZCOMPILE_ERROR_COUNT]; - -#endif /* _KNOTD_ZCOMPILE_ERROR_H_ */ - -/*! @} */ diff --git a/src/zcompile/zcompile.c b/src/zcompile/zcompile.c deleted file mode 100644 index afc036a749f0ec7a3313840838763547df3001e0..0000000000000000000000000000000000000000 --- a/src/zcompile/zcompile.c +++ /dev/null @@ -1,673 +0,0 @@ -/*! - * \file zcompile.c - * - * \author Jan Kadlec <jan.kadlec@nic.cz>. Minor portions of code taken from - * NSD. - * - * \brief Zone compiler. - * - * \addtogroup zoneparser - * @{ - */ - -/* Copyright (C) 2011 CZ.NIC, z.s.p.o. <knot-dns@labs.nic.cz> - - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see <http://www.gnu.org/licenses/>. - */ - -#include <config.h> -#include <assert.h> -#include <ctype.h> -#include <stdio.h> -#include <string.h> -#include <stdlib.h> -#include <assert.h> -#include <sys/stat.h> - -#include "common/base32hex.h" -#include "common/log.h" -#include "knot/other/debug.h" -#include "zcompile/zcompile.h" -#include "zcompile/parser-util.h" -#include "zcompile/zcompile-error.h" -#include "knot/zone/zone-dump.h" -#include "libknot/zone/zone-diff.h" -#include "libknot/rrset.h" -#include "libknot/util/utils.h" -#include "zscanner/file_loader.h" - -//#define dbg_zp_detail printf -//#define dbg_zp printf - -//#define dbg_zp_exec_detail(cmds) do { cmds } while (0) - -static long rr_count = 0; -static long new_rr_count = 0; -static long new_dname_count = 0; -static long err_count = 0; - -struct parser_context { - rrset_list_t *node_rrsigs; - knot_zone_contents_t *current_zone; - knot_rrset_t *current_rrset; - knot_dname_t *origin_from_config; - knot_node_t *last_node; - int ret; -}; - -typedef struct parser_context parser_context_t; - -/*! - * \brief Adds RRSet to list. - * - * \param head Head of list. - * \param rrsig RRSet to be added. - */ -static int rrset_list_add(rrset_list_t **head, knot_rrset_t *rrsig) -{ - if (*head == NULL) { - *head = malloc(sizeof(rrset_list_t)); - if (*head == NULL) { - ERR_ALLOC_FAILED; - return KNOTDZCOMPILE_ENOMEM; - } - (*head)->next = NULL; - (*head)->data = rrsig; - } else { - rrset_list_t *tmp = malloc(sizeof(*tmp)); - if (tmp == NULL) { - ERR_ALLOC_FAILED; - return KNOTDZCOMPILE_ENOMEM; - } - tmp->next = *head; - tmp->data = rrsig; - *head = tmp; - } - - dbg_zp_verb("zp: rrset_add: Added RRSIG %p to list.\n", rrsig); - - return KNOTDZCOMPILE_EOK; -} - -/*! - * \brief Deletes RRSet list. Sets pointer to NULL. - * - * \param head Head of list to be deleted. - */ -static void rrset_list_delete(rrset_list_t **head) -{ - rrset_list_t *tmp; - if (*head == NULL) { - return; - } - - while (*head != NULL) { - tmp = *head; - *head = (*head)->next; - free(tmp); - } - - *head = NULL; - - dbg_zp("zp: list_delete: List deleleted.\n"); -} - -static int find_rrset_for_rrsig_in_node(knot_zone_contents_t *zone, - knot_node_t *node, - knot_rrset_t *rrsig) -{ - assert(node); - - assert(knot_dname_compare(rrsig->owner, node->owner) == 0); - - knot_rrset_t *tmp_rrset = - knot_node_get_rrset(node, - knot_rrset_rdata_rrsig_type_covered(rrsig)); - - int ret; - - if (tmp_rrset == NULL) { - dbg_zp("zp: find_rr_for_sig_in_node: Node does not contain " - "RRSet of type %d.\n", - knot_rrset_rdata_rrsig_type_covered(rrsig)); - tmp_rrset = knot_rrset_new(rrsig->owner, - knot_rrset_rdata_rrsig_type_covered(rrsig), - rrsig->rclass, - rrsig->ttl); - if (tmp_rrset == NULL) { - dbg_zp("zp: find_rr_for_sig_in_node: Cannot create " - "dummy RRSet.\n"); - return KNOT_ERROR; - } - - ret = knot_zone_contents_add_rrset(zone, tmp_rrset, &node, - KNOT_RRSET_DUPL_MERGE, 1); - assert(ret <= 0); - if (ret < 0) { - dbg_zp("zp: Failed to add new dummy RRSet to the zone." - "\n"); - return KNOT_ERROR; - } - } - - assert(tmp_rrset); - - if (tmp_rrset->ttl != rrsig->ttl) { - char *name = knot_dname_to_str(tmp_rrset->owner); - assert(name); - log_zone_warning("RRSIG owned by: %s cannot be added to " - "its RRSet, because their TTLs differ. " - "Changing TTL to value=%d.\n", - name, tmp_rrset->ttl); - free(name); - } - - ret = knot_zone_contents_add_rrsigs(zone, rrsig, &tmp_rrset, &node, - KNOT_RRSET_DUPL_MERGE, 1); - if (ret < 0) { - dbg_zp("zp: find_rr_for_sig: Cannot add RRSIG.\n"); - return KNOTDZCOMPILE_EINVAL; - } else if (ret > 0) { - knot_rrset_deep_free(&rrsig, 0, 0); - } - - knot_dname_release(tmp_rrset->owner); - - assert(tmp_rrset->rrsigs != NULL); - - return KNOTDZCOMPILE_EOK; -} - -static knot_node_t *create_node(knot_zone_contents_t *zone, - knot_rrset_t *current_rrset, - int (*node_add_func)(knot_zone_contents_t *zone, knot_node_t *node, - int create_parents, uint8_t, int), - knot_node_t *(*node_get_func)(const knot_zone_contents_t *zone, - const knot_dname_t *owner)) -{ - dbg_zp_verb("zp: create_node: Creating node using RRSet: %p.\n", - current_rrset); - knot_node_t *node = - knot_node_new(current_rrset->owner, NULL, 0); - if (node_add_func(zone, node, 1, 0, 1) != 0) { - return NULL; - } - - assert(current_rrset->owner == node->owner); - - return node; -} - -static void process_rrsigs_in_node(parser_context_t *parser, - knot_zone_contents_t *zone, - knot_node_t *node) -{ - dbg_zp_verb("zp: process_rrsigs: Processing RRSIGS in node: %p.\n", - node); - rrset_list_t *tmp = parser->node_rrsigs; - while (tmp != NULL) { - if (find_rrset_for_rrsig_in_node(zone, node, - tmp->data) != KNOT_EOK) { - fprintf(stderr, "Could not add RRSIG to zone!\n"); - return; - } - tmp = tmp->next; - } -} - -static void process_error(const scanner_t *s) -{ - err_count++; - if (s->stop == true) { - printf("ERROR=%s\n", knot_strerror(s->error_code)); - } else { - printf("WARNG=%s\n", knot_strerror(s->error_code)); - } - fflush(stdout); -} - -// TODO this could be a part of the cycle below, but we'd need a buffer. -static size_t calculate_item_size(const knot_rrset_t *rrset, - const scanner_t *scanner) -{ - const rdata_descriptor_t *desc = get_rdata_descriptor(rrset->type); - assert(desc); - size_t size = 0; - for (int i = 0; desc->block_types[i] != KNOT_RDATA_WF_END; i++) { - int item = desc->block_types[i]; - if (descriptor_item_is_dname(item)) { - size += sizeof(knot_dname_t *); - } else if (descriptor_item_is_fixed(item)) { - assert(item == scanner->r_data_blocks[i + 1] - - scanner->r_data_blocks[i]); - size += item; - } else if (descriptor_item_is_remainder(item)) { - size += scanner->r_data_blocks[i + 1] - - scanner->r_data_blocks[i]; - } else { - //naptr - assert(0); - } - } - - return size; -} - -static int add_rdata_to_rr(knot_rrset_t *rrset, const scanner_t *scanner) -{ - if (rrset == NULL) { - dbg_zp("zp: add_rdata_to_rr: No RRSet.\n"); - return KNOT_EINVAL; - } - - const rdata_descriptor_t *desc = - get_rdata_descriptor(knot_rrset_type(rrset)); - assert(desc); - - dbg_zp_detail("zp: add_rdata_to_rr: Adding type %d, RRSet has %d RRs.\n", - rrset->type, rrset->rdata_count); - - size_t rdlen = calculate_item_size(rrset, scanner); - size_t offset = 0; - uint8_t *rdata = knot_rrset_create_rdata(rrset, rdlen); - if (rdata == NULL) { - dbg_zp("zp: create_rdata: Could not create RR.\n"); - return KNOT_ENOMEM; - } - - for (int i = 0; desc->block_types[i] != KNOT_RDATA_WF_END; i++) { - int item = desc->block_types[i]; - if (descriptor_item_is_dname(item)) { - /* TODO another function perhaps? */ - knot_dname_t *dname = - knot_dname_new_from_wire(scanner->r_data + - scanner->r_data_blocks[i], - scanner->r_data_blocks[i + 1] - scanner->r_data_blocks[i], - NULL); - if (dname == NULL) { - //TODO handle - return KNOT_ERROR; - } -dbg_zp_exec_detail( - char *name = knot_dname_to_str(dname); - dbg_zp_detail("zp: arr_rdata_to_rr: " - "Offset=%d:Adding dname=%s (%p)\n", - offset, name, dname); - free(name); -); - memcpy(rdata + offset, &dname, sizeof(knot_dname_t *)); - offset += sizeof(knot_dname_t *); - //parse dname from binary - } else if (descriptor_item_is_fixed(item)) { - //copy the whole thing - // TODO check the size - assert(item == scanner->r_data_blocks[i + 1] - - scanner->r_data_blocks[i]); - memcpy(rdata + offset, - scanner->r_data + scanner->r_data_blocks[i], - item); - offset += item; - } else if (descriptor_item_is_remainder(item)) { - //copy the rest - memcpy(rdata + offset, - scanner->r_data + scanner->r_data_blocks[i], - scanner->r_data_blocks[i + 1] - - scanner->r_data_blocks[i]); - offset += scanner->r_data_blocks[i + 1] - - scanner->r_data_blocks[i]; - } else { - //NAPTR - assert(knot_rrset_type(rrset) == KNOT_RRTYPE_NAPTR); - assert(0); - } - } - - return KNOT_EOK; -} - -static void process_rr(const scanner_t *scanner) -{ - dbg_zp_detail("Owner from parser=%s\n", - scanner->r_owner); - rr_count++; - char add = 0; - parser_context_t *parser = scanner->data; - knot_zone_contents_t *contents = parser->current_zone; - /* Create rrset. TODO will not be always needed. */ - knot_dname_t *current_owner = NULL; - knot_rrset_t *current_rrset = NULL; - if (parser->last_node && - (scanner->r_owner_length == parser->last_node->owner->size) && - (strncmp((char *)parser->last_node->owner->name, - (char *)scanner->r_owner, scanner->r_owner_length) == 0)) { - // no need to create new dname; - current_owner = parser->last_node->owner; - // what about RRSet, do we need a new one? - current_rrset = knot_node_get_rrset(parser->last_node, - scanner->r_type); - if (current_rrset == NULL) { - add = 1; - new_rr_count++ ; - current_rrset = - knot_rrset_new(current_owner, - scanner->r_type, - scanner->r_class, - scanner->r_ttl); - } - } else { - add = 1; -// if (strncmp((char *)parser->last_node->owner->name, -// (char *)scanner->r_owner, scanner->r_owner_length)) { -// new_dname_count++; -// current_owner = -// knot_dname_new_from_wire(scanner->r_owner, -// scanner->r_owner_length, -// NULL); -// } else { -// current_owner = parser->last_node->owner; -// } - current_owner = - knot_dname_new_from_wire(scanner->r_owner, - scanner->r_owner_length, - NULL); - new_rr_count++; - new_dname_count++; - current_rrset = - knot_rrset_new(current_owner, - scanner->r_type, - scanner->r_class, - scanner->r_ttl); - knot_dname_release(current_owner); - } - - assert(current_owner); - parser->current_rrset = current_rrset; - assert(current_rrset); - - int ret = add_rdata_to_rr(current_rrset, scanner); - assert(ret == 0); - - dbg_zp_verb("zp: process_rr: Processing type: %s.\n", - knot_rrtype_to_string(parser->current_rrset->type)); - dbg_zp_verb("zp: process_rr: RDATA count: %d.\n",\ - parser->current_rrset->rdata->count); - - assert(current_rrset->rdata_count); - - int (*node_add_func)(knot_zone_contents_t *, knot_node_t *, int, - uint8_t, int); - knot_node_t *(*node_get_func)(const knot_zone_contents_t *, - const knot_dname_t *); - - - /* If we have RRSIG of NSEC3 type first node will have - * to be created in NSEC3 part of the zone */ - - uint16_t type_covered = 0; - if (current_rrset->type == KNOT_RRTYPE_RRSIG) { - type_covered = - knot_rrset_rdata_rrsig_type_covered(current_rrset); - } - - if (current_rrset->type != KNOT_RRTYPE_NSEC3 && - type_covered != KNOT_RRTYPE_NSEC3) { - node_add_func = &knot_zone_contents_add_node; - node_get_func = &knot_zone_contents_get_node; - } else { - node_add_func = &knot_zone_contents_add_nsec3_node; - node_get_func = &knot_zone_contents_get_nsec3_node; - } - - if (current_rrset->type == KNOT_RRTYPE_SOA) { - if (knot_node_rrset(knot_zone_contents_apex(contents), - KNOT_RRTYPE_SOA) != NULL) { - /* Receiving another SOA. */ - if (!knot_rrset_equal(current_rrset, - knot_node_rrset(knot_zone_contents_apex(contents), - KNOT_RRTYPE_SOA), KNOT_RRSET_COMPARE_WHOLE)) { - parser->ret = KNOTDZCOMPILE_ESOA; - return; - } else { - log_zone_warning("encountered identical " - "extra SOA record"); - parser->ret = KNOTDZCOMPILE_EOK; - return; - } - } - } - - /*!< \todo Make sure the maximum RDLENGTH does not exceed 65535 bytes.*/ - - if (current_rrset->type == KNOT_RRTYPE_SOA) { - if (knot_dname_compare(current_rrset->owner, - parser->origin_from_config) != 0) { - fprintf(stderr, "SOA record has a different " - "owner than the one specified " - "in config! \n"); - /* Such SOA cannot even be added, because - * it would not be in the zone apex. */ - parser->ret = KNOTDZCOMPILE_ESOA; - return; - } - } - - if (current_rrset->type == KNOT_RRTYPE_RRSIG) { - knot_rrset_t *tmp_rrsig = current_rrset; - - if (parser->last_node && - knot_dname_compare(parser->last_node->owner, - current_rrset->owner) != 0) { - /* RRSIG is first in the node, so we have to create it - * before we return - */ - if (parser->node_rrsigs != NULL) { - process_rrsigs_in_node(parser, - contents, - parser->last_node); - rrset_list_delete(&parser->node_rrsigs); - } - - /* The node might however been created previously. */ - parser->last_node = - knot_zone_contents_get_node(contents, - knot_rrset_owner(current_rrset)); - - if (parser->last_node == NULL) { - /* Try NSEC3 tree. */ - if (current_rrset->type == KNOT_RRTYPE_NSEC3 || - current_rrset->type == KNOT_RRTYPE_RRSIG) { - parser->last_node = - knot_zone_contents_get_nsec3_node( - contents, - knot_rrset_owner( - current_rrset)); - } - } - - if (parser->last_node == NULL) { - /* Still NULL, node has to be created. */ - if ((parser->last_node = create_node(contents, - current_rrset, node_add_func, - node_get_func)) == NULL) { - knot_rrset_free(&tmp_rrsig); - dbg_zp("zp: process_rr: Cannot " - "create new node.\n"); - parser->ret = KNOTDZCOMPILE_EBADNODE; - return; - } - } - } - - if (rrset_list_add(&parser->node_rrsigs, tmp_rrsig) != 0) { - dbg_zp("zp: process_rr: Cannot " - "create new node.\n"); - parser->ret = KNOTDZCOMPILE_ENOMEM; - return; - } - - dbg_zp_verb("zp: process_rr: RRSIG proccesed successfully.\n"); - parser->ret = KNOTDZCOMPILE_EOK; - return; - } - - /*! \todo Move RRSIG and RRSet handling to funtions. */ - assert(current_rrset->type != KNOT_RRTYPE_RRSIG); - - knot_node_t *node = NULL; - /* \note this could probably be much simpler */ - if (parser->last_node && current_rrset->type != KNOT_RRTYPE_SOA && - knot_dname_compare(parser->last_node->owner, - current_rrset->owner) == - 0) { - node = parser->last_node; - } else { - if (parser->last_node && parser->node_rrsigs) { - process_rrsigs_in_node(parser, - contents, - parser->last_node); - } - - rrset_list_delete(&parser->node_rrsigs); - - /* new node */ - node = node_get_func(contents, current_rrset->owner); - } - - if (node == NULL) { - if (parser->last_node && parser->node_rrsigs) { - process_rrsigs_in_node(parser, - contents, - parser->last_node); - } - - if ((node = create_node(contents, current_rrset, - node_add_func, - node_get_func)) == NULL) { - dbg_zp("zp: process_rr: Cannot " - "create new node.\n"); - parser->ret = KNOTDZCOMPILE_EBADNODE; - return; - } - } - -// rrset = knot_node_get_rrset(node, current_rrset->type); -// if (!rrset) { -// rrset = current_rrset; -// } else { -// merged = 1; -// } -/// if (!rrset) { -// int ret = knot_rrset_deep_copy(current_rrset, &rrset, 1); -// if (ret != KNOT_EOK) { -// dbg_zp("zp: Cannot copy RRSet.\n"); -// return ret; -// } -// rrset = knot_rrset_new(current_rrset->owner, -// current_rrset->type, -// current_rrset->rclass, -// current_rrset->ttl); -// if (rrset == NULL) { -// dbg_zp("zp: process_rr: Cannot " -// "create new RRSet.\n"); -// return KNOTDZCOMPILE_ENOMEM; -// } - -// if (knot_rrset_add_rdata(rrset, current_rrset->rdata) != 0) { -// knot_rrset_free(&rrset); -// dbg_zp("zp: process_rr: Cannot " -// "add RDATA to RRSet.\n"); -// return KNOTDZCOMPILE_EBRDATA; -// } - - /* Selected merge option does not really matter here. */ -// if (knot_zone_contents_add_rrset(contents, current_rrset, &node, -// KNOT_RRSET_DUPL_MERGE, 1) < 0) { -// knot_rrset_free(&rrset); -// dbg_zp("zp: process_rr: Cannot " -// "add RDATA to RRSet.\n"); -// return KNOTDZCOMPILE_EBRDATA; -// } -// } else { -// TODO needs solving -// if (current_rrset->type != -// KNOT_RRTYPE_RRSIG && rrset->ttl != -// current_rrset->ttl) { -// fprintf(stderr, -// "TTL does not match the TTL of the RRSet. " -// "Changing to %d.\n", rrset->ttl); -// } - - if (add) { - ret = knot_zone_contents_add_rrset(contents, current_rrset, - &node, - KNOT_RRSET_DUPL_MERGE, 1); - if (ret < 0) { - dbg_zp("zp: process_rr: Cannot " - "add RRSets.\n"); - /*!< \todo mixed error codes, has to be changed. */ - parser->ret = ret; - return; - } else if (ret > 0) { - knot_rrset_deep_free(¤t_rrset, 0, 0); - } - } -// } - - parser->last_node = node; - - dbg_zp_verb("zp: process_rr: RRSet %p processed successfully.\n", - parser->current_rrset); - parser->ret = KNOTDZCOMPILE_EOK; -} - -int zone_read(const char *name, const char *zonefile, - int semantic_checks, knot_zone_t **out_zone) -{ - parser_context_t my_parser; - my_parser.origin_from_config = knot_dname_new_from_str(name, - strnlen((char *)name, - 255), - NULL); - assert(my_parser.origin_from_config); - my_parser.last_node = knot_node_new(my_parser.origin_from_config, - NULL, 0); - knot_zone_t *zone = knot_zone_new(my_parser.last_node, 0, 0); - my_parser.current_zone = knot_zone_get_contents(zone); - my_parser.node_rrsigs = NULL; - file_loader_t *loader = file_loader_create(zonefile, name, - KNOT_CLASS_IN, 3600, - process_rr, - process_error, - &my_parser); - file_loader_process(loader); - if (my_parser.last_node && my_parser.node_rrsigs) { - process_rrsigs_in_node(&my_parser, - my_parser.current_zone, - my_parser.last_node); - } - if (my_parser.ret != KNOTDZCOMPILE_EOK) { - log_zone_error("Zone could not be loaded (%d).", my_parser.ret); - /*!< \todo Depending on the error, free stuff. */ - rrset_list_delete(&my_parser.node_rrsigs); - file_loader_free(loader); - return KNOT_ERROR; - } - knot_zone_contents_adjust(my_parser.current_zone); - rrset_list_delete(&my_parser.node_rrsigs); - file_loader_free(loader); - *out_zone = zone; - return KNOT_EOK; -} - -/*! @} */ diff --git a/src/zcompile/zcompile.h b/src/zcompile/zcompile.h deleted file mode 100644 index f00d93cae34a8de84e4727397f34283d065a4899..0000000000000000000000000000000000000000 --- a/src/zcompile/zcompile.h +++ /dev/null @@ -1,119 +0,0 @@ -/*! - * \file zoneparser.h - * - * \author modifications by Jan Kadlec <jan.kadlec@nic.cz>, most of the code - * by NLnet Labs. - * Copyright (c) 2001-2011, NLnet Labs. All rights reserved. - * - * \brief Zone compiler. - * - * \addtogroup zoneparser - * @{ - */ - -/* - * Copyright (c) 2001-2011, NLnet Labs. All rights reserved. - * - * This software is open source. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * - * Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * - * Neither the name of the NLNET LABS nor the names of its contributors may - * be used to endorse or promote products derived from this software without - * specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED - * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - */ - -#ifndef _KNOTD_ZONEPARSER_H_ -#define _KNOTD_ZONEPARSER_H_ - -#include <stdio.h> - -#include "libknot/dname.h" -#include "libknot/rrset.h" -#include "libknot/zone/node.h" -#include "libknot/zone/zone.h" -#include "libknot/zone/dname-table.h" -#include "libknot/zone/dname-table.h" -#include "common/slab/slab.h" - -#define MAXRDATALEN 64 /*!< Maximum number of RDATA items. */ -#define MAXLABELLEN 63 /*!< Maximum label length. */ -#define MAXDOMAINLEN 255 /*!< Maximum domain name length */ -#define MAX_RDLENGTH 65535 /*!< Maximum length of RDATA item */ -#define MAXTOKENSLEN 512 /*!< Maximum number of tokens per entry. */ -#define B64BUFSIZE 65535 /*!< Buffer size for b64 conversion. */ -#define ROOT (const uint8_t *)"\001" /*!< Root domain name. */ - -#define NSEC_WINDOW_COUNT 256 /*!< Number of NSEC windows. */ -#define NSEC_WINDOW_BITS_COUNT 256 /*!< Number of bits in NSEC window. */ -/*! \brief Size of NSEC window in bytes. */ -#define NSEC_WINDOW_BITS_SIZE (NSEC_WINDOW_BITS_COUNT / 8) - -/* - * RFC 4025 - codes for different types that IPSECKEY can hold. - */ -#define IPSECKEY_NOGATEWAY 0 -#define IPSECKEY_IP4 1 -#define IPSECKEY_IP6 2 -#define IPSECKEY_DNAME 3 - -#define LINEBUFSZ 1024 /*!< Buffer size for one line in zone file. */ - -struct lex_data { - size_t len; /*!< holds the label length */ - char *str; /*!< holds the data */ -}; - -#define DEFAULT_TTL 3600 - -/*! \todo Implement ZoneDB. */ -typedef void namedb_type; - -/*! - * \brief One-purpose linked list holding pointers to RRSets. - */ -struct rrset_list { - knot_rrset_t *data; /*!< List data. */ - struct rrset_list *next; /*!< Next node. */ -}; - -typedef struct rrset_list rrset_list_t; - -/*! - * \brief Parses and creates zone from given file. - * - * \param name Origin domain name string. - * \param zonefile File containing the zone. - * \param outfile File to save dump of the zone to. - * \param semantic_checks Enables or disables sematic checks. - * - * \retval 0 on success. - * \retval -1 on error. - */ -int zone_read(const char *name, const char *zonefile, int semantic_checks, - knot_zone_t **out_zone); - -#endif /* _KNOTD_ZONEPARSER_H_ */ - -/*! @} */ diff --git a/src/zcompile/zcompile_main.c b/src/zcompile/zcompile_main.c deleted file mode 100644 index 0818970bcd7f19c042bcc74756c2924ff5a12b5e..0000000000000000000000000000000000000000 --- a/src/zcompile/zcompile_main.c +++ /dev/null @@ -1,111 +0,0 @@ -/* Copyright (C) 2011 CZ.NIC, z.s.p.o. <knot-dns@labs.nic.cz> - - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see <http://www.gnu.org/licenses/>. - */ - -#include <config.h> -#include <unistd.h> -#include <stdlib.h> - -#include "zcompile/zcompile.h" -#include "common/log.h" -#include <config.h> - -static void help(int argc, char **argv) -{ - printf("Usage: %s [parameters] origin zonefile\n", - argv[0]); - printf("\n:Parameters:\n" - " -o <outfile> Override output file.\n" - " -v Verbose mode - additional runtime information.\n" - " -s Enable semantic checks.\n" - " -V Print version of the server.\n" - " -h Print help and usage.\n"); -} - -int main(int argc, char **argv) -{ - // Parse command line arguments - int c = 0; - int verbose = 0; - int semantic_checks = 0; - const char* origin = 0; - const char* zonefile = 0; - const char* outfile = 0; - while ((c = getopt (argc, argv, "o:vVsh")) != -1) { - switch (c) - { - case 'o': - outfile = optarg; - break; - case 'v': - verbose = 1; - break; - case 'V': - printf("%s, version %s\n", "Knot DNS", PACKAGE_VERSION); - return 0; - case 's': - semantic_checks = 1; - break; - case 'h': - case '?': - default: - if (optopt == 'o') { - fprintf (stderr, - "Option -%c requires an argument.\n", - optopt); - } - help(argc, argv); - return 1; - } - } - - UNUSED(verbose); - - // Check if there's at least two remaining non-option - if (argc - optind < 2) { - help(argc, argv); - return 1; - } - - origin = argv[optind]; - zonefile = argv[optind + 1]; - - // Initialize log (no syslog) - log_init(); - log_levels_set(LOGT_SYSLOG, LOG_ANY, 0); - if (outfile != NULL) { - log_zone_info("Parsing file '%s', origin '%s' ...\n", - zonefile, origin); - } - - int error = zone_read(origin, zonefile, outfile, semantic_checks); - - if (error != 0) { - /* FIXME! */ -// if (error < 0) { -// fprintf(stderr, "Finished with error: %s.\n", -// error_to_str(knot_zcompile_error_msgs, error)); -// } else { -// fprintf(stderr, "Finished with %u errors.\n"); -// } - return 1; - } else if (outfile != NULL) { - log_zone_info("Compilation of '%s' successful.\n", origin); - } else { - log_zone_info("Zone file for '%s' is OK.\n", origin); - } - - return 0; -} diff --git a/src/zcompile/zlexer.l b/src/zcompile/zlexer.l deleted file mode 100644 index 58e64396472dbebe5ac92417f482d039916fb81a..0000000000000000000000000000000000000000 --- a/src/zcompile/zlexer.l +++ /dev/null @@ -1,532 +0,0 @@ -%{ -/*! - * \file zlexer.l - * - * \author minor modifications by Jan Kadlec <jan.kadlec@nic.cz>, - * most of the code by NLnet Labs - * Copyright (c) 2001-2011, NLnet Labs. All rights reserved. - * - * \brief lexical analyzer for (DNS) zone files. - * - * \addtogroup zoneparser - * @{ - */ - -/* - * Copyright (c) 2001-2011, NLnet Labs. All rights reserved. - * - * This software is open source. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * - * Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * - * Neither the name of the NLNET LABS nor the names of its contributors may - * be used to endorse or promote products derived from this software without - * specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED - * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - */ - -//#include "common.h" - -#include <ctype.h> -#include <errno.h> -#include <string.h> -#include <strings.h> -#include <assert.h> - -#include "zcompile/zcompile.h" -#include "libknot/dname.h" -#include "zcompile/parser-descriptor.h" -#include "zparser.h" - -#define YY_NO_INPUT - -/* Utils */ -extern void zc_error(const char *fmt, ...); -extern void zc_warning(const char *fmt, ...); - -void strip_string(char *str) -{ - char *start = str; - char *end = str + strlen(str) - 1; - - while (isspace(*start)) - ++start; - if (start > end) { - /* Completely blank. */ - str[0] = '\0'; - } else { - while (isspace(*end)) - --end; - *++end = '\0'; - - if (str != start) - memmove(str, start, end - start + 1); - } -} - -int hexdigit_to_int(char ch) -{ - switch (ch) { - case '0': return 0; - case '1': return 1; - case '2': return 2; - case '3': return 3; - case '4': return 4; - case '5': return 5; - case '6': return 6; - case '7': return 7; - case '8': return 8; - case '9': return 9; - case 'a': case 'A': return 10; - case 'b': case 'B': return 11; - case 'c': case 'C': return 12; - case 'd': case 'D': return 13; - case 'e': case 'E': return 14; - case 'f': case 'F': return 15; - default: - abort(); - } -} - -extern uint32_t strtottl(const char *nptr, const char **endptr); - -#define YY_NO_UNPUT -#define MAXINCLUDES 10 - -#define scanner yyscanner -extern int zp_lex(YYSTYPE *lvalp, void *scanner); - -#if 0 -#define LEXOUT(s) printf s /* used ONLY when debugging */ -#else -#define LEXOUT(s) -#endif - -enum lexer_state { - EXPECT_OWNER, - PARSING_OWNER, - PARSING_TTL_CLASS_TYPE, - PARSING_RDATA -}; - -static YY_BUFFER_STATE include_stack[MAXINCLUDES]; -static zparser_type zparser_stack[MAXINCLUDES]; -static int include_stack_ptr = 0; - -static void pop_parser_state(void *scanner); -static void push_parser_state(FILE *input, void *scanner); -static int parse_token(void *scanner, int token, char *in_str, - enum lexer_state *lexer_state); - - -/*!< \todo does not compile */ -#ifndef yy_set_bol // compat definition, for flex 2.4.6 -#define yy_set_bol(at_bol) \ -{ \ - if (!yy_current_buffer ) \ - yy_current_buffer = yy_create_buffer( yyin, YY_BUF_SIZE ); \ - yy_current_buffer->yy_ch_buf[0] = ((at_bol)?'\n':' '); \ -} -#endif - -%} - -%option nounput -%option reentrant bison-bridge -%option prefix = "zp_" -%option outfile = "lex.yy.c" - -SPACE [ \t] -LETTER [a-zA-Z] -NEWLINE [\n\r] -ZONESTR [^ \t\n\r();.\"\$] -DOLLAR \$ -COMMENT ; -DOT \. -BIT [^\]\n]|\\. -ANY [^\"\n\\]|\\. - -%x incl bitlabel quotedstring - -%% - static int paren_open = 0; - static enum lexer_state lexer_state = EXPECT_OWNER; - -{SPACE}*{COMMENT}.* /* ignore */ -^{DOLLAR}TTL { lexer_state = PARSING_RDATA; return DOLLAR_TTL; } -^{DOLLAR}ORIGIN { lexer_state = PARSING_RDATA; return DOLLAR_ORIGIN; } - - /* - * Handle $INCLUDE directives. See - * http://dinosaur.compilertools.net/flex/flex_12.html#SEC12. - */ -^{DOLLAR}INCLUDE { - BEGIN(incl); -} -<incl>\n | -<incl><<EOF>> { - int error_occurred = parser->error_occurred; - BEGIN(INITIAL); - zc_error("missing file name in $INCLUDE directive"); - yy_set_bol(1); /* Set beginning of line, so "^" rules match. */ - ++parser->line; - parser->error_occurred = error_occurred; -} -<incl>.+ { - char *tmp; - /*! \todo pointer to origin. */ - void *origin = parser->origin; - /* domain_type *origin = parser->origin; */ - int error_occurred = parser->error_occurred; - - BEGIN(INITIAL); - if (include_stack_ptr >= MAXINCLUDES ) { - zc_error("includes nested too deeply, skipped (>%d)", - MAXINCLUDES); - } else { - FILE *input; - - /* Remove trailing comment. */ - tmp = strrchr(yytext, ';'); - if (tmp) { - *tmp = '\0'; - } - strip_string(yytext); - - /* Parse origin for include file. */ - tmp = strrchr(yytext, ' '); - if (!tmp) { - tmp = strrchr(yytext, '\t'); - } - if (tmp) { - /* split the original yytext */ - *tmp = '\0'; - strip_string(yytext); - - /*! \todo knot_dname_new_from_wire() (dname.h) - * which knot_node to pass as node? - */ - knot_dname_t *dname; - dname = knot_dname_new_from_wire((uint8_t*)tmp + 1, - strlen(tmp + 1), - NULL); - if (!dname) { - zc_error("incorrect include origin '%s'", - tmp + 1); - } else { - /*! \todo insert to zonedb. */ - /* origin = domain_table_insert( - parser->db->domains, dname); */ - } - } - - if (strlen(yytext) == 0) { - zc_error("missing file name in $INCLUDE directive"); - } else if (!(input = fopen(yytext, "r"))) { - char ebuf[256] = {0}; - strerror_r(errno, ebuf, sizeof(ebuf)); - zc_error("cannot open include file '%s': %s", - yytext, ebuf); - } else { - /* Initialize parser for include file. */ - char *filename = strdup(yytext); - push_parser_state(input, scanner); /* Destroys yytext. */ - parser->filename = filename; - parser->line = 1; - parser->origin = origin; - lexer_state = EXPECT_OWNER; - } - } - - parser->error_occurred = error_occurred; -} -<INITIAL><<EOF>> { - yy_set_bol(1); /* Set beginning of line, so "^" rules match. */ - if (include_stack_ptr == 0) { - // from: http://stackoverflow.com/questions/1756275/bison-end-of-file - static int once = 0; - once++; - if (once > 1) { - yyterminate(); - } else { - return NL; - } - } else { - fclose(yyin); - pop_parser_state(scanner); - } -} -^{DOLLAR}{LETTER}+ { zc_warning("Unknown directive: %s", yytext); } -{DOT} { - LEXOUT((". ")); - return parse_token(scanner, '.', yytext, &lexer_state); -} -@ { - LEXOUT(("@ ")); - return parse_token(scanner, '@', yytext, &lexer_state); -} -\\# { - LEXOUT(("\\# ")); - return parse_token(scanner, URR, yytext, &lexer_state); -} -{NEWLINE} { - ++parser->line; - if (!paren_open) { - lexer_state = EXPECT_OWNER; - LEXOUT(("NL\n")); - return NL; - } else { - LEXOUT(("SP ")); - return SP; - } -} -\( { - if (paren_open) { - zc_error("nested parentheses"); - yyterminate(); - } - LEXOUT(("( ")); - paren_open = 1; - return SP; -} -\) { - if (!paren_open) { - zc_error("closing parentheses without opening parentheses"); - yyterminate(); - } - LEXOUT((") ")); - paren_open = 0; - return SP; -} -{SPACE}+ { - if (!paren_open && lexer_state == EXPECT_OWNER) { - lexer_state = PARSING_TTL_CLASS_TYPE; - LEXOUT(("PREV ")); - return PREV; - } - if (lexer_state == PARSING_OWNER) { - lexer_state = PARSING_TTL_CLASS_TYPE; - } - LEXOUT(("SP ")); - return SP; -} - - /* Bitlabels. Strip leading and ending brackets. */ -\\\[ { BEGIN(bitlabel); } -<bitlabel><<EOF>> { - zc_error("EOF inside bitlabel"); - BEGIN(INITIAL); -} -<bitlabel>{BIT}* { yymore(); } -<bitlabel>\n { ++parser->line; yymore(); } -<bitlabel>\] { - BEGIN(INITIAL); - yytext[yyleng - 1] = '\0'; - return parse_token(scanner, BITLAB, yytext, &lexer_state); -} - - /* Quoted strings. Strip leading and ending quotes. */ -\" { BEGIN(quotedstring); LEXOUT(("\" ")); } -<quotedstring><<EOF>> { - zc_error("EOF inside quoted string"); - BEGIN(INITIAL); -} -<quotedstring>{ANY}* { LEXOUT(("STR ")); yymore(); } -<quotedstring>\n { ++parser->line; yymore(); } -<quotedstring>\" { - LEXOUT(("\" ")); - BEGIN(INITIAL); - yytext[yyleng - 1] = '\0'; - return parse_token(scanner, STR, yytext, &lexer_state); -} - -({ZONESTR}|\\.|\\\n)+ { - /* Any allowed word. */ - return parse_token(scanner, STR, yytext, &lexer_state); -} -. { - zc_error("unknown character '%c' (\\%03d) seen - is this a zonefile?", - (int) yytext[0], (int) yytext[0]); -} -%% - -/* - * Analyze "word" to see if it matches an RR type, possibly by using - * the "TYPExxx" notation. If it matches, the corresponding token is - * returned and the TYPE parameter is set to the RR type value. - */ -static int -rrtype_to_token(const char *word, uint16_t *type) -{ - uint16_t t = parser_rrtype_from_string(word); - if (t != 0) { - parser_rrtype_descriptor_t *entry = 0; - entry = parser_rrtype_descriptor_by_type(t); - *type = t; - - /*! \todo entry should return associated token. - see nsd/dns.c */ - return entry->token; - } - - return 0; -} - - -/* - * Remove \DDD constructs from the input. See RFC 1035, section 5.1. - */ -static size_t -zoctet(char *text) -{ - /* - * s follows the string, p lags behind and rebuilds the new - * string - */ - char *s; - char *p; - - for (s = p = text; *s; ++s, ++p) { - assert(p <= s); - if (s[0] != '\\') { - /* Ordinary character. */ - *p = *s; - } else if (isdigit((int)s[1]) && isdigit((int)s[2]) && isdigit((int)s[3])) { - /* \DDD escape. */ - int val = (hexdigit_to_int(s[1]) * 100 + - hexdigit_to_int(s[2]) * 10 + - hexdigit_to_int(s[3])); - if (0 <= val && val <= 255) { - s += 3; - *p = val; - } else { - zc_warning("text escape \\DDD overflow"); - *p = *++s; - } - } else if (s[1] != '\0') { - /* \X where X is any character, keep X. */ - *p = *++s; - } else { - /* Trailing backslash, ignore it. */ - zc_warning("trailing backslash ignored"); - --p; - } - } - *p = '\0'; - return p - text; -} - -static int parse_token(void *scanner, int token, char *in_str, - enum lexer_state *lexer_state) -{ - size_t len = 0; - char *str = NULL; - - struct yyguts_t *yyg = (struct yyguts_t *)scanner; - - if (*lexer_state == EXPECT_OWNER) { - *lexer_state = PARSING_OWNER; - } else if (*lexer_state == PARSING_TTL_CLASS_TYPE) { - const char *t; - int token; - uint16_t rrclass; - - /* type */ - token = rrtype_to_token(in_str, &yylval->type); - if (token != 0) { - *lexer_state = PARSING_RDATA; - LEXOUT(("%d[%s] ", token, in_str)); - return token; - } - - /* class */ - rrclass = parser_rrclass_from_string(in_str); - if (rrclass != 0) { - yylval->rclass = rrclass; - LEXOUT(("CLASS ")); - return T_RRCLASS; - } - - /* ttl */ - yylval->ttl = strtottl(in_str, &t); - if (*t == '\0') { - LEXOUT(("TTL ")); - return T_TTL; - } - } - - str = strdup(yytext); - if (str == NULL) { - /* Out of memory */ - ERR_ALLOC_FAILED; - return NO_MEM; - } - len = zoctet(str); - - yylval->data.str = str; - assert(yylval->data.str != NULL); - yylval->data.len = len; - - if (strcmp(yytext, ".") == 0) { - free(str); - yylval->data.str="."; - } else if (strcmp(str, "@") == 0) { - free(str); - yylval->data.str="@"; - } else if (strcmp(str, "\\#") == 0) { - free(str); - yylval->data.str="\\#"; - } - - LEXOUT(("%d[%s] ", token, in_str)); - return token; -} - -/* - * Saves the file specific variables on the include stack. - */ -static void push_parser_state(FILE *input, void *scanner) -{ - struct yyguts_t *yyg = (struct yyguts_t *)scanner; - zparser_stack[include_stack_ptr].filename = parser->filename; - zparser_stack[include_stack_ptr].line = parser->line; - zparser_stack[include_stack_ptr].origin = parser->origin; - include_stack[include_stack_ptr] = YY_CURRENT_BUFFER; - yy_switch_to_buffer(yy_create_buffer(input, YY_BUF_SIZE, scanner), - scanner); - ++include_stack_ptr; -} - -/* - * Restores the file specific variables from the include stack. - */ -void pop_parser_state(void *scanner) -{ - struct yyguts_t *yyg = (struct yyguts_t *)scanner; - --include_stack_ptr; - parser->filename = zparser_stack[include_stack_ptr].filename; - parser->line = zparser_stack[include_stack_ptr].line; - parser->origin = zparser_stack[include_stack_ptr].origin; - yy_delete_buffer(YY_CURRENT_BUFFER, scanner); - yy_switch_to_buffer(include_stack[include_stack_ptr], scanner); -} diff --git a/src/zcompile/zparser.y b/src/zcompile/zparser.y deleted file mode 100644 index fd0d1b87529597c3f5d8d9b4a6f1a481d7d13cf9..0000000000000000000000000000000000000000 --- a/src/zcompile/zparser.y +++ /dev/null @@ -1,1774 +0,0 @@ -%{ -/*! - * \file zparser.y - * - * \author modifications by Jan Kadlec <jan.kadlec@nic.cz>, - * notable changes: normal allocation, parser is reentrant. - * most of the code by NLnet Labs - * Copyright (c) 2001-2011, NLnet Labs. All rights reserved. - * - * \brief yacc grammar for (DNS) zone files - * - * \addtogroup zoneparser - * @{ - */ - -/* - * Copyright (c) 2001-2011, NLnet Labs. All rights reserved. - * - * This software is open source. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * - * Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * - * Neither the name of the NLNET LABS nor the names of its contributors may - * be used to endorse or promote products derived from this software without - * specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED - * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - */ - -//#include "common.h" - -#include <stdarg.h> -#include <stdio.h> -#include <string.h> -#include <assert.h> - -#include "zcompile/parser-util.h" -#include "common/log.h" - -#include "libknot/libknot.h" -#include "zcompile/zcompile.h" -#include "zcompile/parser-descriptor.h" -#include "zcompile/zcompile-error.h" -#include "zparser.h" - -/* these need to be global, otherwise they cannot be used inside yacc */ -zparser_type *parser; - -#ifdef __cplusplus -extern "C" -#endif /* __cplusplus */ -int zp_wrap(void); - -/* this hold the nxt bits */ -static uint8_t nxtbits[16]; -static int dlv_warn = 1; - -/* 256 windows of 256 bits (32 bytes) */ -/* still need to reset the bastard somewhere */ -static uint8_t nsecbits[NSEC_WINDOW_COUNT][NSEC_WINDOW_BITS_SIZE]; - -/* hold the highest rcode seen in a NSEC rdata , BUG #106 */ -uint16_t nsec_highest_rcode; - -void zp_error(void *scanner, const char *message); -int zp_lex(YYSTYPE *lvalp, void *scanner); - -/* helper functions */ -void zc_error(const char *fmt, ...); -void zc_warning(const char *fmt, ...); -void zc_error_prev_line(const char *fmt, ...); -void zc_warning_prev_line(const char *fmt, ...); - -#define NSEC3 -#ifdef NSEC3 -/* parse nsec3 parameters and add the (first) rdata elements */ -static void -nsec3_add_params(const char* hash_algo_str, const char* flag_str, - const char* iter_str, const char* salt_str, int salt_len); -#endif /* NSEC3 */ - -knot_dname_t *error_dname; //XXX used to be const -knot_dname_t *error_domain; - -%} -%union { - knot_dname_t *domain; - knot_dname_t *dname; - struct lex_data data; - uint32_t ttl; - uint16_t rclass; - uint16_t type; - uint16_t *unknown; -} - -%pure-parser -%parse-param {void *scanner} -%lex-param {void *scanner} -%name-prefix = "zp_" - -/* - * Tokens to represent the known RR types of DNS. - */ -%token <type> T_A T_NS T_MX T_TXT T_CNAME T_AAAA T_PTR T_NXT T_KEY T_SOA T_SIG -%token <type> T_SRV T_CERT T_LOC T_MD T_MF T_MB T_MG T_MR T_NULL T_WKS T_HINFO -%token <type> T_MINFO T_RP T_AFSDB T_X25 T_ISDN T_RT T_NSAP T_NSAP_PTR T_PX -%token <type> T_GPOS T_EID T_NIMLOC T_ATMA T_NAPTR T_KX T_A6 T_DNAME T_SINK -%token <type> T_OPT T_APL T_UINFO T_UID T_GID T_UNSPEC T_TKEY T_TSIG T_IXFR -%token <type> T_AXFR T_MAILB T_MAILA T_DS T_DLV T_SSHFP T_RRSIG T_NSEC T_DNSKEY -%token <type> T_SPF T_NSEC3 T_IPSECKEY T_DHCID T_NSEC3PARAM T_TLSA - -/* other tokens */ -%token DOLLAR_TTL DOLLAR_ORIGIN NL SP NO_MEM -%token <data> STR PREV BITLAB -%token <ttl> T_TTL -%token <rclass> T_RRCLASS - -/* unknown RRs */ -%token URR -%token <type> T_UTYPE - -%type <type> type_and_rdata -%type <domain> owner dname abs_dname -%type <dname> rel_dname label -%type <data> wire_dname wire_abs_dname wire_rel_dname wire_label -%type <data> concatenated_str_seq str_sp_seq str_dot_seq dotted_str -%type <data> nxt_seq nsec_more -%type <unknown> rdata_unknown - -%% -lines: /* empty file */ - | lines line - ; - -line: NL - | sp NL - | NO_MEM { - zc_error_prev_line("Parser ran out of memory!"); - YYABORT; - } - | PREV NL {} /* Lines containing only whitespace. */ - | ttl_directive - { - parser->error_occurred = 0; - } - | origin_directive - { - parser->error_occurred = 0; - } - | rr - { /* rr should be fully parsed */ - if (!parser->error_occurred) { - /*!< \todo assign error to error occurred */ - /*! \todo Make sure this does not crash */ - if (parser->current_rrset->owner == NULL) { - knot_rrset_deep_free(&(parser->current_rrset), - 0, 0, 0); - knot_zone_deep_free(&(parser->current_zone), - 1); - YYABORT; - } - knot_rdata_t *tmp_rdata = knot_rdata_new(); - if (tmp_rdata == NULL) { - knot_rrset_deep_free(&(parser->current_rrset), - 0, 0, 0); - knot_zone_deep_free(&(parser->current_zone), - 1); - YYABORT; - } - - if (knot_rdata_set_items(tmp_rdata, - parser->temporary_items, - parser->rdata_count) != 0) { - knot_rdata_free(&tmp_rdata); - knot_rrset_deep_free(&(parser->current_rrset), 0, 0, 0); - knot_zone_deep_free(&(parser->current_zone), 1); - YYABORT; - } - - assert(parser->current_rrset->rdata == NULL); -// if (knot_rrset_add_rdata(parser->current_rrset, tmp_rdata) -// != 0) { -// log_zone_error("Could not add rdata!\n"); -// } -// tmp_rdata->next = tmp_rdata; -// parser->current_rrset->rdata = tmp_rdata; - - if (!knot_dname_is_fqdn(parser->current_rrset->owner)) { - knot_dname_t *tmp_dname = - knot_dname_cat(parser->current_rrset->owner, - parser->root_domain); - if (tmp_dname == NULL) { - knot_rrset_deep_free(&(parser->current_rrset), - 0, 0, 0); - knot_zone_deep_free(&(parser->current_zone), - 1); - YYABORT; - } -// knot_rrset_set_owner(parser->current_rrset, tmp_dname); - } - - assert(parser->current_rrset->owner != NULL); - knot_dname_retain(parser->current_rrset->owner); - int ret = 0; - if ((ret = process_rr()) != 0) { - char *name = - knot_dname_to_str(parser->current_rrset->owner); - log_zone_error("Error: could not process RRSet\n" - "owner: %s reason: %s\n", - name, - error_to_str(knot_zcompile_error_msgs, ret)); - free(name); - - /* If the owner is not already in the table, free it. */ -// if (dnslib_dname_table_find_dname(parser->dname_table, -// parser->current_rrset->owner) == NULL) { -// dnslib_dname_free(&parser-> -// current_rrset->owner); -// } /* This would never happen */ - - if (ret == KNOTDZCOMPILE_EBADSOA) { - knot_rrset_deep_free(&(parser->current_rrset), - 0, 0, 0); - knot_zone_deep_free(&(parser->current_zone), - 1); - YYABORT; - } else { - YYABORT; - /* Free rdata, it will not be added - * and hence cannot be - * freed with rest of the zone. */ -/* knot_rdata_deep_free(&tmp_rdata, - parser-> - current_rrset->type, - 0); */ - } - } - } else { - /* Error occured. This could either be lack of memory, or one - * of the converting function was not able to convert. */ - if (parser->error_occurred == KNOTDZCOMPILE_ENOMEM) { - /* Ran out of memory in converting functions. */ - log_zone_error("Parser ran out " - "of memory, aborting!\n"); - knot_rrset_deep_free(&(parser->current_rrset), - 0, 0, 0); - knot_zone_deep_free(&(parser->current_zone), - 1); - YYABORT; - } - } - -// printf("Current rrset name: %p (%s)\n", parser->current_rrset->owner->name, -// knot_dname_to_str(parser->current_rrset->owner)); - -// knot_dname_release(parser->current_rrset->owner); - - parser->current_rrset->type = 0; - parser->rdata_count = 0; - parser->current_rrset->rdata = NULL; - parser->error_occurred = 0; - } - | error NL - ; - -/* needed to cope with ( and ) in arbitary places */ -sp: SP - | sp SP - ; - -trail: NL - | sp NL - ; - -ttl_directive: DOLLAR_TTL sp STR trail - { - parser->default_ttl = zparser_ttl2int($3.str, - &(parser->error_occurred)); - if (parser->error_occurred == 1) { - parser->default_ttl = DEFAULT_TTL; - parser->error_occurred = 0; - } - - free($3.str); - } - ; - - - -origin_directive: DOLLAR_ORIGIN sp abs_dname trail - { - /*!< \todo this will leak. */ - knot_node_t *origin_node = knot_node_new($3 ,NULL, 0); - if (parser->origin != NULL) { -// knot_node_free(&parser->origin, 1); - } - parser->origin = origin_node; - } - | DOLLAR_ORIGIN sp rel_dname trail - { - zc_error_prev_line("$ORIGIN directive requires" - "absolute domain name"); - } - ; - -rr: owner classttl type_and_rdata - { - /* Save the pointer, it might get freed! */ - parser->current_rrset->owner = $1; -// parser->current_rrset->owner = $1; -// printf("new owner assigned: %p\n", $1); - parser->current_rrset->type = $3; - } - ; - -owner: dname sp - { -// char *name = knot_dname_to_str($1); -// printf("Totally new dname: %p %s\n", $1, -// name); -// free(name); - if (parser->prev_dname != NULL) { - // knot_dname_release(parser->prev_dname); - } - parser->prev_dname = $1;//knot_dname_deep_copy($1); - knot_dname_retain(parser->prev_dname); - $$ = $1; - } - | PREV - { -// printf("Name from prev_dname!: %p %s\n", parser->prev_dname, -// knot_dname_to_str(parser->prev_dname)); - knot_dname_retain(parser->prev_dname); - $$ = parser->prev_dname;//knot_dname_deep_copy(parser->prev_dname); - } - ; - -classttl: /* empty - fill in the default, def. ttl and IN class */ - { - parser->current_rrset->ttl = parser->default_ttl; - parser->current_rrset->rclass = parser->default_class; - } - | T_RRCLASS sp /* no ttl */ - { - parser->current_rrset->ttl = parser->default_ttl; - parser->current_rrset->rclass = $1; - } - | T_TTL sp /* no class */ - { - parser->current_rrset->ttl = $1; - parser->current_rrset->rclass = parser->default_class; - } - | T_TTL sp T_RRCLASS sp /* the lot */ - { - parser->current_rrset->ttl = $1; - parser->current_rrset->rclass = $3; - } - | T_RRCLASS sp T_TTL sp /* the lot - reversed */ - { - parser->current_rrset->ttl = $3; - parser->current_rrset->rclass = $1; - } - ; - -dname: abs_dname - | rel_dname - { - if ($1 == error_dname) { - $$ = error_domain; - } else if ($1->size + parser->origin->owner->size - 1 > - MAXDOMAINLEN) { - zc_error("domain name exceeds %d character limit", - MAXDOMAINLEN); - $$ = error_domain; - } else { - $$ = knot_dname_cat($1, - parser->origin->owner); - } - } - ; - -abs_dname: '.' - { - $$ = parser->root_domain; - /* TODO how about concatenation now? */ - } - | '@' - { - assert(parser->origin != NULL); - $$ = parser->origin->owner; - } - | rel_dname '.' - { - if ($1 != error_dname) { - $$ = $1; - } else { - $$ = error_domain; - } - } - ; - -label: STR - { - if ($1.len > MAXLABELLEN) { - zc_error("label exceeds %d character limit", MAXLABELLEN); - $$ = error_dname; - } else { - $$ = knot_dname_new_from_str($1.str, $1.len, NULL); - $$->ref.count = 0; - } - - free($1.str); - - } - | BITLAB - { - zc_error("bitlabels are not supported." - "RFC2673 has status experimental."); - $$ = error_dname; - } - ; - -rel_dname: label - | rel_dname '.' label - { - if ($1 == error_dname || $3 == error_dname) { - $$ = error_dname; - } else if ($1->size + $3->size - 1 > MAXDOMAINLEN) { - zc_error("domain name exceeds %d character limit", - MAXDOMAINLEN); - $$ = error_dname; - } else { - $$ = knot_dname_cat($1, $3); -// knot_dname_release($1); /*!< \todo check! */ - knot_dname_free(&$3); - } - } - ; - -/* - * Some dnames in rdata are handled as opaque blobs - */ - -wire_dname: wire_abs_dname - | wire_rel_dname - ; - -wire_abs_dname: '.' - { - char *result = malloc(2 * sizeof(char)); - if (result == NULL) { - ERR_ALLOC_FAILED; - knot_rrset_deep_free(&(parser->current_rrset), - 0, 0, 0); - knot_zone_deep_free(&(parser->current_zone), - 1); - YYABORT; - } - result[0] = 0; - result[1] = '\0'; - $$.str = result; - $$.len = 1; - } - | wire_rel_dname '.' - { - char *result = malloc($1.len + 2 * sizeof(char)); - if (result == NULL) { - ERR_ALLOC_FAILED; - knot_rrset_deep_free(&(parser->current_rrset), - 0, 0, 0); - knot_zone_deep_free(&(parser->current_zone), - 1); - YYABORT; - } - memcpy(result, $1.str, $1.len); - result[$1.len] = 0; - result[$1.len+1] = '\0'; - $$.str = result; - $$.len = $1.len + 1; - - free($1.str); -; - } - ; - -wire_label: STR - { - char *result = malloc($1.len + sizeof(char)); - if (result == NULL) { - ERR_ALLOC_FAILED; - knot_rrset_deep_free(&(parser->current_rrset), - 0, 0, 0); - knot_zone_deep_free(&(parser->current_zone), - 1); - YYABORT; - } - - if ($1.len > MAXLABELLEN) - zc_error("label exceeds %d character limit", MAXLABELLEN); - - /* make label anyway */ - result[0] = $1.len; - memcpy(result+1, $1.str, $1.len); - - $$.str = result; - $$.len = $1.len + 1; - - free($1.str); - } - ; - -wire_rel_dname: wire_label - | wire_rel_dname '.' wire_label - { - if ($1.len + $3.len - 3 > MAXDOMAINLEN) - zc_error("domain name exceeds %d character limit", - MAXDOMAINLEN); - - /* make dname anyway */ - $$.len = $1.len + $3.len; - $$.str = malloc($$.len + sizeof(char)); - if ($$.str == NULL) { - ERR_ALLOC_FAILED; - knot_rrset_deep_free(&(parser->current_rrset), - 0, 0, 0); - knot_zone_deep_free(&(parser->current_zone), - 1); - YYABORT; - } - memcpy($$.str, $1.str, $1.len); - memcpy($$.str + $1.len, $3.str, $3.len); - $$.str[$$.len] = '\0'; - - free($1.str); - free($3.str); - } - ; - - - -str_seq: STR - { - zadd_rdata_txt_wireformat(zparser_conv_text($1.str, $1.len), 1); - - if(strcmp($1.str, ".") && strcmp($1.str, "@") - && strcmp($1.str, "\\#")) { // Lexer freed that - free($1.str); - } - } - | str_seq sp STR - { - zadd_rdata_txt_wireformat(zparser_conv_text($3.str, $3.len), 0); - - if(strcmp($3.str, ".") && strcmp($3.str, "@") - && strcmp($3.str, "\\#")) { // Lexer freed that - free($3.str); - } - } - ; - -/* - * Generate a single string from multiple STR tokens, separated by - * spaces or dots. - */ -concatenated_str_seq: STR - | '.' - { - $$.len = 1; - $$.str = strdup("."); - } - | concatenated_str_seq sp STR - { - $$.len = $1.len + $3.len + 1; - $$.str = malloc($$.len + 1); - if ($$.str == NULL) { - ERR_ALLOC_FAILED; - knot_rrset_deep_free(&(parser->current_rrset), - 0, 0, 0); - knot_zone_deep_free(&(parser->current_zone), - 1); - YYABORT; - } - - memcpy($$.str, $1.str, $1.len); - memcpy($$.str + $1.len, " ", 1); - memcpy($$.str + $1.len + 1, $3.str, $3.len); - $$.str[$$.len] = '\0'; - - free($1.str); - free($3.str); - } - | concatenated_str_seq '.' STR - { - $$.len = $1.len + $3.len + 1; - $$.str = malloc($$.len + 1); - if ($$.str == NULL) { - ERR_ALLOC_FAILED; - knot_rrset_deep_free(&(parser->current_rrset), - 0, 0, 0); - knot_zone_deep_free(&(parser->current_zone), - 1); - YYABORT; - } - memcpy($$.str, $1.str, $1.len); - memcpy($$.str + $1.len, ".", 1); - memcpy($$.str + $1.len + 1, $3.str, $3.len); - - free($1.str); - free($3.str); - - $$.str[$$.len] = '\0'; - } - ; - -/* used to convert a nxt list of types */ -nxt_seq: STR - { - uint16_t type = knot_rrtype_from_string($1.str); - if (type != 0 && type < 128) { - set_bit(nxtbits, type); - } else { - zc_error("bad type %d in NXT record", (int) type); - } - - free($1.str); - } - | nxt_seq sp STR - { - uint16_t type = knot_rrtype_from_string($3.str); - if (type != 0 && type < 128) { - set_bit(nxtbits, type); - } else { - zc_error("bad type %d in NXT record", (int) type); - } - - free($3.str); - } - ; - -nsec_more: SP nsec_more - { - } - | NL - { - } - | STR nsec_seq - { - uint16_t type = knot_rrtype_from_string($1.str); - if (type != 0) { - if (type > nsec_highest_rcode) { - nsec_highest_rcode = type; - } - set_bitnsec(nsecbits, type); - } else { - zc_error("bad type %d in NSEC record", (int) type); - } - - free($1.str); - } - ; - -nsec_seq: NL - | SP nsec_more - ; - -/* - * Sequence of STR tokens separated by spaces. The spaces are not - * preserved during concatenation. - */ -str_sp_seq: STR - | str_sp_seq sp STR - { - char *result = malloc($1.len + $3.len + 1); - if (result == NULL) { - ERR_ALLOC_FAILED; - log_zone_error("Parser ran out of memory, aborting!\n"); - knot_rrset_deep_free(&(parser->current_rrset), - 0, 0, 0); - knot_zone_deep_free(&(parser->current_zone), - 1); - YYABORT; - } - memcpy(result, $1.str, $1.len); - memcpy(result + $1.len, $3.str, $3.len); - $$.str = result; - $$.len = $1.len + $3.len; - $$.str[$$.len] = '\0'; - - free($1.str); - free($3.str); - } - ; - -/* - * Sequence of STR tokens separated by dots. The dots are not - * preserved during concatenation. - */ -str_dot_seq: STR - | str_dot_seq '.' STR - { - char *result = malloc($1.len + $3.len + 1); - if (result == NULL) { - ERR_ALLOC_FAILED; - log_zone_error("Parser ran out of memory, aborting!\n"); - knot_rrset_deep_free(&(parser->current_rrset), - 0, 0, 0); - knot_zone_deep_free(&(parser->current_zone), - 1); - YYABORT; - } - memcpy(result, $1.str, $1.len); - memcpy(result + $1.len, $3.str, $3.len); - $$.str = result; - $$.len = $1.len + $3.len; - $$.str[$$.len] = '\0'; - - free($1.str); - free($3.str); - } - ; - -/* - * A string that can contain dots. - */ -dotted_str: STR - | '.' - { - $$.str = "."; - $$.len = 1; - } - | dotted_str '.' - { - char *result = malloc($1.len + 2); - if (result == NULL) { - ERR_ALLOC_FAILED; - log_zone_error("Parser ran out of memory, aborting!\n"); - knot_rrset_deep_free(&(parser->current_rrset), - 0, 0, 0); - knot_zone_deep_free(&(parser->current_zone), - 1); - YYABORT; - } - memcpy(result, $1.str, $1.len); - result[$1.len] = '.'; - $$.str = result; - $$.len = $1.len + 1; - $$.str[$$.len] = '\0'; - - free($1.str); - } - | dotted_str '.' STR - { - char *result = malloc($1.len + $3.len + 2); - if (result == NULL) { - ERR_ALLOC_FAILED; - log_zone_error("Parser ran out of memory, aborting!\n"); - knot_rrset_deep_free(&(parser->current_rrset), - 0, 0, 0); - knot_zone_deep_free(&(parser->current_zone), - 1); - YYABORT; - } - memcpy(result, $1.str, $1.len); - result[$1.len] = '.'; - memcpy(result + $1.len + 1, $3.str, $3.len); - $$.str = result; - $$.len = $1.len + $3.len + 1; - $$.str[$$.len] = '\0'; - - - free($1.str); - free($3.str); - } - ; - -/* define what we can parse */ -type_and_rdata: - /* - * All supported RR types. We don't support NULL and types marked obsolete. - */ - T_A sp rdata_a - | T_A sp rdata_unknown { $$ = $1; parse_unknown_rdata($1, $3); } - | T_NS sp rdata_domain_name - | T_NS sp rdata_unknown { $$ = $1; parse_unknown_rdata($1, $3); } - | T_MD sp rdata_domain_name { zc_warning_prev_line("MD is obsolete"); } - | T_MD sp rdata_unknown - { - zc_warning_prev_line("MD is obsolete"); - $$ = $1; parse_unknown_rdata($1, $3); - } - | T_MF sp rdata_domain_name { zc_warning_prev_line("MF is obsolete"); } - | T_MF sp rdata_unknown - { - zc_warning_prev_line("MF is obsolete"); - $$ = $1; - parse_unknown_rdata($1, $3); - } - | T_CNAME sp rdata_domain_name - | T_CNAME sp rdata_unknown { $$ = $1; parse_unknown_rdata($1, $3); } - | T_SOA sp rdata_soa - | T_SOA sp rdata_unknown { $$ = $1; parse_unknown_rdata($1, $3); } - | T_MB sp rdata_domain_name { zc_warning_prev_line("MB is obsolete"); } - | T_MB sp rdata_unknown - { - zc_warning_prev_line("MB is obsolete"); - $$ = $1; - parse_unknown_rdata($1, $3); - } - | T_MG sp rdata_domain_name - | T_MG sp rdata_unknown { $$ = $1; parse_unknown_rdata($1, $3); } - | T_MR sp rdata_domain_name - | T_MR sp rdata_unknown { $$ = $1; parse_unknown_rdata($1, $3); } - /* NULL */ - | T_WKS sp rdata_wks - | T_WKS sp rdata_unknown { $$ = $1; parse_unknown_rdata($1, $3); } - | T_PTR sp rdata_domain_name - | T_PTR sp rdata_unknown { $$ = $1; parse_unknown_rdata($1, $3); } - | T_HINFO sp rdata_hinfo - | T_HINFO sp rdata_unknown { $$ = $1; parse_unknown_rdata($1, $3); } - | T_MINFO sp rdata_minfo /* Experimental */ - | T_MINFO sp rdata_unknown { $$ = $1; parse_unknown_rdata($1, $3); } - | T_MX sp rdata_mx - | T_MX sp rdata_unknown { $$ = $1; parse_unknown_rdata($1, $3); } - | T_TXT sp rdata_txt - | T_TXT sp rdata_unknown { $$ = $1; parse_unknown_rdata($1, $3); } - | T_SPF sp rdata_txt - | T_SPF sp rdata_unknown { $$ = $1; parse_unknown_rdata($1, $3); } - | T_RP sp rdata_rp /* RFC 1183 */ - | T_RP sp rdata_unknown { $$ = $1; parse_unknown_rdata($1, $3); } - | T_AFSDB sp rdata_afsdb /* RFC 1183 */ - | T_AFSDB sp rdata_unknown { $$ = $1; parse_unknown_rdata($1, $3); } - | T_X25 sp rdata_x25 /* RFC 1183 */ - | T_X25 sp rdata_unknown { $$ = $1; parse_unknown_rdata($1, $3); } - | T_ISDN sp rdata_isdn /* RFC 1183 */ - | T_ISDN sp rdata_unknown { $$ = $1; parse_unknown_rdata($1, $3); } - | T_IPSECKEY sp rdata_ipseckey /* RFC 4025 */ - | T_IPSECKEY sp rdata_unknown { $$ = $1; parse_unknown_rdata($1, $3); } - | T_DHCID sp rdata_dhcid - | T_DHCID sp rdata_unknown { $$ = $1; parse_unknown_rdata($1, $3); } - | T_RT sp rdata_rt /* RFC 1183 */ - | T_RT sp rdata_unknown { $$ = $1; parse_unknown_rdata($1, $3); } - | T_NSAP sp rdata_nsap /* RFC 1706 */ - | T_NSAP sp rdata_unknown { $$ = $1; parse_unknown_rdata($1, $3); } - | T_SIG sp rdata_rrsig - | T_SIG sp rdata_unknown { $$ = $1; parse_unknown_rdata($1, $3); } - | T_KEY sp rdata_dnskey - | T_KEY sp rdata_unknown { $$ = $1; parse_unknown_rdata($1, $3); } - | T_PX sp rdata_px /* RFC 2163 */ - | T_PX sp rdata_unknown { $$ = $1; parse_unknown_rdata($1, $3); } - | T_AAAA sp rdata_aaaa - | T_AAAA sp rdata_unknown { $$ = $1; parse_unknown_rdata($1, $3); } - | T_LOC sp rdata_loc - | T_LOC sp rdata_unknown { $$ = $1; parse_unknown_rdata($1, $3); } - | T_NXT sp rdata_nxt - | T_NXT sp rdata_unknown { $$ = $1; parse_unknown_rdata($1, $3); } - | T_SRV sp rdata_srv - | T_SRV sp rdata_unknown { $$ = $1; parse_unknown_rdata($1, $3); } - | T_NAPTR sp rdata_naptr /* RFC 2915 */ - | T_NAPTR sp rdata_unknown { $$ = $1; parse_unknown_rdata($1, $3); } - | T_KX sp rdata_kx /* RFC 2230 */ - | T_KX sp rdata_unknown { $$ = $1; parse_unknown_rdata($1, $3); } - | T_CERT sp rdata_cert /* RFC 2538 */ - | T_CERT sp rdata_unknown { $$ = $1; parse_unknown_rdata($1, $3); } - | T_DNAME sp rdata_domain_name /* RFC 2672 */ - | T_DNAME sp rdata_unknown { $$ = $1; parse_unknown_rdata($1, $3); } - | T_APL trail /* RFC 3123 */ - | T_APL sp rdata_apl /* RFC 3123 */ - | T_APL sp rdata_unknown { $$ = $1; parse_unknown_rdata($1, $3); } - | T_DS sp rdata_ds - | T_DS sp rdata_unknown { $$ = $1; parse_unknown_rdata($1, $3); } - | T_DLV sp rdata_dlv - { - if (dlv_warn) { - dlv_warn = 0; - zc_warning_prev_line("DLV is experimental"); - } - } - | T_DLV sp rdata_unknown - { - if (dlv_warn) { - dlv_warn = 0; - zc_warning_prev_line("DLV is experimental"); - } - $$ = $1; - parse_unknown_rdata($1, $3); - } - | T_SSHFP sp rdata_sshfp - | T_SSHFP sp rdata_unknown { $$ = $1; parse_unknown_rdata($1, $3); } - | T_RRSIG sp rdata_rrsig - | T_RRSIG sp rdata_unknown { $$ = $1; parse_unknown_rdata($1, $3); } - | T_NSEC sp rdata_nsec - | T_NSEC sp rdata_unknown { $$ = $1; parse_unknown_rdata($1, $3); } - | T_NSEC3 sp rdata_nsec3 - | T_NSEC3 sp rdata_unknown { $$ = $1; parse_unknown_rdata($1, $3); } - | T_NSEC3PARAM sp rdata_nsec3_param - | T_NSEC3PARAM sp rdata_unknown { $$ = $1; parse_unknown_rdata($1, $3); } - | T_TLSA sp rdata_tlsa - | T_TLSA sp rdata_unknown { $$ = $1; parse_unknown_rdata($1, $3); } - | T_DNSKEY sp rdata_dnskey - | T_DNSKEY sp rdata_unknown { $$ = $1; parse_unknown_rdata($1, $3); } - | T_UTYPE sp rdata_unknown { $$ = $1; parse_unknown_rdata($1, $3); } - - | STR error NL - { - zc_error_prev_line("unrecognized RR type '%s'", $1.str); - free($1.str); - } - | NO_MEM - { - zc_error_prev_line("parser ran out of memory!"); - YYABORT; - } - ; - -/* - * - * below are all the definition for all the different rdata - * - */ - -rdata_a: dotted_str trail - { - zadd_rdata_wireformat(zparser_conv_a($1.str)); - free($1.str); - } - ; - -rdata_domain_name: dname trail - { - /* convert a single dname record */ - if ($1 != NULL) { - if (!knot_dname_is_fqdn($1)) { - knot_dname_cat($1, parser->root_domain); -// parser->current_rrset->owner = -// knot_dname_cat($1, parser->root_domain); - } - } - zadd_rdata_domain($1); - } - ; - -rdata_soa: dname sp dname sp STR sp STR sp STR sp STR sp STR trail - { - /* convert the soa data */ - if (!knot_dname_is_fqdn($1)) { - knot_dname_cat($1, parser->root_domain); -// parser->current_rrset->owner = -// knot_dname_cat($1, parser->root_domain); - - } - if (!knot_dname_is_fqdn($3)) { - knot_dname_cat($3, parser->root_domain); -// parser->current_rrset->owner = -// knot_dname_cat($3, parser->root_domain); - - } - zadd_rdata_domain($1); /* prim. ns */ - zadd_rdata_domain($3); /* email */ - zadd_rdata_wireformat(zparser_conv_serial($5.str)); /* serial */ - zadd_rdata_wireformat(zparser_conv_period($7.str)); /* refresh */ - zadd_rdata_wireformat(zparser_conv_period($9.str)); /* retry */ - zadd_rdata_wireformat(zparser_conv_period($11.str)); /* expire */ - zadd_rdata_wireformat(zparser_conv_period($13.str)); /* minimum */ - - free($5.str); - free($7.str); - free($9.str); - free($11.str); - free($13.str); - } - ; - -rdata_wks: dotted_str sp STR sp concatenated_str_seq trail - { - zadd_rdata_wireformat(zparser_conv_a($1.str)); /* address */ - zadd_rdata_wireformat(zparser_conv_services($3.str, $5.str)); - /* protocol and services */ - - free($1.str); - free($3.str); - free($5.str); - } - ; - -rdata_hinfo: STR sp STR trail - { - zadd_rdata_wireformat(zparser_conv_text($1.str, $1.len)); /* CPU */ - zadd_rdata_wireformat(zparser_conv_text($3.str, $3.len)); /* OS*/ - - free($1.str); - free($3.str); - } - ; - -rdata_minfo: dname sp dname trail - { - if (!knot_dname_is_fqdn($1)) { - - knot_dname_cat($1, parser->root_domain); - - } - if (!knot_dname_is_fqdn($3)) { - - knot_dname_cat($3, parser->root_domain); - - } - - /* convert a single dname record */ - zadd_rdata_domain($1); - zadd_rdata_domain($3); - } - ; - -rdata_mx: STR sp dname trail - { - if (!knot_dname_is_fqdn($3)) { - knot_dname_cat($3, parser->root_domain); - } - - zadd_rdata_wireformat(zparser_conv_short($1.str)); /* priority */ - zadd_rdata_domain($3); /* MX host */ - - free($1.str); - } - ; - -rdata_txt: str_seq trail - { - ; //zadd_rdata_txt_clean_wireformat(); - } - ; - -/* RFC 1183 */ -rdata_rp: dname sp dname trail - { - if (!knot_dname_is_fqdn($1)) { - knot_dname_cat($1, parser->root_domain); - } - if (!knot_dname_is_fqdn($3)) { - knot_dname_cat($3, parser->root_domain); - } - - zadd_rdata_domain($1); /* mbox d-name */ - zadd_rdata_domain($3); /* txt d-name */ - } - ; - -/* RFC 1183 */ -rdata_afsdb: STR sp dname trail - { - if (!knot_dname_is_fqdn($3)) { - knot_dname_cat($3, parser->root_domain); - } - - zadd_rdata_wireformat(zparser_conv_short($1.str)); /* subtype */ - zadd_rdata_domain($3); /* domain name */ - - free($1.str); - } - ; - -/* RFC 1183 */ -rdata_x25: STR trail - { - zadd_rdata_wireformat(zparser_conv_text($1.str, $1.len)); - /* X.25 address. */ - - free($1.str); - } - ; - -/* RFC 1183 */ -rdata_isdn: STR trail - { - zadd_rdata_wireformat(zparser_conv_text($1.str, $1.len)); - /* address */ - - free($1.str); - } - | STR sp STR trail - { - zadd_rdata_wireformat(zparser_conv_text($1.str, $1.len)); - /* address */ - zadd_rdata_wireformat(zparser_conv_text($3.str, $3.len)); - /* sub-address */ - - free($1.str); - free($3.str); - } - ; - -/* RFC 1183 */ -rdata_rt: STR sp dname trail - { - if (!knot_dname_is_fqdn($3)) { - knot_dname_cat($3, parser->root_domain); - } - - zadd_rdata_wireformat(zparser_conv_short($1.str)); /* preference */ - zadd_rdata_domain($3); /* intermediate host */ - - free($1.str); - } - ; - -/* RFC 1706 */ -rdata_nsap: str_dot_seq trail - { - /* String must start with "0x" or "0X". */ - if (strncasecmp($1.str, "0x", 2) != 0) { - zc_error_prev_line("NSAP rdata must start with '0x'"); - } else { - zadd_rdata_wireformat(zparser_conv_hex($1.str + 2, - $1.len - 2)); - /* NSAP */ - } - - free($1.str); - } - ; - -/* RFC 2163 */ -rdata_px: STR sp dname sp dname trail - { - if (!knot_dname_is_fqdn($3)) { - knot_dname_cat($3, parser->root_domain); - } - if (!knot_dname_is_fqdn($5)) { - knot_dname_cat($5, parser->root_domain); - } - zadd_rdata_wireformat(zparser_conv_short($1.str)); /* preference */ - zadd_rdata_domain($3); /* MAP822 */ - zadd_rdata_domain($5); /* MAPX400 */ - - free($1.str); - } - ; - -rdata_aaaa: dotted_str trail - { - zadd_rdata_wireformat(zparser_conv_aaaa($1.str)); - /* IPv6 address */ - - free($1.str); - } - ; - -rdata_loc: concatenated_str_seq trail - { - zadd_rdata_wireformat(zparser_conv_loc($1.str)); /* Location */ - - free($1.str); - } - ; - -rdata_nxt: dname sp nxt_seq trail - { - if (!knot_dname_is_fqdn($1)) { - knot_dname_cat($1, parser->root_domain); - } - zadd_rdata_domain($1); /* nxt name */ - zadd_rdata_wireformat(zparser_conv_nxt(nxtbits)); /* nxt bitlist */ - memset(nxtbits, 0, sizeof(nxtbits)); - } - ; - -rdata_srv: STR sp STR sp STR sp dname trail - { - if (!knot_dname_is_fqdn($7)) { - knot_dname_cat($7, parser->root_domain); - - } - zadd_rdata_wireformat(zparser_conv_short($1.str)); /* prio */ - zadd_rdata_wireformat(zparser_conv_short($3.str)); /* weight */ - zadd_rdata_wireformat(zparser_conv_short($5.str)); /* port */ - zadd_rdata_domain($7); /* target name */ - - free($1.str); - free($3.str); - free($5.str); - } - ; - -/* RFC 2915 */ -rdata_naptr: STR sp STR sp STR sp STR sp STR sp dname trail - { - if (!knot_dname_is_fqdn($11)) { - knot_dname_cat($11, parser->root_domain); - - } - zadd_rdata_wireformat(zparser_conv_short($1.str)); /* order */ - zadd_rdata_wireformat(zparser_conv_short($3.str)); /* preference */ - zadd_rdata_wireformat(zparser_conv_text($5.str, $5.len)); - /* flags */ - zadd_rdata_wireformat(zparser_conv_text($7.str, $7.len)); - /* service */ - zadd_rdata_wireformat(zparser_conv_text($9.str, $9.len)); - /* regexp */ - zadd_rdata_domain($11); /* target name */ - - free($1.str); - free($3.str); - free($5.str); - free($7.str); - free($9.str); - } - ; - -/* RFC 2230 */ -rdata_kx: STR sp dname trail - { - if (!knot_dname_is_fqdn($3)) { - knot_dname_cat($3, parser->root_domain); - } - zadd_rdata_wireformat(zparser_conv_short($1.str)); /* preference */ - zadd_rdata_domain($3); /* exchanger */ - - free($1.str); - } - ; - -/* RFC 2538 */ -rdata_cert: STR sp STR sp STR sp str_sp_seq trail - { - zadd_rdata_wireformat(zparser_conv_certificate_type($1.str)); - /* type */ - zadd_rdata_wireformat(zparser_conv_short($3.str)); /* key tag */ - zadd_rdata_wireformat(zparser_conv_algorithm($5.str)); - /* algorithm */ - zadd_rdata_wireformat(zparser_conv_b64($7.str)); - /* certificate or CRL */ - - free($1.str); - free($3.str); - free($5.str); - free($7.str); - } - ; - -/* RFC 3123 */ -rdata_apl: rdata_apl_seq trail - ; - -rdata_apl_seq: dotted_str - { - zadd_rdata_txt_wireformat(zparser_conv_apl_rdata($1.str), 1); - - free($1.str); - } - | rdata_apl_seq sp dotted_str - { - zadd_rdata_txt_wireformat(zparser_conv_apl_rdata($3.str), 0); - - free($3.str); - } - ; - -rdata_ds: STR sp STR sp STR sp str_sp_seq trail - { - zadd_rdata_wireformat(zparser_conv_short($1.str)); /* keytag */ - zadd_rdata_wireformat(zparser_conv_algorithm($3.str)); /* alg */ - zadd_rdata_wireformat(zparser_conv_byte($5.str)); /* type */ - zadd_rdata_wireformat(zparser_conv_hex($7.str, $7.len)); /* hash */ - - free($1.str); - free($3.str); - free($5.str); - free($7.str); - } - ; - -rdata_dlv: STR sp STR sp STR sp str_sp_seq trail - { - zadd_rdata_wireformat(zparser_conv_short($1.str)); /* keytag */ - zadd_rdata_wireformat(zparser_conv_algorithm($3.str)); /* alg */ - zadd_rdata_wireformat(zparser_conv_byte($5.str)); /* type */ - zadd_rdata_wireformat(zparser_conv_hex($7.str, $7.len)); /* hash */ - - free($1.str); - free($3.str); - free($5.str); - free($7.str); - } - ; - -rdata_sshfp: STR sp STR sp str_sp_seq trail - { - zadd_rdata_wireformat(zparser_conv_byte($1.str)); /* alg */ - zadd_rdata_wireformat(zparser_conv_byte($3.str)); /* fp type */ - zadd_rdata_wireformat(zparser_conv_hex($5.str, $5.len)); /* hash */ - - free($1.str); - free($3.str); - free($5.str); - } - ; - -rdata_dhcid: str_sp_seq trail - { - zadd_rdata_wireformat(zparser_conv_b64($1.str)); /* data blob */ - - free($1.str); - } - ; - -rdata_rrsig: STR sp STR sp STR sp STR sp STR sp STR - sp STR sp wire_dname sp str_sp_seq trail - { - zadd_rdata_wireformat(zparser_conv_rrtype($1.str)); - /* rr covered */ - zadd_rdata_wireformat(zparser_conv_algorithm($3.str)); /* alg */ - zadd_rdata_wireformat(zparser_conv_byte($5.str)); /* # labels */ - zadd_rdata_wireformat(zparser_conv_period($7.str)); - /* # orig TTL */ - zadd_rdata_wireformat(zparser_conv_time($9.str)); /* sig exp */ - zadd_rdata_wireformat(zparser_conv_time($11.str)); /* sig inc */ - zadd_rdata_wireformat(zparser_conv_short($13.str)); /* key id */ -/* zadd_rdata_wireformat(zparser_conv_dns_name((const uint8_t*) - $15.str, - $15.len));*/ - knot_dname_t *dname = - knot_dname_new_from_wire((uint8_t *)$15.str, $15.len, NULL); - knot_dname_retain(dname); - if (dname == NULL) { - parser->error_occurred = KNOTDZCOMPILE_ENOMEM; - } else { - knot_dname_cat(dname, parser->root_domain); - } - - zadd_rdata_domain(dname); - /* sig name */ - zadd_rdata_wireformat(zparser_conv_b64($17.str)); /* sig data */ - - free($1.str); - free($3.str); - free($5.str); - free($7.str); - free($9.str); - free($11.str); - free($13.str); - free($15.str); - free($17.str); - } - ; - -rdata_nsec: wire_dname nsec_seq - { -/* zadd_rdata_wireformat(zparser_conv_dns_name((const uint8_t*) - $1.str, - $1.len));*/ - - knot_dname_t *dname = - knot_dname_new_from_wire((uint8_t *)$1.str, $1.len, NULL); - knot_dname_retain(dname); - free($1.str); - - knot_dname_cat(dname, parser->root_domain); - - zadd_rdata_domain(dname); - /* nsec name */ - zadd_rdata_wireformat(zparser_conv_nsec(nsecbits)); - /* nsec bitlist */ - memset(nsecbits, 0, sizeof(nsecbits)); - nsec_highest_rcode = 0; - } - ; - -rdata_nsec3: STR sp STR sp STR sp STR sp STR nsec_seq - { -#ifdef NSEC3 - nsec3_add_params($1.str, $3.str, $5.str, $7.str, $7.len); - -/* knot_dname_t *dname = - knot_dname_new_from_str($9.str, $9.len, NULL); - - zadd_rdata_domain(dname); */ - - zadd_rdata_wireformat(zparser_conv_b32($9.str)); - /* next hashed name */ - zadd_rdata_wireformat(zparser_conv_nsec(nsecbits)); - /* nsec bitlist */ - memset(nsecbits, 0, sizeof(nsecbits)); - nsec_highest_rcode = 0; -#else - zc_error_prev_line("nsec3 not supported"); -#endif /* NSEC3 */ - - free($1.str); - free($3.str); - free($5.str); - free($7.str); - free($9.str); - } - ; - -rdata_nsec3_param: STR sp STR sp STR sp STR trail - { -#ifdef NSEC3 - nsec3_add_params($1.str, $3.str, $5.str, $7.str, $7.len); -#else - zc_error_prev_line("nsec3 not supported"); -#endif /* NSEC3 */ - - free($1.str); - free($3.str); - free($5.str); - free($7.str); - } - ; - -rdata_tlsa: STR sp STR sp STR sp str_sp_seq trail - { - zadd_rdata_wireformat(zparser_conv_byte($1.str)); - zadd_rdata_wireformat(zparser_conv_byte($3.str)); - zadd_rdata_wireformat(zparser_conv_byte($5.str)); - zadd_rdata_wireformat(zparser_conv_hex($7.str, $7.len)); - - free($1.str); - free($3.str); - free($5.str); - free($7.str); - } - ; - -rdata_dnskey: STR sp STR sp STR sp str_sp_seq trail - { - zadd_rdata_wireformat(zparser_conv_short($1.str)); /* flags */ - zadd_rdata_wireformat(zparser_conv_byte($3.str)); /* proto */ - zadd_rdata_wireformat(zparser_conv_algorithm($5.str)); /* alg */ - zadd_rdata_wireformat(zparser_conv_b64($7.str)); /* hash */ - - free($1.str); - free($3.str); - free($5.str); - free($7.str); - } - ; - -rdata_ipsec_base: STR sp STR sp STR sp dotted_str - { - knot_dname_t* name = 0; - zadd_rdata_wireformat(zparser_conv_byte($1.str)); /* precedence */ - zadd_rdata_wireformat(zparser_conv_byte($3.str)); - /* gateway type */ - zadd_rdata_wireformat(zparser_conv_byte($5.str)); /* algorithm */ - switch(atoi($3.str)) { - case IPSECKEY_NOGATEWAY: - zadd_rdata_wireformat(alloc_rdata_init("", 0)); - break; - case IPSECKEY_IP4: - zadd_rdata_wireformat(zparser_conv_a($7.str)); - break; - case IPSECKEY_IP6: - zadd_rdata_wireformat(zparser_conv_aaaa($7.str)); - break; - case IPSECKEY_DNAME: - /* convert and insert the dname */ - if(strlen($7.str) == 0) - zc_error_prev_line("IPSECKEY must specify" - "gateway name"); - name = knot_dname_new_from_str($7.str, - strlen($7.str), - NULL); - if(!name) { - zc_error_prev_line("IPSECKEY bad gateway" - "dname %s", $7.str); - knot_rrset_deep_free(&(parser->current_rrset), - 0, 0, 0); - knot_zone_deep_free(&(parser->current_zone), - 1); - YYABORT; - } - - if(!knot_dname_is_fqdn(name)) { - assert(parser->origin); - name = knot_dname_cat(name, - parser->origin->owner); - if (name == NULL) { - zc_error_prev_line("Cannot concatenete dnames, probably run out of memory!\n"); - YYABORT; - } - } - - free($1.str); - free($3.str); - free($5.str); - free($7.str); - - uint16_t* dncpy = malloc(sizeof(uint8_t) * name->size + 2); - dncpy[0] = name->size; - if (dncpy == NULL) { - ERR_ALLOC_FAILED; - knot_rrset_deep_free(&(parser->current_rrset), - 0, 0, 0); - knot_zone_deep_free(&(parser->current_zone), - 1); - YYABORT; - } - - memcpy((uint8_t *)(dncpy + 1), name->name, name->size); - zadd_rdata_wireformat(dncpy); - knot_dname_free(&name); - break; - default: - zc_error_prev_line("unknown IPSECKEY gateway type"); - } - } - ; - -rdata_ipseckey: rdata_ipsec_base sp str_sp_seq trail - { - zadd_rdata_wireformat(zparser_conv_b64($3.str)); /* public key */ - - free($3.str); - } - | rdata_ipsec_base trail - ; - -rdata_unknown: URR sp STR sp str_sp_seq trail - { - /* $2 is the number of octects, currently ignored */ - $$ = zparser_conv_hex($5.str, $5.len); - free($5.str); - free($3.str); - } - | URR sp STR trail - { - $$ = zparser_conv_hex("", 0); - free($3.str); - } - | URR error NL - { - $$ = zparser_conv_hex("", 0); - } - ; -%% - -int zp_wrap(void) -{ - return 1; -} - -/* - * Create the parser. - */ -zparser_type *zparser_create() -{ - zparser_type *result = malloc(sizeof(zparser_type)); - if (result == NULL) { - ERR_ALLOC_FAILED; - return NULL; - } - - result->temporary_items = malloc(MAXRDATALEN * - sizeof(knot_rdata_item_t)); - if (result->temporary_items == NULL) { - ERR_ALLOC_FAILED; - free(result); - return NULL; - } - - result->current_rrset = knot_rrset_new(NULL, 0, 0, 0); - if (result->current_rrset == NULL) { - free(result->temporary_items); - free(result); - return NULL; - } - - result->root_domain = knot_dname_new_from_str(".", 1, NULL); - if (result->root_domain == NULL) { - free(result->temporary_items); - free(result->current_rrset); - free(result); - return NULL; - } - - return result; -} - -/* - * Initialize the parser for a new zone file. - */ -void -zparser_init(const char *filename, uint32_t ttl, uint16_t rclass, - knot_node_t *origin, knot_dname_t *origin_from_config) -{ - memset(nxtbits, 0, sizeof(nxtbits)); - memset(nsecbits, 0, sizeof(nsecbits)); - nsec_highest_rcode = 0; - - parser->current_zone = NULL; - parser->prev_dname = NULL; - - parser->default_ttl = ttl; - parser->default_class = rclass; - - parser->origin = origin; - parser->prev_dname = NULL;//parser->origin->owner; - - parser->default_apex = origin; - parser->error_occurred = 0; - parser->errors = 0; - parser->line = 1; - parser->filename = filename; - parser->rdata_count = 0; - parser->origin_from_config = origin_from_config; - knot_dname_retain(origin_from_config); - - parser->last_node = origin; -// parser->root_domain = NULL; - - /* Create zone */ - parser->current_zone = knot_zone_new(origin, 0, 1); - - parser->node_rrsigs = NULL; - - parser->current_rrset->rclass = parser->default_class; - parser->current_rrset->rdata = NULL; -} - - -void zparser_free() -{ - knot_dname_release(parser->root_domain); -// knot_dname_release(parser->prev_dname); - knot_zone_deep_free(&parser->current_zone, 1); - knot_dname_release(parser->origin_from_config); - free(parser->temporary_items); - if (parser->current_rrset != NULL) { - free(parser->current_rrset); - } - free(parser); -} - -void -yyerror(void *scanner, const char *message) -{ - zc_error("%s", message); -} - -static void -error_va_list(unsigned line, const char *fmt, va_list args) -{ - char sbuf[4096] = {0}; - size_t buflen = sizeof(sbuf) - 1; - char *buf = sbuf; - int wb = 0; - if (parser->filename) { - wb = snprintf(buf, buflen, "%s:%u: ", - parser->filename, line); - if (wb > 0) { - buf += wb; - buflen -= wb; - } - } - - wb = vsnprintf(buf, buflen, fmt, args); - if (wb > 0) { - buf += wb; - buflen -= wb; - *buf = '\n'; - *(buf + 1) = '\0'; - } - - log_zone_error("%s", sbuf); - - ++parser->errors; - parser->error_occurred = 1; -} - -/* the line counting sux, to say the least - * with this grose hack we try do give sane - * numbers back */ -void -zc_error_prev_line(const char *fmt, ...) -{ - va_list args; - va_start(args, fmt); - error_va_list(parser->line - 1, fmt, args); - va_end(args); -} - -void -zc_error(const char *fmt, ...) -{ - /* send an error message to stderr */ - va_list args; - va_start(args, fmt); - error_va_list(parser->line, fmt, args); - va_end(args); -} - -static void -warning_va_list(unsigned line, const char *fmt, va_list args) -{ - char sbuf[4096] = {0}; - size_t buflen = sizeof(sbuf) - 1; - char *buf = sbuf; - int wb = 0; - if (parser->filename) { - wb = snprintf(buf, buflen, "%s:%u: ", - parser->filename, line); - if (wb > 0) { - buf += wb; - buflen -= wb; - } - } - - wb = vsnprintf(buf, buflen, fmt, args); - if (wb > 0) { - buf += wb; - buflen -= wb; - *buf = '\n'; - *(buf + 1) = '\0'; - } - - log_zone_warning("%s", sbuf); -} - -void -zc_warning_prev_line(const char *fmt, ...) -{ - va_list args; - va_start(args, fmt); - warning_va_list(parser->line - 1, fmt, args); - va_end(args); -} - -void -zc_warning(const char *fmt, ... ) -{ - va_list args; - va_start(args, fmt); - warning_va_list(parser->line, fmt, args); - va_end(args); -} - -#ifdef NSEC3 -static void -nsec3_add_params(const char* hashalgo_str, const char* flag_str, - const char* iter_str, const char* salt_str, int salt_len) -{ - zadd_rdata_wireformat(zparser_conv_byte(hashalgo_str)); - zadd_rdata_wireformat(zparser_conv_byte(flag_str)); - zadd_rdata_wireformat(zparser_conv_short(iter_str)); - - /* salt */ - if(strcmp(salt_str, "-") != 0) - zadd_rdata_wireformat(zparser_conv_hex_length(salt_str, - salt_len)); - else - zadd_rdata_wireformat(alloc_rdata_init("", 1)); - -} -#endif /* NSEC3 */