diff --git a/.cirrus.yml b/.cirrus.yml index cfd6c0fd0..67be79837 100644 --- a/.cirrus.yml +++ b/.cirrus.yml @@ -18,7 +18,7 @@ ubuntu_2204_gcc11: &ubuntu_2204_gcc11 bootstrap_script: - apt-get update install_script: - - apt-get install -y autoconf automake libtool make gcc-11 clang libc-dev libevent-dev libssl-dev flex bison + - apt-get install -y autoconf automake libtool make gcc-11 clang libc-dev libevent-dev libssl-dev flex bison git ubuntu_2204_clang14: &ubuntu_2204_clang14 container: @@ -30,7 +30,7 @@ ubuntu_2204_clang14: &ubuntu_2204_clang14 bootstrap_script: - apt-get update install_script: - - apt-get install -y autoconf automake libtool make clang-${CLANG_VERSION} libc-dev libevent-dev libssl-dev flex bison + - apt-get install -y autoconf automake libtool make clang-${CLANG_VERSION} libc-dev libevent-dev libssl-dev flex bison git - update-alternatives --install /usr/bin/clang clang /usr/bin/clang-${CLANG_VERSION} 10 freebsd_14_0: &freebsd_14_0 @@ -39,7 +39,7 @@ freebsd_14_0: &freebsd_14_0 env: CC: clang install_script: - - pkg install --yes --quiet bash gmake autoconf automake libtool libevent + - pkg install --yes --quiet bash gmake autoconf automake libtool libevent git macos_13_1_xcode14_2: &macos_13_1_xcode14_2 macos_instance: @@ -49,7 +49,7 @@ macos_13_1_xcode14_2: &macos_13_1_xcode14_2 COV_COMPTYPE: clang COV_COMPTYPE: macOSX install_script: - - brew install bash autoconf automake libtool openssl libevent flex bison + - brew install bash autoconf automake libtool openssl libevent flex bison git install_coverity: &install_coverity env: @@ -114,7 +114,9 @@ task: LIBEVENT: "/opt/homebrew/opt/libevent" build_script: + - git submodule update --init - autoconf && autoheader + - (cd simdzone && autoconf) - libtoolize -c -i || glibtoolize -c -i - ./configure --enable-checking --disable-flto --with-ssl=${OPENSSL:-yes} --with-libevent=${LIBEVENT:-yes} - make -j 2 diff --git a/.gitmodules b/.gitmodules new file mode 100644 index 000000000..23bd18f65 --- /dev/null +++ b/.gitmodules @@ -0,0 +1,3 @@ +[submodule "simdzone"] + path = simdzone + url = https://github.com/NLnetLabs/simdzone.git diff --git a/Makefile.in b/Makefile.in index a9cc03867..8743fe75d 100644 --- a/Makefile.in +++ b/Makefile.in @@ -30,12 +30,15 @@ user = @user@ DNSTAP_SRC=@DNSTAP_SRC@ DNSTAP_OBJ=@DNSTAP_OBJ@ +# GNU Make provides MAKECMDGOALS, BSD Make provides .TARGETS +MAKECMDGOALS ?= $(.TARGETS) + # override $U variable which is used by autotools for deansification (for # K&R C compilers), but causes problems if $U is defined in the env). U= CC = @CC@ -CPPFLAGS = @CPPFLAGS@ +CPPFLAGS = @CPPFLAGS@ -I@srcdir@/simdzone/include CFLAGS = @CFLAGS@ LDFLAGS = @LDFLAGS@ LIBS = @LIBS@ @@ -78,13 +81,13 @@ MANUALS=nsd.8 nsd-checkconf.8 nsd-checkzone.8 nsd-control.8 nsd.conf.5 COMMON_OBJ=answer.o axfr.o ixfr.o ixfrcreate.o buffer.o configlexer.o configparser.o dname.o dns.o edns.o iterated_hash.o lookup3.o namedb.o nsec3.o options.o packet.o query.o rbtree.o radtree.o rdata.o region-allocator.o rrl.o siphash.o tsig.o tsig-openssl.o udb.o util.o bitset.o popen3.o proxy_protocol.o XFRD_OBJ=xfrd-catalog-zones.o xfrd-disk.o xfrd-notify.o xfrd-tcp.o xfrd.o remote.o $(DNSTAP_OBJ) -NSD_OBJ=$(COMMON_OBJ) $(XFRD_OBJ) difffile.o ipc.o mini_event.o netio.o nsd.o server.o dbaccess.o dbcreate.o zlexer.o zonec.o zparser.o verify.o +NSD_OBJ=$(COMMON_OBJ) $(XFRD_OBJ) difffile.o ipc.o mini_event.o netio.o nsd.o server.o dbaccess.o dbcreate.o zonec.o verify.o ALL_OBJ=$(NSD_OBJ) nsd-checkconf.o nsd-checkzone.o nsd-control.o nsd-mem.o xfr-inspect.o NSD_CHECKCONF_OBJ=$(COMMON_OBJ) nsd-checkconf.o -NSD_CHECKZONE_OBJ=$(COMMON_OBJ) $(XFRD_OBJ) dbaccess.o dbcreate.o difffile.o ipc.o mini_event.o netio.o server.o zonec.o zparser.o zlexer.o nsd-checkzone.o verify.o +NSD_CHECKZONE_OBJ=$(COMMON_OBJ) $(XFRD_OBJ) dbaccess.o dbcreate.o difffile.o ipc.o mini_event.o netio.o server.o zonec.o nsd-checkzone.o verify.o NSD_CONTROL_OBJ=$(COMMON_OBJ) nsd-control.o -CUTEST_OBJ=$(COMMON_OBJ) $(XFRD_OBJ) dbaccess.o dbcreate.o difffile.o ipc.o mini_event.o netio.o server.o verify.o zonec.o zparser.o zlexer.o cutest_dname.o cutest_dns.o cutest_iterated_hash.o cutest_run.o cutest_radtree.o cutest_rbtree.o cutest_namedb.o cutest_options.o cutest_region.o cutest_rrl.o cutest_udb.o cutest_util.o cutest_bitset.o cutest_popen3.o cutest_iter.o cutest_event.o cutest.o qtest.o -NSD_MEM_OBJ=$(COMMON_OBJ) $(XFRD_OBJ) dbaccess.o dbcreate.o difffile.o ipc.o mini_event.o netio.o verify.o server.o zonec.o zparser.o zlexer.o nsd-mem.o +CUTEST_OBJ=$(COMMON_OBJ) $(XFRD_OBJ) dbaccess.o dbcreate.o difffile.o ipc.o mini_event.o netio.o server.o verify.o zonec.o cutest_dname.o cutest_dns.o cutest_iterated_hash.o cutest_run.o cutest_radtree.o cutest_rbtree.o cutest_namedb.o cutest_options.o cutest_region.o cutest_rrl.o cutest_udb.o cutest_util.o cutest_bitset.o cutest_popen3.o cutest_iter.o cutest_event.o cutest.o qtest.o +NSD_MEM_OBJ=$(COMMON_OBJ) $(XFRD_OBJ) dbaccess.o dbcreate.o difffile.o ipc.o mini_event.o netio.o verify.o server.o zonec.o nsd-mem.o all: $(TARGETS) $(MANUALS) $(ALL_OBJ): @@ -152,26 +155,29 @@ uninstall: test: -nsd: $(NSD_OBJ) $(LIBOBJS) - $(LINK) -o $@ $(NSD_OBJ) $(LIBOBJS) $(SSL_LIBS) $(LIBS) +simdzone/libzone.a: + $(MAKE) -C simdzone + +nsd: simdzone/libzone.a $(NSD_OBJ) $(LIBOBJS) + $(LINK) -o $@ $(NSD_OBJ) $(LIBOBJS) simdzone/libzone.a $(SSL_LIBS) $(LIBS) -nsd-checkconf: $(NSD_CHECKCONF_OBJ) $(LIBOBJS) - $(LINK) -o $@ $(NSD_CHECKCONF_OBJ) $(LIBOBJS) $(LIBS) +nsd-checkconf: simdzone/libzone.a $(NSD_CHECKCONF_OBJ) $(LIBOBJS) + $(LINK) -o $@ $(NSD_CHECKCONF_OBJ) simdzone/libzone.a $(LIBOBJS) $(LIBS) -nsd-checkzone: $(NSD_CHECKZONE_OBJ) $(LIBOBJS) - $(LINK) -o $@ $(NSD_CHECKZONE_OBJ) $(LIBOBJS) $(SSL_LIBS) $(LIBS) +nsd-checkzone: simdzone/libzone.a $(NSD_CHECKZONE_OBJ) $(LIBOBJS) + $(LINK) -o $@ $(NSD_CHECKZONE_OBJ) $(LIBOBJS) simdzone/libzone.a $(SSL_LIBS) $(LIBS) -nsd-control: $(NSD_CONTROL_OBJ) $(LIBOBJS) - $(LINK) -o $@ $(NSD_CONTROL_OBJ) $(LIBOBJS) $(SSL_LIBS) $(LIBS) +nsd-control: simdzone/libzone.a $(NSD_CONTROL_OBJ) $(LIBOBJS) + $(LINK) -o $@ $(NSD_CONTROL_OBJ) $(LIBOBJS) simdzone/libzone.a $(SSL_LIBS) $(LIBS) -nsd-mem: $(NSD_MEM_OBJ) $(LIBOBJS) - $(LINK) -o $@ $(NSD_MEM_OBJ) $(LIBOBJS) $(SSL_LIBS) $(LIBS) +nsd-mem: simdzone/libzone.a $(NSD_MEM_OBJ) $(LIBOBJS) + $(LINK) -o $@ $(NSD_MEM_OBJ) $(LIBOBJS) simdzone/libzone.a $(SSL_LIBS) $(LIBS) -cutest: $(CUTEST_OBJ) $(LIBOBJS) popen3_echo - $(LINK) -o $@ $(CUTEST_OBJ) $(LIBOBJS) $(SSL_LIBS) $(LIBS) +cutest: simdzone/libzone.a $(CUTEST_OBJ) $(LIBOBJS) popen3_echo + $(LINK) -o $@ $(CUTEST_OBJ) $(LIBOBJS) simdzone/libzone.a $(SSL_LIBS) $(LIBS) -xfr-inspect: xfr-inspect.o $(COMMON_OBJ) zonec.o zparser.o zlexer.o $(LIBOBJS) - $(LINK) -o $@ xfr-inspect.o $(COMMON_OBJ) zonec.o zparser.o zlexer.o $(LIBOBJS) $(LIBS) +xfr-inspect: simdzone/libzone.a xfr-inspect.o $(COMMON_OBJ) zonec.o $(LIBOBJS) + $(LINK) -o $@ xfr-inspect.o $(COMMON_OBJ) zonec.o $(LIBOBJS) simdzone/libzone.a $(LIBS) popen3_echo: popen3.o popen3_echo.o $(LINK) -o $@ popen3.o popen3_echo.o @@ -189,13 +195,13 @@ audit: nsd nsd-checkconf nsd-checkzone nsd-control nsd-mem checksec clean: rm -f *.o $(TARGETS) $(MANUALS) cutest popen3_echo xfr-inspect nsd-mem + make -C simdzone $(MAKECMDGOALS) distclean: clean rm -f Makefile config.h config.log config.status dnstap/dnstap_config.h realclean: distclean rm -rf autom4te* - rm -f zlexer.c zparser.h zparser.c zparser.stamp rm -f configlexer.c configparser.h configparser.c configparser.stamp maintainer-clean: realclean @@ -326,16 +332,6 @@ cutest.o: $(srcdir)/tpkg/cutest/cutest.c qtest.o: $(srcdir)/tpkg/cutest/qtest.c $(COMPILE) -c $(srcdir)/tpkg/cutest/qtest.c -zlexer.c: $(srcdir)/zlexer.lex - if test "$(LEX)" != ":"; then rm -f $@ ;\ - echo '#include "config.h"' > $@ ;\ - $(LEX) -i -t $(srcdir)/zlexer.lex >> $@ ;\ - fi - @if test ! -f $@; then echo "No $@ : need flex and bison to compile from source repository"; exit 1; fi - -zparser.c zparser.h: $(srcdir)/zparser.y - $(YACC) -d -o zparser.c $(srcdir)/zparser.y - configlexer.c: $(srcdir)/configlexer.lex if test "$(LEX)" != ":"; then rm -f $@ ;\ echo '#include "config.h"' > $@ ;\ @@ -350,10 +346,8 @@ configparser.c configparser.h: $(srcdir)/configparser.y configlexer.o: configlexer.c config.h configparser.h configparser.o: configparser.c config.h configparser.h options.o: $(srcdir)/options.c config.h configparser.h -zlexer.o: zlexer.c config.h zparser.h -zparser.o: zparser.c config.h zparser.h -dns.o: $(srcdir)/dns.c config.h zparser.h -zonec.o: $(srcdir)/zonec.c config.h zparser.h +dns.o: $(srcdir)/dns.c config.h +zonec.o: $(srcdir)/zonec.c config.h # dnstap dnstap.o: $(srcdir)/dnstap/dnstap.c config.h dnstap/dnstap_config.h \ @@ -396,9 +390,6 @@ depend: -e 's?$$(srcdir)/dnstap/dnstap_config.h??g' \ -e 's?$$(srcdir)/dnstap/dnstap.pb-c.c?dnstap/dnstap.pb-c.c?g' \ -e 's?$$(srcdir)/dnstap/dnstap.pb-c.h?dnstap/dnstap.pb-c.h?g' \ - -e 's?$$(srcdir)/zlexer.c?zlexer.c?g' \ - -e 's?$$(srcdir)/zparser.c?zparser.c?g' \ - -e 's?$$(srcdir)/zparser.h?zparser.h?g' \ > $(DEPEND_TMP) cp $(DEPEND_TARGET) $(DEPEND_TMP2) head -`$(EGREP) -n "# Dependencies" $(DEPEND_TARGET) | tail -1 | $(SED) -e 's/:.*$$//'` $(DEPEND_TMP2) > $(DEPEND_TARGET) @@ -444,7 +435,7 @@ dname.o: $(srcdir)/dname.c config.h $(srcdir)/compat/cpuset.h $(srcdir)/dns.h $( $(srcdir)/region-allocator.h $(srcdir)/util.h $(srcdir)/query.h $(srcdir)/namedb.h $(srcdir)/radtree.h $(srcdir)/rbtree.h $(srcdir)/nsd.h \ $(srcdir)/edns.h $(srcdir)/bitset.h $(srcdir)/packet.h $(srcdir)/tsig.h dns.o: $(srcdir)/dns.c config.h $(srcdir)/compat/cpuset.h $(srcdir)/dns.h $(srcdir)/zonec.h $(srcdir)/namedb.h $(srcdir)/dname.h \ - $(srcdir)/buffer.h $(srcdir)/region-allocator.h $(srcdir)/util.h $(srcdir)/radtree.h $(srcdir)/rbtree.h zparser.h + $(srcdir)/buffer.h $(srcdir)/region-allocator.h $(srcdir)/util.h $(srcdir)/radtree.h $(srcdir)/rbtree.h edns.o: $(srcdir)/edns.c config.h $(srcdir)/compat/cpuset.h $(srcdir)/dns.h $(srcdir)/edns.h $(srcdir)/buffer.h \ $(srcdir)/region-allocator.h $(srcdir)/util.h $(srcdir)/nsd.h $(srcdir)/bitset.h $(srcdir)/query.h $(srcdir)/namedb.h $(srcdir)/dname.h \ $(srcdir)/radtree.h $(srcdir)/rbtree.h $(srcdir)/packet.h $(srcdir)/tsig.h @@ -551,14 +542,9 @@ xfrd-tcp.o: $(srcdir)/xfrd-tcp.c config.h $(srcdir)/compat/cpuset.h $(srcdir)/ns xfr-inspect.o: $(srcdir)/xfr-inspect.c config.h $(srcdir)/compat/cpuset.h $(srcdir)/util.h $(srcdir)/buffer.h \ $(srcdir)/region-allocator.h $(srcdir)/packet.h $(srcdir)/dns.h $(srcdir)/namedb.h $(srcdir)/dname.h $(srcdir)/radtree.h $(srcdir)/rbtree.h \ $(srcdir)/rdata.h $(srcdir)/difffile.h $(srcdir)/options.h $(srcdir)/udb.h -zlexer.o: zlexer.c config.h $(srcdir)/compat/cpuset.h $(srcdir)/zonec.h $(srcdir)/namedb.h $(srcdir)/dname.h \ - $(srcdir)/buffer.h $(srcdir)/region-allocator.h $(srcdir)/util.h $(srcdir)/dns.h $(srcdir)/radtree.h $(srcdir)/rbtree.h zparser.h zonec.o: $(srcdir)/zonec.c config.h $(srcdir)/compat/cpuset.h $(srcdir)/zonec.h $(srcdir)/namedb.h $(srcdir)/dname.h \ $(srcdir)/buffer.h $(srcdir)/region-allocator.h $(srcdir)/util.h $(srcdir)/dns.h $(srcdir)/radtree.h $(srcdir)/rbtree.h $(srcdir)/rdata.h \ - zparser.h $(srcdir)/options.h $(srcdir)/nsec3.h -zparser.o: zparser.c config.h $(srcdir)/compat/cpuset.h $(srcdir)/dname.h $(srcdir)/buffer.h \ - $(srcdir)/region-allocator.h $(srcdir)/util.h $(srcdir)/namedb.h $(srcdir)/dns.h $(srcdir)/radtree.h $(srcdir)/rbtree.h $(srcdir)/zonec.h \ - zparser.h + $(srcdir)/options.h $(srcdir)/nsec3.h b64_ntop.o: $(srcdir)/compat/b64_ntop.c config.h $(srcdir)/compat/cpuset.h b64_pton.o: $(srcdir)/compat/b64_pton.c config.h $(srcdir)/compat/cpuset.h basename.o: $(srcdir)/compat/basename.c diff --git a/buffer.c b/buffer.c index d71fa15e3..3b78b47bc 100644 --- a/buffer.c +++ b/buffer.c @@ -41,7 +41,7 @@ buffer_create(region_type *region, size_t capacity) } void -buffer_create_from(buffer_type *buffer, void *data, size_t size) +buffer_create_from(buffer_type *buffer, const void *data, size_t size) { assert(data); diff --git a/buffer.h b/buffer.h index 1967173fd..1bdffa11b 100644 --- a/buffer.h +++ b/buffer.h @@ -76,7 +76,7 @@ buffer_type *buffer_create(region_type *region, size_t capacity); * and no memory allocations are done. The buffer is fixed and cannot * be resized using buffer_reserve(). */ -void buffer_create_from(buffer_type *buffer, void *data, size_t size); +void buffer_create_from(buffer_type *buffer, const void *data, size_t size); /* * Clear the buffer and make it ready for writing. The buffer's limit diff --git a/configure.ac b/configure.ac index b6590d8c2..c514a8173 100644 --- a/configure.ac +++ b/configure.ac @@ -1399,4 +1399,9 @@ if test "$enable_checking" = "yes"; then fi AC_CONFIG_FILES([Makefile $dnstap_config]) + +# Arguments introduced specifically for simdzone. +AC_ARG_ENABLE(westmere, AS_HELP_STRING([--disable-westmere], [Disable Westmere (SSE4.2) parser kernel])) +AC_ARG_ENABLE(haswell, AS_HELP_STRING([--disable-haswell], [Disable Haswell (AVX2) parser kernel])) +AC_CONFIG_SUBDIRS([simdzone]) AC_OUTPUT diff --git a/dbaccess.c b/dbaccess.c index 5d979979c..90d5d2cf3 100644 --- a/dbaccess.c +++ b/dbaccess.c @@ -35,7 +35,6 @@ void namedb_close(struct namedb* db) { if(db) { - zonec_desetup_parser(); region_destroy(db->region); } } @@ -155,7 +154,6 @@ namedb_open (struct nsd_options* opt) db->zonetree = radix_tree_create(db->region); db->diff_skip = 0; db->diff_pos = 0; - zonec_setup_parser(db); if (gettimeofday(&(db->diff_timestamp), NULL) != 0) { log_msg(LOG_ERR, "unable to load namedb: cannot initialize timestamp"); @@ -254,14 +252,13 @@ namedb_read_zonefile(struct nsd* nsd, struct zone* zone, udb_base* taskudb, } } - assert(parser); /* wipe zone from memory */ #ifdef NSEC3 nsec3_clear_precompile(nsd->db, zone); zone->nsec3_param = NULL; #endif delete_zone_rrs(nsd->db, zone); - errors = zonec_read(zone->opts->name, fname, zone); + errors = zonec_read(nsd->db, nsd->db->domains, zone->opts->name, fname, zone); if(errors > 0) { log_msg(LOG_ERR, "zone %s file %s read with %u errors", zone->opts->name, fname, errors); diff --git a/dns.c b/dns.c index 773facc6d..708c2347f 100644 --- a/dns.c +++ b/dns.c @@ -22,7 +22,6 @@ #include "dns.h" #include "zonec.h" -#include "zparser.h" /* Taken from RFC 1035, section 3.2.4. */ static lookup_table_type dns_rrclasses[] = { @@ -35,90 +34,90 @@ static lookup_table_type dns_rrclasses[] = { static rrtype_descriptor_type rrtype_descriptors[(RRTYPE_DESCRIPTORS_LENGTH+1)] = { /* 0 */ - { 0, NULL, T_UTYPE, 1, 1, { RDATA_WF_BINARY }, { RDATA_ZF_UNKNOWN } }, + { 0, NULL, 1, 1, { RDATA_WF_BINARY }, { RDATA_ZF_UNKNOWN } }, /* 1 */ - { TYPE_A, "A", T_A, 1, 1, + { TYPE_A, "A", 1, 1, { RDATA_WF_A }, { RDATA_ZF_A } }, /* 2 */ - { TYPE_NS, "NS", T_NS, 1, 1, + { TYPE_NS, "NS", 1, 1, { RDATA_WF_COMPRESSED_DNAME }, { RDATA_ZF_DNAME } }, /* 3 */ - { TYPE_MD, "MD", T_MD, 1, 1, + { TYPE_MD, "MD", 1, 1, { RDATA_WF_UNCOMPRESSED_DNAME }, { RDATA_ZF_DNAME } }, /* 4 */ - { TYPE_MF, "MF", T_MF, 1, 1, + { TYPE_MF, "MF", 1, 1, { RDATA_WF_UNCOMPRESSED_DNAME }, { RDATA_ZF_DNAME } }, /* 5 */ - { TYPE_CNAME, "CNAME", T_CNAME, 1, 1, + { TYPE_CNAME, "CNAME", 1, 1, { RDATA_WF_COMPRESSED_DNAME }, { RDATA_ZF_DNAME } }, /* 6 */ - { TYPE_SOA, "SOA", T_SOA, 7, 7, + { TYPE_SOA, "SOA", 7, 7, { RDATA_WF_COMPRESSED_DNAME, RDATA_WF_COMPRESSED_DNAME, RDATA_WF_LONG, RDATA_WF_LONG, RDATA_WF_LONG, RDATA_WF_LONG, RDATA_WF_LONG }, { RDATA_ZF_DNAME, RDATA_ZF_DNAME, RDATA_ZF_PERIOD, RDATA_ZF_PERIOD, RDATA_ZF_PERIOD, RDATA_ZF_PERIOD, RDATA_ZF_PERIOD } }, /* 7 */ - { TYPE_MB, "MB", T_MB, 1, 1, + { TYPE_MB, "MB", 1, 1, { RDATA_WF_COMPRESSED_DNAME }, { RDATA_ZF_DNAME } }, /* 8 */ - { TYPE_MG, "MG", T_MG, 1, 1, + { TYPE_MG, "MG", 1, 1, { RDATA_WF_COMPRESSED_DNAME }, { RDATA_ZF_DNAME } }, /* 9 */ - { TYPE_MR, "MR", T_MR, 1, 1, + { TYPE_MR, "MR", 1, 1, { RDATA_WF_COMPRESSED_DNAME }, { RDATA_ZF_DNAME } }, /* 10 */ - { TYPE_NULL, "NULL", T_UTYPE, 1, 1, + { TYPE_NULL, "NULL", 1, 1, { RDATA_WF_BINARY }, { RDATA_ZF_UNKNOWN } }, /* 11 */ - { TYPE_WKS, "WKS", T_WKS, 2, 2, + { TYPE_WKS, "WKS", 2, 2, { RDATA_WF_A, RDATA_WF_BINARY }, { RDATA_ZF_A, RDATA_ZF_SERVICES } }, /* 12 */ - { TYPE_PTR, "PTR", T_PTR, 1, 1, + { TYPE_PTR, "PTR", 1, 1, { RDATA_WF_COMPRESSED_DNAME }, { RDATA_ZF_DNAME } }, /* 13 */ - { TYPE_HINFO, "HINFO", T_HINFO, 2, 2, + { TYPE_HINFO, "HINFO", 2, 2, { RDATA_WF_TEXT, RDATA_WF_TEXT }, { RDATA_ZF_TEXT, RDATA_ZF_TEXT } }, /* 14 */ - { TYPE_MINFO, "MINFO", T_MINFO, 2, 2, + { TYPE_MINFO, "MINFO", 2, 2, { RDATA_WF_COMPRESSED_DNAME, RDATA_WF_COMPRESSED_DNAME }, { RDATA_ZF_DNAME, RDATA_ZF_DNAME } }, /* 15 */ - { TYPE_MX, "MX", T_MX, 2, 2, + { TYPE_MX, "MX", 2, 2, { RDATA_WF_SHORT, RDATA_WF_COMPRESSED_DNAME }, { RDATA_ZF_SHORT, RDATA_ZF_DNAME } }, /* 16 */ - { TYPE_TXT, "TXT", T_TXT, 1, 1, + { TYPE_TXT, "TXT", 1, 1, { RDATA_WF_TEXTS }, { RDATA_ZF_TEXTS } }, /* 17 */ - { TYPE_RP, "RP", T_RP, 2, 2, + { TYPE_RP, "RP", 2, 2, { RDATA_WF_UNCOMPRESSED_DNAME, RDATA_WF_UNCOMPRESSED_DNAME }, { RDATA_ZF_DNAME, RDATA_ZF_DNAME } }, /* 18 */ - { TYPE_AFSDB, "AFSDB", T_AFSDB, 2, 2, + { TYPE_AFSDB, "AFSDB", 2, 2, { RDATA_WF_SHORT, RDATA_WF_UNCOMPRESSED_DNAME }, { RDATA_ZF_SHORT, RDATA_ZF_DNAME } }, /* 19 */ - { TYPE_X25, "X25", T_X25, 1, 1, + { TYPE_X25, "X25", 1, 1, { RDATA_WF_TEXT }, { RDATA_ZF_TEXT } }, /* 20 */ - { TYPE_ISDN, "ISDN", T_ISDN, 1, 2, + { TYPE_ISDN, "ISDN", 1, 2, { RDATA_WF_TEXT, RDATA_WF_TEXT }, { RDATA_ZF_TEXT, RDATA_ZF_TEXT } }, /* 21 */ - { TYPE_RT, "RT", T_RT, 2, 2, + { TYPE_RT, "RT", 2, 2, { RDATA_WF_SHORT, RDATA_WF_UNCOMPRESSED_DNAME }, { RDATA_ZF_SHORT, RDATA_ZF_DNAME } }, /* 22 */ - { TYPE_NSAP, "NSAP", T_NSAP, 1, 1, + { TYPE_NSAP, "NSAP", 1, 1, { RDATA_WF_BINARY }, { RDATA_ZF_NSAP } }, /* 23 */ - { 23, NULL, T_UTYPE, 1, 1, { RDATA_WF_BINARY }, { RDATA_ZF_UNKNOWN } }, + { 23, NULL, 1, 1, { RDATA_WF_BINARY }, { RDATA_ZF_UNKNOWN } }, /* 24 */ - { TYPE_SIG, "SIG", T_SIG, 9, 9, + { TYPE_SIG, "SIG", 9, 9, { RDATA_WF_SHORT, RDATA_WF_BYTE, RDATA_WF_BYTE, RDATA_WF_LONG, RDATA_WF_LONG, RDATA_WF_LONG, RDATA_WF_SHORT, RDATA_WF_LITERAL_DNAME, RDATA_WF_BINARY }, @@ -126,67 +125,67 @@ static rrtype_descriptor_type rrtype_descriptors[(RRTYPE_DESCRIPTORS_LENGTH+1)] RDATA_ZF_TIME, RDATA_ZF_TIME, RDATA_ZF_SHORT, RDATA_ZF_LITERAL_DNAME, RDATA_ZF_BASE64 } }, /* 25 */ - { TYPE_KEY, "KEY", T_KEY, 4, 4, + { TYPE_KEY, "KEY", 4, 4, { RDATA_WF_SHORT, RDATA_WF_BYTE, RDATA_WF_BYTE, RDATA_WF_BINARY }, { RDATA_ZF_SHORT, RDATA_ZF_BYTE, RDATA_ZF_ALGORITHM, RDATA_ZF_BASE64 } }, /* 26 */ - { TYPE_PX, "PX", T_PX, 3, 3, + { TYPE_PX, "PX", 3, 3, { RDATA_WF_SHORT, RDATA_WF_UNCOMPRESSED_DNAME, RDATA_WF_UNCOMPRESSED_DNAME }, { RDATA_ZF_SHORT, RDATA_ZF_DNAME, RDATA_ZF_DNAME } }, /* 27 */ - { 27, NULL, T_UTYPE, 1, 1, { RDATA_WF_BINARY }, { RDATA_ZF_UNKNOWN } }, + { 27, NULL, 1, 1, { RDATA_WF_BINARY }, { RDATA_ZF_UNKNOWN } }, /* 28 */ - { TYPE_AAAA, "AAAA", T_AAAA, 1, 1, + { TYPE_AAAA, "AAAA", 1, 1, { RDATA_WF_AAAA }, { RDATA_ZF_AAAA } }, /* 29 */ - { TYPE_LOC, "LOC", T_LOC, 1, 1, + { TYPE_LOC, "LOC", 1, 1, { RDATA_WF_BINARY }, { RDATA_ZF_LOC } }, /* 30 */ - { TYPE_NXT, "NXT", T_NXT, 2, 2, + { TYPE_NXT, "NXT", 2, 2, { RDATA_WF_UNCOMPRESSED_DNAME, RDATA_WF_BINARY }, { RDATA_ZF_DNAME, RDATA_ZF_NXT } }, /* 31 */ - { 31, NULL, T_UTYPE, 1, 1, { RDATA_WF_BINARY }, { RDATA_ZF_UNKNOWN } }, + { 31, NULL, 1, 1, { RDATA_WF_BINARY }, { RDATA_ZF_UNKNOWN } }, /* 32 */ - { 32, NULL, T_UTYPE, 1, 1, { RDATA_WF_BINARY }, { RDATA_ZF_UNKNOWN } }, + { 32, NULL, 1, 1, { RDATA_WF_BINARY }, { RDATA_ZF_UNKNOWN } }, /* 33 */ - { TYPE_SRV, "SRV", T_SRV, 4, 4, + { TYPE_SRV, "SRV", 4, 4, { RDATA_WF_SHORT, RDATA_WF_SHORT, RDATA_WF_SHORT, RDATA_WF_UNCOMPRESSED_DNAME }, { RDATA_ZF_SHORT, RDATA_ZF_SHORT, RDATA_ZF_SHORT, RDATA_ZF_DNAME } }, /* 34 */ - { 34, NULL, T_UTYPE, 1, 1, { RDATA_WF_BINARY }, { RDATA_ZF_UNKNOWN } }, + { 34, NULL, 1, 1, { RDATA_WF_BINARY }, { RDATA_ZF_UNKNOWN } }, /* 35 */ - { TYPE_NAPTR, "NAPTR", T_NAPTR, 6, 6, + { TYPE_NAPTR, "NAPTR", 6, 6, { RDATA_WF_SHORT, RDATA_WF_SHORT, RDATA_WF_TEXT, RDATA_WF_TEXT, RDATA_WF_TEXT, RDATA_WF_UNCOMPRESSED_DNAME }, { RDATA_ZF_SHORT, RDATA_ZF_SHORT, RDATA_ZF_TEXT, RDATA_ZF_TEXT, RDATA_ZF_TEXT, RDATA_ZF_DNAME } }, /* 36 */ - { TYPE_KX, "KX", T_KX, 2, 2, + { TYPE_KX, "KX", 2, 2, { RDATA_WF_SHORT, RDATA_WF_UNCOMPRESSED_DNAME }, { RDATA_ZF_SHORT, RDATA_ZF_DNAME } }, /* 37 */ - { TYPE_CERT, "CERT", T_CERT, 4, 4, + { TYPE_CERT, "CERT", 4, 4, { RDATA_WF_SHORT, RDATA_WF_SHORT, RDATA_WF_BYTE, RDATA_WF_BINARY }, { RDATA_ZF_CERTIFICATE_TYPE, RDATA_ZF_SHORT, RDATA_ZF_ALGORITHM, RDATA_ZF_BASE64 } }, /* 38 */ - { TYPE_A6, NULL, T_UTYPE, 1, 1, { RDATA_WF_BINARY }, { RDATA_ZF_UNKNOWN } }, + { TYPE_A6, NULL, 1, 1, { RDATA_WF_BINARY }, { RDATA_ZF_UNKNOWN } }, /* 39 */ - { TYPE_DNAME, "DNAME", T_DNAME, 1, 1, + { TYPE_DNAME, "DNAME", 1, 1, { RDATA_WF_UNCOMPRESSED_DNAME }, { RDATA_ZF_DNAME } }, /* 40 */ - { 40, NULL, T_UTYPE, 1, 1, { RDATA_WF_BINARY }, { RDATA_ZF_UNKNOWN } }, + { 40, NULL, 1, 1, { RDATA_WF_BINARY }, { RDATA_ZF_UNKNOWN } }, /* 41 */ - { TYPE_OPT, "OPT", T_UTYPE, 1, 1, + { TYPE_OPT, "OPT", 1, 1, { RDATA_WF_BINARY }, { RDATA_ZF_UNKNOWN } }, /* 42 */ - { TYPE_APL, "APL", T_APL, 0, MAXRDATALEN, + { TYPE_APL, "APL", 0, MAXRDATALEN, { RDATA_WF_APL, RDATA_WF_APL, RDATA_WF_APL, RDATA_WF_APL, RDATA_WF_APL, RDATA_WF_APL, RDATA_WF_APL, RDATA_WF_APL, RDATA_WF_APL, RDATA_WF_APL, RDATA_WF_APL, RDATA_WF_APL, @@ -220,21 +219,21 @@ static rrtype_descriptor_type rrtype_descriptors[(RRTYPE_DESCRIPTORS_LENGTH+1)] RDATA_ZF_APL, RDATA_ZF_APL, RDATA_ZF_APL, RDATA_ZF_APL, RDATA_ZF_APL, RDATA_ZF_APL, RDATA_ZF_APL, RDATA_ZF_APL } }, /* 43 */ - { TYPE_DS, "DS", T_DS, 4, 4, + { TYPE_DS, "DS", 4, 4, { RDATA_WF_SHORT, RDATA_WF_BYTE, RDATA_WF_BYTE, RDATA_WF_BINARY }, { RDATA_ZF_SHORT, RDATA_ZF_ALGORITHM, RDATA_ZF_BYTE, RDATA_ZF_HEX } }, /* 44 */ - { TYPE_SSHFP, "SSHFP", T_SSHFP, 3, 3, + { TYPE_SSHFP, "SSHFP", 3, 3, { RDATA_WF_BYTE, RDATA_WF_BYTE, RDATA_WF_BINARY }, { RDATA_ZF_BYTE, RDATA_ZF_BYTE, RDATA_ZF_HEX } }, /* 45 */ - { TYPE_IPSECKEY, "IPSECKEY", T_IPSECKEY, 4, 5, + { TYPE_IPSECKEY, "IPSECKEY", 4, 5, { RDATA_WF_BYTE, RDATA_WF_BYTE, RDATA_WF_BYTE, RDATA_WF_IPSECGATEWAY, RDATA_WF_BINARY }, { RDATA_ZF_BYTE, RDATA_ZF_BYTE, RDATA_ZF_BYTE, RDATA_ZF_IPSECGATEWAY, RDATA_ZF_BASE64 } }, /* 46 */ - { TYPE_RRSIG, "RRSIG", T_RRSIG, 9, 9, + { TYPE_RRSIG, "RRSIG", 9, 9, { RDATA_WF_SHORT, RDATA_WF_BYTE, RDATA_WF_BYTE, RDATA_WF_LONG, RDATA_WF_LONG, RDATA_WF_LONG, RDATA_WF_SHORT, RDATA_WF_LITERAL_DNAME, RDATA_WF_BINARY }, @@ -242,18 +241,18 @@ static rrtype_descriptor_type rrtype_descriptors[(RRTYPE_DESCRIPTORS_LENGTH+1)] RDATA_ZF_TIME, RDATA_ZF_TIME, RDATA_ZF_SHORT, RDATA_ZF_LITERAL_DNAME, RDATA_ZF_BASE64 } }, /* 47 */ - { TYPE_NSEC, "NSEC", T_NSEC, 2, 2, + { TYPE_NSEC, "NSEC", 2, 2, { RDATA_WF_LITERAL_DNAME, RDATA_WF_BINARY }, { RDATA_ZF_LITERAL_DNAME, RDATA_ZF_NSEC } }, /* 48 */ - { TYPE_DNSKEY, "DNSKEY", T_DNSKEY, 4, 4, + { TYPE_DNSKEY, "DNSKEY", 4, 4, { RDATA_WF_SHORT, RDATA_WF_BYTE, RDATA_WF_BYTE, RDATA_WF_BINARY }, { RDATA_ZF_SHORT, RDATA_ZF_BYTE, RDATA_ZF_ALGORITHM, RDATA_ZF_BASE64 } }, /* 49 */ - { TYPE_DHCID, "DHCID", T_DHCID, 1, 1, { RDATA_WF_BINARY }, { RDATA_ZF_BASE64 } }, + { TYPE_DHCID, "DHCID", 1, 1, { RDATA_WF_BINARY }, { RDATA_ZF_BASE64 } }, /* 50 */ - { TYPE_NSEC3, "NSEC3", T_NSEC3, 6, 6, + { TYPE_NSEC3, "NSEC3", 6, 6, { RDATA_WF_BYTE, /* hash type */ RDATA_WF_BYTE, /* flags */ RDATA_WF_SHORT, /* iterations */ @@ -263,60 +262,60 @@ static rrtype_descriptor_type rrtype_descriptors[(RRTYPE_DESCRIPTORS_LENGTH+1)] { RDATA_ZF_BYTE, RDATA_ZF_BYTE, RDATA_ZF_SHORT, RDATA_ZF_HEX_LEN, RDATA_ZF_BASE32, RDATA_ZF_NSEC } }, /* 51 */ - { TYPE_NSEC3PARAM, "NSEC3PARAM", T_NSEC3PARAM, 4, 4, + { TYPE_NSEC3PARAM, "NSEC3PARAM", 4, 4, { RDATA_WF_BYTE, /* hash type */ RDATA_WF_BYTE, /* flags */ RDATA_WF_SHORT, /* iterations */ RDATA_WF_BINARYWITHLENGTH /* salt */ }, { RDATA_ZF_BYTE, RDATA_ZF_BYTE, RDATA_ZF_SHORT, RDATA_ZF_HEX_LEN } }, /* 52 */ - { TYPE_TLSA, "TLSA", T_TLSA, 4, 4, + { TYPE_TLSA, "TLSA", 4, 4, { RDATA_WF_BYTE, /* usage */ RDATA_WF_BYTE, /* selector */ RDATA_WF_BYTE, /* matching type */ RDATA_WF_BINARY }, /* certificate association data */ { RDATA_ZF_BYTE, RDATA_ZF_BYTE, RDATA_ZF_BYTE, RDATA_ZF_HEX } }, /* 53 */ - { TYPE_SMIMEA, "SMIMEA", T_SMIMEA, 4, 4, + { TYPE_SMIMEA, "SMIMEA", 4, 4, { RDATA_WF_BYTE, /* usage */ RDATA_WF_BYTE, /* selector */ RDATA_WF_BYTE, /* matching type */ RDATA_WF_BINARY }, /* certificate association data */ { RDATA_ZF_BYTE, RDATA_ZF_BYTE, RDATA_ZF_BYTE, RDATA_ZF_HEX } }, /* 54 */ - { 54, NULL, T_UTYPE, 1, 1, { RDATA_WF_BINARY }, { RDATA_ZF_UNKNOWN } }, + { 54, NULL, 1, 1, { RDATA_WF_BINARY }, { RDATA_ZF_UNKNOWN } }, /* 55 - HIP [RFC 5205] */ - { 55, NULL, T_UTYPE, 1, 1, { RDATA_WF_BINARY }, { RDATA_ZF_UNKNOWN } }, + { 55, NULL, 1, 1, { RDATA_WF_BINARY }, { RDATA_ZF_UNKNOWN } }, /* 56 - NINFO */ - { 56, NULL, T_UTYPE, 1, 1, { RDATA_WF_BINARY }, { RDATA_ZF_UNKNOWN } }, + { 56, NULL, 1, 1, { RDATA_WF_BINARY }, { RDATA_ZF_UNKNOWN } }, /* 57 - RKEY */ - { 57, NULL, T_UTYPE, 1, 1, { RDATA_WF_BINARY }, { RDATA_ZF_UNKNOWN } }, + { 57, NULL, 1, 1, { RDATA_WF_BINARY }, { RDATA_ZF_UNKNOWN } }, /* 58 - TALINK */ - { 58, NULL, T_UTYPE, 1, 1, { RDATA_WF_BINARY }, { RDATA_ZF_UNKNOWN } }, + { 58, NULL, 1, 1, { RDATA_WF_BINARY }, { RDATA_ZF_UNKNOWN } }, /* 59 - CDS */ - { TYPE_CDS, "CDS", T_CDS, 4, 4, + { TYPE_CDS, "CDS", 4, 4, { RDATA_WF_SHORT, RDATA_WF_BYTE, RDATA_WF_BYTE, RDATA_WF_BINARY }, { RDATA_ZF_SHORT, RDATA_ZF_ALGORITHM, RDATA_ZF_BYTE, RDATA_ZF_HEX } }, /* 60 - CDNSKEY */ - { TYPE_CDNSKEY, "CDNSKEY", T_CDNSKEY, 4, 4, + { TYPE_CDNSKEY, "CDNSKEY", 4, 4, { RDATA_WF_SHORT, RDATA_WF_BYTE, RDATA_WF_BYTE, RDATA_WF_BINARY }, { RDATA_ZF_SHORT, RDATA_ZF_BYTE, RDATA_ZF_ALGORITHM, RDATA_ZF_BASE64 } }, /* 61 - OPENPGPKEY */ - { TYPE_OPENPGPKEY, "OPENPGPKEY", T_OPENPGPKEY, 1, 1, + { TYPE_OPENPGPKEY, "OPENPGPKEY", 1, 1, { RDATA_WF_BINARY }, { RDATA_ZF_BASE64 } }, /* 62 - CSYNC */ - { TYPE_CSYNC, "CSYNC", T_CSYNC, 3, 3, { RDATA_WF_LONG, RDATA_WF_SHORT, + { TYPE_CSYNC, "CSYNC", 3, 3, { RDATA_WF_LONG, RDATA_WF_SHORT, RDATA_WF_BINARY }, { RDATA_ZF_LONG, RDATA_ZF_SHORT, RDATA_ZF_NSEC } }, /* 63 - ZONEMD */ - { TYPE_ZONEMD, "ZONEMD", T_ZONEMD, 4, 4, + { TYPE_ZONEMD, "ZONEMD", 4, 4, { RDATA_WF_LONG, /* serial */ RDATA_WF_BYTE, /* scheme */ RDATA_WF_BYTE, /* hash Algorithm */ RDATA_WF_BINARY }, /* digest */ { RDATA_ZF_PERIOD, RDATA_ZF_BYTE, RDATA_ZF_BYTE, RDATA_ZF_HEX } }, /* 64 - SVCB */ - { TYPE_SVCB, "SVCB", T_SVCB, 2, MAXRDATALEN, + { TYPE_SVCB, "SVCB", 2, MAXRDATALEN, { RDATA_WF_SHORT /* SvcFieldPriority */ , RDATA_WF_UNCOMPRESSED_DNAME /* SvcDomainName */ , RDATA_WF_SVCPARAM, RDATA_WF_SVCPARAM /* SvcFieldValue */ @@ -365,7 +364,7 @@ static rrtype_descriptor_type rrtype_descriptors[(RRTYPE_DESCRIPTORS_LENGTH+1)] , RDATA_ZF_SVCPARAM, RDATA_ZF_SVCPARAM, RDATA_ZF_SVCPARAM } }, /* 65 - HTTPS */ - { TYPE_HTTPS, "HTTPS", T_HTTPS, 2, MAXRDATALEN, + { TYPE_HTTPS, "HTTPS", 2, MAXRDATALEN, { RDATA_WF_SHORT /* SvcFieldPriority */ , RDATA_WF_UNCOMPRESSED_DNAME /* SvcDomainName */ , RDATA_WF_SVCPARAM, RDATA_WF_SVCPARAM /* SvcFieldValue */ @@ -414,73 +413,73 @@ static rrtype_descriptor_type rrtype_descriptors[(RRTYPE_DESCRIPTORS_LENGTH+1)] , RDATA_ZF_SVCPARAM, RDATA_ZF_SVCPARAM, RDATA_ZF_SVCPARAM } }, /* 66 */ - { 66, NULL, T_UTYPE, 1, 1, { RDATA_WF_BINARY }, { RDATA_ZF_UNKNOWN } }, + { 66, NULL, 1, 1, { RDATA_WF_BINARY }, { RDATA_ZF_UNKNOWN } }, /* 67 */ - { 67, NULL, T_UTYPE, 1, 1, { RDATA_WF_BINARY }, { RDATA_ZF_UNKNOWN } }, + { 67, NULL, 1, 1, { RDATA_WF_BINARY }, { RDATA_ZF_UNKNOWN } }, /* 68 */ - { 68, NULL, T_UTYPE, 1, 1, { RDATA_WF_BINARY }, { RDATA_ZF_UNKNOWN } }, + { 68, NULL, 1, 1, { RDATA_WF_BINARY }, { RDATA_ZF_UNKNOWN } }, /* 69 */ - { 69, NULL, T_UTYPE, 1, 1, { RDATA_WF_BINARY }, { RDATA_ZF_UNKNOWN } }, + { 69, NULL, 1, 1, { RDATA_WF_BINARY }, { RDATA_ZF_UNKNOWN } }, /* 70 */ - { 70, NULL, T_UTYPE, 1, 1, { RDATA_WF_BINARY }, { RDATA_ZF_UNKNOWN } }, + { 70, NULL, 1, 1, { RDATA_WF_BINARY }, { RDATA_ZF_UNKNOWN } }, /* 71 */ - { 71, NULL, T_UTYPE, 1, 1, { RDATA_WF_BINARY }, { RDATA_ZF_UNKNOWN } }, + { 71, NULL, 1, 1, { RDATA_WF_BINARY }, { RDATA_ZF_UNKNOWN } }, /* 72 */ - { 72, NULL, T_UTYPE, 1, 1, { RDATA_WF_BINARY }, { RDATA_ZF_UNKNOWN } }, + { 72, NULL, 1, 1, { RDATA_WF_BINARY }, { RDATA_ZF_UNKNOWN } }, /* 73 */ - { 73, NULL, T_UTYPE, 1, 1, { RDATA_WF_BINARY }, { RDATA_ZF_UNKNOWN } }, + { 73, NULL, 1, 1, { RDATA_WF_BINARY }, { RDATA_ZF_UNKNOWN } }, /* 74 */ - { 74, NULL, T_UTYPE, 1, 1, { RDATA_WF_BINARY }, { RDATA_ZF_UNKNOWN } }, + { 74, NULL, 1, 1, { RDATA_WF_BINARY }, { RDATA_ZF_UNKNOWN } }, /* 75 */ - { 75, NULL, T_UTYPE, 1, 1, { RDATA_WF_BINARY }, { RDATA_ZF_UNKNOWN } }, + { 75, NULL, 1, 1, { RDATA_WF_BINARY }, { RDATA_ZF_UNKNOWN } }, /* 76 */ - { 76, NULL, T_UTYPE, 1, 1, { RDATA_WF_BINARY }, { RDATA_ZF_UNKNOWN } }, + { 76, NULL, 1, 1, { RDATA_WF_BINARY }, { RDATA_ZF_UNKNOWN } }, /* 77 */ - { 77, NULL, T_UTYPE, 1, 1, { RDATA_WF_BINARY }, { RDATA_ZF_UNKNOWN } }, + { 77, NULL, 1, 1, { RDATA_WF_BINARY }, { RDATA_ZF_UNKNOWN } }, /* 78 */ - { 78, NULL, T_UTYPE, 1, 1, { RDATA_WF_BINARY }, { RDATA_ZF_UNKNOWN } }, + { 78, NULL, 1, 1, { RDATA_WF_BINARY }, { RDATA_ZF_UNKNOWN } }, /* 79 */ - { 79, NULL, T_UTYPE, 1, 1, { RDATA_WF_BINARY }, { RDATA_ZF_UNKNOWN } }, + { 79, NULL, 1, 1, { RDATA_WF_BINARY }, { RDATA_ZF_UNKNOWN } }, /* 80 */ - { 80, NULL, T_UTYPE, 1, 1, { RDATA_WF_BINARY }, { RDATA_ZF_UNKNOWN } }, + { 80, NULL, 1, 1, { RDATA_WF_BINARY }, { RDATA_ZF_UNKNOWN } }, /* 81 */ - { 81, NULL, T_UTYPE, 1, 1, { RDATA_WF_BINARY }, { RDATA_ZF_UNKNOWN } }, + { 81, NULL, 1, 1, { RDATA_WF_BINARY }, { RDATA_ZF_UNKNOWN } }, /* 82 */ - { 82, NULL, T_UTYPE, 1, 1, { RDATA_WF_BINARY }, { RDATA_ZF_UNKNOWN } }, + { 82, NULL, 1, 1, { RDATA_WF_BINARY }, { RDATA_ZF_UNKNOWN } }, /* 83 */ - { 83, NULL, T_UTYPE, 1, 1, { RDATA_WF_BINARY }, { RDATA_ZF_UNKNOWN } }, + { 83, NULL, 1, 1, { RDATA_WF_BINARY }, { RDATA_ZF_UNKNOWN } }, /* 84 */ - { 84, NULL, T_UTYPE, 1, 1, { RDATA_WF_BINARY }, { RDATA_ZF_UNKNOWN } }, + { 84, NULL, 1, 1, { RDATA_WF_BINARY }, { RDATA_ZF_UNKNOWN } }, /* 85 */ - { 85, NULL, T_UTYPE, 1, 1, { RDATA_WF_BINARY }, { RDATA_ZF_UNKNOWN } }, + { 85, NULL, 1, 1, { RDATA_WF_BINARY }, { RDATA_ZF_UNKNOWN } }, /* 86 */ - { 86, NULL, T_UTYPE, 1, 1, { RDATA_WF_BINARY }, { RDATA_ZF_UNKNOWN } }, + { 86, NULL, 1, 1, { RDATA_WF_BINARY }, { RDATA_ZF_UNKNOWN } }, /* 87 */ - { 87, NULL, T_UTYPE, 1, 1, { RDATA_WF_BINARY }, { RDATA_ZF_UNKNOWN } }, + { 87, NULL, 1, 1, { RDATA_WF_BINARY }, { RDATA_ZF_UNKNOWN } }, /* 88 */ - { 88, NULL, T_UTYPE, 1, 1, { RDATA_WF_BINARY }, { RDATA_ZF_UNKNOWN } }, + { 88, NULL, 1, 1, { RDATA_WF_BINARY }, { RDATA_ZF_UNKNOWN } }, /* 89 */ - { 89, NULL, T_UTYPE, 1, 1, { RDATA_WF_BINARY }, { RDATA_ZF_UNKNOWN } }, + { 89, NULL, 1, 1, { RDATA_WF_BINARY }, { RDATA_ZF_UNKNOWN } }, /* 90 */ - { 90, NULL, T_UTYPE, 1, 1, { RDATA_WF_BINARY }, { RDATA_ZF_UNKNOWN } }, + { 90, NULL, 1, 1, { RDATA_WF_BINARY }, { RDATA_ZF_UNKNOWN } }, /* 91 */ - { 91, NULL, T_UTYPE, 1, 1, { RDATA_WF_BINARY }, { RDATA_ZF_UNKNOWN } }, + { 91, NULL, 1, 1, { RDATA_WF_BINARY }, { RDATA_ZF_UNKNOWN } }, /* 92 */ - { 92, NULL, T_UTYPE, 1, 1, { RDATA_WF_BINARY }, { RDATA_ZF_UNKNOWN } }, + { 92, NULL, 1, 1, { RDATA_WF_BINARY }, { RDATA_ZF_UNKNOWN } }, /* 93 */ - { 93, NULL, T_UTYPE, 1, 1, { RDATA_WF_BINARY }, { RDATA_ZF_UNKNOWN } }, + { 93, NULL, 1, 1, { RDATA_WF_BINARY }, { RDATA_ZF_UNKNOWN } }, /* 94 */ - { 94, NULL, T_UTYPE, 1, 1, { RDATA_WF_BINARY }, { RDATA_ZF_UNKNOWN } }, + { 94, NULL, 1, 1, { RDATA_WF_BINARY }, { RDATA_ZF_UNKNOWN } }, /* 95 */ - { 95, NULL, T_UTYPE, 1, 1, { RDATA_WF_BINARY }, { RDATA_ZF_UNKNOWN } }, + { 95, NULL, 1, 1, { RDATA_WF_BINARY }, { RDATA_ZF_UNKNOWN } }, /* 96 */ - { 96, NULL, T_UTYPE, 1, 1, { RDATA_WF_BINARY }, { RDATA_ZF_UNKNOWN } }, + { 96, NULL, 1, 1, { RDATA_WF_BINARY }, { RDATA_ZF_UNKNOWN } }, /* 97 */ - { 97, NULL, T_UTYPE, 1, 1, { RDATA_WF_BINARY }, { RDATA_ZF_UNKNOWN } }, + { 97, NULL, 1, 1, { RDATA_WF_BINARY }, { RDATA_ZF_UNKNOWN } }, /* 98 */ - { 98, NULL, T_UTYPE, 1, 1, { RDATA_WF_BINARY }, { RDATA_ZF_UNKNOWN } }, + { 98, NULL, 1, 1, { RDATA_WF_BINARY }, { RDATA_ZF_UNKNOWN } }, /* 99 */ - { TYPE_SPF, "SPF", T_SPF, 1, MAXRDATALEN, + { TYPE_SPF, "SPF", 1, MAXRDATALEN, { RDATA_WF_TEXT, RDATA_WF_TEXT, RDATA_WF_TEXT, RDATA_WF_TEXT, RDATA_WF_TEXT, RDATA_WF_TEXT, RDATA_WF_TEXT, RDATA_WF_TEXT, RDATA_WF_TEXT, RDATA_WF_TEXT, RDATA_WF_TEXT, RDATA_WF_TEXT, @@ -514,343 +513,343 @@ static rrtype_descriptor_type rrtype_descriptors[(RRTYPE_DESCRIPTORS_LENGTH+1)] RDATA_ZF_TEXT, RDATA_ZF_TEXT, RDATA_ZF_TEXT, RDATA_ZF_TEXT, RDATA_ZF_TEXT, RDATA_ZF_TEXT, RDATA_ZF_TEXT, RDATA_ZF_TEXT } }, /* 100 - UINFO */ - { 100, NULL, T_UTYPE, 1, 1, { RDATA_WF_BINARY }, { RDATA_ZF_UNKNOWN } }, + { 100, NULL, 1, 1, { RDATA_WF_BINARY }, { RDATA_ZF_UNKNOWN } }, /* 101 - UID */ - { 101, NULL, T_UTYPE, 1, 1, { RDATA_WF_BINARY }, { RDATA_ZF_UNKNOWN } }, + { 101, NULL, 1, 1, { RDATA_WF_BINARY }, { RDATA_ZF_UNKNOWN } }, /* 102 - GID */ - { 102, NULL, T_UTYPE, 1, 1, { RDATA_WF_BINARY }, { RDATA_ZF_UNKNOWN } }, + { 102, NULL, 1, 1, { RDATA_WF_BINARY }, { RDATA_ZF_UNKNOWN } }, /* 103 - UNSPEC */ - { 103, NULL, T_UTYPE, 1, 1, { RDATA_WF_BINARY }, { RDATA_ZF_UNKNOWN } }, + { 103, NULL, 1, 1, { RDATA_WF_BINARY }, { RDATA_ZF_UNKNOWN } }, /* 104 */ - { TYPE_NID, "NID", T_NID, 2, 2, + { TYPE_NID, "NID", 2, 2, { RDATA_WF_SHORT, RDATA_WF_ILNP64 }, { RDATA_ZF_SHORT, RDATA_ZF_ILNP64 } }, /* 105 */ - { TYPE_L32, "L32", T_L32, 2, 2, + { TYPE_L32, "L32", 2, 2, { RDATA_WF_SHORT, RDATA_WF_A }, { RDATA_ZF_SHORT, RDATA_ZF_A } }, /* 106 */ - { TYPE_L64, "L64", T_L64, 2, 2, + { TYPE_L64, "L64", 2, 2, { RDATA_WF_SHORT, RDATA_WF_ILNP64 }, { RDATA_ZF_SHORT, RDATA_ZF_ILNP64 } }, /* 107 */ - { TYPE_LP, "LP", T_LP, 2, 2, + { TYPE_LP, "LP", 2, 2, { RDATA_WF_SHORT, RDATA_WF_UNCOMPRESSED_DNAME }, { RDATA_ZF_SHORT, RDATA_ZF_DNAME } }, /* 108 */ - { TYPE_EUI48, "EUI48", T_EUI48, 1, 1, + { TYPE_EUI48, "EUI48", 1, 1, { RDATA_WF_EUI48 }, { RDATA_ZF_EUI48 } }, /* 109 */ - { TYPE_EUI64, "EUI64", T_EUI64, 1, 1, + { TYPE_EUI64, "EUI64", 1, 1, { RDATA_WF_EUI64 }, { RDATA_ZF_EUI64 } }, /* 110 */ - { 110, NULL, T_UTYPE, 1, 1, { RDATA_WF_BINARY }, { RDATA_ZF_UNKNOWN } }, + { 110, NULL, 1, 1, { RDATA_WF_BINARY }, { RDATA_ZF_UNKNOWN } }, /* 111 */ - { 111, NULL, T_UTYPE, 1, 1, { RDATA_WF_BINARY }, { RDATA_ZF_UNKNOWN } }, + { 111, NULL, 1, 1, { RDATA_WF_BINARY }, { RDATA_ZF_UNKNOWN } }, /* 112 */ - { 112, NULL, T_UTYPE, 1, 1, { RDATA_WF_BINARY }, { RDATA_ZF_UNKNOWN } }, + { 112, NULL, 1, 1, { RDATA_WF_BINARY }, { RDATA_ZF_UNKNOWN } }, /* 113 */ - { 113, NULL, T_UTYPE, 1, 1, { RDATA_WF_BINARY }, { RDATA_ZF_UNKNOWN } }, + { 113, NULL, 1, 1, { RDATA_WF_BINARY }, { RDATA_ZF_UNKNOWN } }, /* 114 */ - { 114, NULL, T_UTYPE, 1, 1, { RDATA_WF_BINARY }, { RDATA_ZF_UNKNOWN } }, + { 114, NULL, 1, 1, { RDATA_WF_BINARY }, { RDATA_ZF_UNKNOWN } }, /* 115 */ - { 115, NULL, T_UTYPE, 1, 1, { RDATA_WF_BINARY }, { RDATA_ZF_UNKNOWN } }, + { 115, NULL, 1, 1, { RDATA_WF_BINARY }, { RDATA_ZF_UNKNOWN } }, /* 116 */ - { 116, NULL, T_UTYPE, 1, 1, { RDATA_WF_BINARY }, { RDATA_ZF_UNKNOWN } }, + { 116, NULL, 1, 1, { RDATA_WF_BINARY }, { RDATA_ZF_UNKNOWN } }, /* 117 */ - { 117, NULL, T_UTYPE, 1, 1, { RDATA_WF_BINARY }, { RDATA_ZF_UNKNOWN } }, + { 117, NULL, 1, 1, { RDATA_WF_BINARY }, { RDATA_ZF_UNKNOWN } }, /* 118 */ - { 118, NULL, T_UTYPE, 1, 1, { RDATA_WF_BINARY }, { RDATA_ZF_UNKNOWN } }, + { 118, NULL, 1, 1, { RDATA_WF_BINARY }, { RDATA_ZF_UNKNOWN } }, /* 119 */ - { 119, NULL, T_UTYPE, 1, 1, { RDATA_WF_BINARY }, { RDATA_ZF_UNKNOWN } }, + { 119, NULL, 1, 1, { RDATA_WF_BINARY }, { RDATA_ZF_UNKNOWN } }, /* 120 */ - { 120, NULL, T_UTYPE, 1, 1, { RDATA_WF_BINARY }, { RDATA_ZF_UNKNOWN } }, + { 120, NULL, 1, 1, { RDATA_WF_BINARY }, { RDATA_ZF_UNKNOWN } }, /* 121 */ - { 121, NULL, T_UTYPE, 1, 1, { RDATA_WF_BINARY }, { RDATA_ZF_UNKNOWN } }, + { 121, NULL, 1, 1, { RDATA_WF_BINARY }, { RDATA_ZF_UNKNOWN } }, /* 122 */ - { 122, NULL, T_UTYPE, 1, 1, { RDATA_WF_BINARY }, { RDATA_ZF_UNKNOWN } }, + { 122, NULL, 1, 1, { RDATA_WF_BINARY }, { RDATA_ZF_UNKNOWN } }, /* 123 */ - { 123, NULL, T_UTYPE, 1, 1, { RDATA_WF_BINARY }, { RDATA_ZF_UNKNOWN } }, + { 123, NULL, 1, 1, { RDATA_WF_BINARY }, { RDATA_ZF_UNKNOWN } }, /* 124 */ - { 124, NULL, T_UTYPE, 1, 1, { RDATA_WF_BINARY }, { RDATA_ZF_UNKNOWN } }, + { 124, NULL, 1, 1, { RDATA_WF_BINARY }, { RDATA_ZF_UNKNOWN } }, /* 125 */ - { 125, NULL, T_UTYPE, 1, 1, { RDATA_WF_BINARY }, { RDATA_ZF_UNKNOWN } }, + { 125, NULL, 1, 1, { RDATA_WF_BINARY }, { RDATA_ZF_UNKNOWN } }, /* 126 */ - { 126, NULL, T_UTYPE, 1, 1, { RDATA_WF_BINARY }, { RDATA_ZF_UNKNOWN } }, + { 126, NULL, 1, 1, { RDATA_WF_BINARY }, { RDATA_ZF_UNKNOWN } }, /* 127 */ - { 127, NULL, T_UTYPE, 1, 1, { RDATA_WF_BINARY }, { RDATA_ZF_UNKNOWN } }, + { 127, NULL, 1, 1, { RDATA_WF_BINARY }, { RDATA_ZF_UNKNOWN } }, /* 128 */ - { 128, NULL, T_UTYPE, 1, 1, { RDATA_WF_BINARY }, { RDATA_ZF_UNKNOWN } }, + { 128, NULL, 1, 1, { RDATA_WF_BINARY }, { RDATA_ZF_UNKNOWN } }, /* 129 */ - { 129, NULL, T_UTYPE, 1, 1, { RDATA_WF_BINARY }, { RDATA_ZF_UNKNOWN } }, + { 129, NULL, 1, 1, { RDATA_WF_BINARY }, { RDATA_ZF_UNKNOWN } }, /* 130 */ - { 130, NULL, T_UTYPE, 1, 1, { RDATA_WF_BINARY }, { RDATA_ZF_UNKNOWN } }, + { 130, NULL, 1, 1, { RDATA_WF_BINARY }, { RDATA_ZF_UNKNOWN } }, /* 131 */ - { 131, NULL, T_UTYPE, 1, 1, { RDATA_WF_BINARY }, { RDATA_ZF_UNKNOWN } }, + { 131, NULL, 1, 1, { RDATA_WF_BINARY }, { RDATA_ZF_UNKNOWN } }, /* 132 */ - { 132, NULL, T_UTYPE, 1, 1, { RDATA_WF_BINARY }, { RDATA_ZF_UNKNOWN } }, + { 132, NULL, 1, 1, { RDATA_WF_BINARY }, { RDATA_ZF_UNKNOWN } }, /* 133 */ - { 133, NULL, T_UTYPE, 1, 1, { RDATA_WF_BINARY }, { RDATA_ZF_UNKNOWN } }, + { 133, NULL, 1, 1, { RDATA_WF_BINARY }, { RDATA_ZF_UNKNOWN } }, /* 134 */ - { 134, NULL, T_UTYPE, 1, 1, { RDATA_WF_BINARY }, { RDATA_ZF_UNKNOWN } }, + { 134, NULL, 1, 1, { RDATA_WF_BINARY }, { RDATA_ZF_UNKNOWN } }, /* 135 */ - { 135, NULL, T_UTYPE, 1, 1, { RDATA_WF_BINARY }, { RDATA_ZF_UNKNOWN } }, + { 135, NULL, 1, 1, { RDATA_WF_BINARY }, { RDATA_ZF_UNKNOWN } }, /* 136 */ - { 136, NULL, T_UTYPE, 1, 1, { RDATA_WF_BINARY }, { RDATA_ZF_UNKNOWN } }, + { 136, NULL, 1, 1, { RDATA_WF_BINARY }, { RDATA_ZF_UNKNOWN } }, /* 137 */ - { 137, NULL, T_UTYPE, 1, 1, { RDATA_WF_BINARY }, { RDATA_ZF_UNKNOWN } }, + { 137, NULL, 1, 1, { RDATA_WF_BINARY }, { RDATA_ZF_UNKNOWN } }, /* 138 */ - { 138, NULL, T_UTYPE, 1, 1, { RDATA_WF_BINARY }, { RDATA_ZF_UNKNOWN } }, + { 138, NULL, 1, 1, { RDATA_WF_BINARY }, { RDATA_ZF_UNKNOWN } }, /* 139 */ - { 139, NULL, T_UTYPE, 1, 1, { RDATA_WF_BINARY }, { RDATA_ZF_UNKNOWN } }, + { 139, NULL, 1, 1, { RDATA_WF_BINARY }, { RDATA_ZF_UNKNOWN } }, /* 140 */ - { 140, NULL, T_UTYPE, 1, 1, { RDATA_WF_BINARY }, { RDATA_ZF_UNKNOWN } }, + { 140, NULL, 1, 1, { RDATA_WF_BINARY }, { RDATA_ZF_UNKNOWN } }, /* 141 */ - { 141, NULL, T_UTYPE, 1, 1, { RDATA_WF_BINARY }, { RDATA_ZF_UNKNOWN } }, + { 141, NULL, 1, 1, { RDATA_WF_BINARY }, { RDATA_ZF_UNKNOWN } }, /* 142 */ - { 142, NULL, T_UTYPE, 1, 1, { RDATA_WF_BINARY }, { RDATA_ZF_UNKNOWN } }, + { 142, NULL, 1, 1, { RDATA_WF_BINARY }, { RDATA_ZF_UNKNOWN } }, /* 143 */ - { 143, NULL, T_UTYPE, 1, 1, { RDATA_WF_BINARY }, { RDATA_ZF_UNKNOWN } }, + { 143, NULL, 1, 1, { RDATA_WF_BINARY }, { RDATA_ZF_UNKNOWN } }, /* 144 */ - { 144, NULL, T_UTYPE, 1, 1, { RDATA_WF_BINARY }, { RDATA_ZF_UNKNOWN } }, + { 144, NULL, 1, 1, { RDATA_WF_BINARY }, { RDATA_ZF_UNKNOWN } }, /* 145 */ - { 145, NULL, T_UTYPE, 1, 1, { RDATA_WF_BINARY }, { RDATA_ZF_UNKNOWN } }, + { 145, NULL, 1, 1, { RDATA_WF_BINARY }, { RDATA_ZF_UNKNOWN } }, /* 146 */ - { 146, NULL, T_UTYPE, 1, 1, { RDATA_WF_BINARY }, { RDATA_ZF_UNKNOWN } }, + { 146, NULL, 1, 1, { RDATA_WF_BINARY }, { RDATA_ZF_UNKNOWN } }, /* 147 */ - { 147, NULL, T_UTYPE, 1, 1, { RDATA_WF_BINARY }, { RDATA_ZF_UNKNOWN } }, + { 147, NULL, 1, 1, { RDATA_WF_BINARY }, { RDATA_ZF_UNKNOWN } }, /* 148 */ - { 148, NULL, T_UTYPE, 1, 1, { RDATA_WF_BINARY }, { RDATA_ZF_UNKNOWN } }, + { 148, NULL, 1, 1, { RDATA_WF_BINARY }, { RDATA_ZF_UNKNOWN } }, /* 149 */ - { 149, NULL, T_UTYPE, 1, 1, { RDATA_WF_BINARY }, { RDATA_ZF_UNKNOWN } }, + { 149, NULL, 1, 1, { RDATA_WF_BINARY }, { RDATA_ZF_UNKNOWN } }, /* 150 */ - { 150, NULL, T_UTYPE, 1, 1, { RDATA_WF_BINARY }, { RDATA_ZF_UNKNOWN } }, + { 150, NULL, 1, 1, { RDATA_WF_BINARY }, { RDATA_ZF_UNKNOWN } }, /* 151 */ - { 151, NULL, T_UTYPE, 1, 1, { RDATA_WF_BINARY }, { RDATA_ZF_UNKNOWN } }, + { 151, NULL, 1, 1, { RDATA_WF_BINARY }, { RDATA_ZF_UNKNOWN } }, /* 152 */ - { 152, NULL, T_UTYPE, 1, 1, { RDATA_WF_BINARY }, { RDATA_ZF_UNKNOWN } }, + { 152, NULL, 1, 1, { RDATA_WF_BINARY }, { RDATA_ZF_UNKNOWN } }, /* 153 */ - { 153, NULL, T_UTYPE, 1, 1, { RDATA_WF_BINARY }, { RDATA_ZF_UNKNOWN } }, + { 153, NULL, 1, 1, { RDATA_WF_BINARY }, { RDATA_ZF_UNKNOWN } }, /* 154 */ - { 154, NULL, T_UTYPE, 1, 1, { RDATA_WF_BINARY }, { RDATA_ZF_UNKNOWN } }, + { 154, NULL, 1, 1, { RDATA_WF_BINARY }, { RDATA_ZF_UNKNOWN } }, /* 155 */ - { 155, NULL, T_UTYPE, 1, 1, { RDATA_WF_BINARY }, { RDATA_ZF_UNKNOWN } }, + { 155, NULL, 1, 1, { RDATA_WF_BINARY }, { RDATA_ZF_UNKNOWN } }, /* 156 */ - { 156, NULL, T_UTYPE, 1, 1, { RDATA_WF_BINARY }, { RDATA_ZF_UNKNOWN } }, + { 156, NULL, 1, 1, { RDATA_WF_BINARY }, { RDATA_ZF_UNKNOWN } }, /* 157 */ - { 157, NULL, T_UTYPE, 1, 1, { RDATA_WF_BINARY }, { RDATA_ZF_UNKNOWN } }, + { 157, NULL, 1, 1, { RDATA_WF_BINARY }, { RDATA_ZF_UNKNOWN } }, /* 158 */ - { 158, NULL, T_UTYPE, 1, 1, { RDATA_WF_BINARY }, { RDATA_ZF_UNKNOWN } }, + { 158, NULL, 1, 1, { RDATA_WF_BINARY }, { RDATA_ZF_UNKNOWN } }, /* 159 */ - { 159, NULL, T_UTYPE, 1, 1, { RDATA_WF_BINARY }, { RDATA_ZF_UNKNOWN } }, + { 159, NULL, 1, 1, { RDATA_WF_BINARY }, { RDATA_ZF_UNKNOWN } }, /* 160 */ - { 160, NULL, T_UTYPE, 1, 1, { RDATA_WF_BINARY }, { RDATA_ZF_UNKNOWN } }, + { 160, NULL, 1, 1, { RDATA_WF_BINARY }, { RDATA_ZF_UNKNOWN } }, /* 161 */ - { 161, NULL, T_UTYPE, 1, 1, { RDATA_WF_BINARY }, { RDATA_ZF_UNKNOWN } }, + { 161, NULL, 1, 1, { RDATA_WF_BINARY }, { RDATA_ZF_UNKNOWN } }, /* 162 */ - { 162, NULL, T_UTYPE, 1, 1, { RDATA_WF_BINARY }, { RDATA_ZF_UNKNOWN } }, + { 162, NULL, 1, 1, { RDATA_WF_BINARY }, { RDATA_ZF_UNKNOWN } }, /* 163 */ - { 163, NULL, T_UTYPE, 1, 1, { RDATA_WF_BINARY }, { RDATA_ZF_UNKNOWN } }, + { 163, NULL, 1, 1, { RDATA_WF_BINARY }, { RDATA_ZF_UNKNOWN } }, /* 164 */ - { 164, NULL, T_UTYPE, 1, 1, { RDATA_WF_BINARY }, { RDATA_ZF_UNKNOWN } }, + { 164, NULL, 1, 1, { RDATA_WF_BINARY }, { RDATA_ZF_UNKNOWN } }, /* 165 */ - { 165, NULL, T_UTYPE, 1, 1, { RDATA_WF_BINARY }, { RDATA_ZF_UNKNOWN } }, + { 165, NULL, 1, 1, { RDATA_WF_BINARY }, { RDATA_ZF_UNKNOWN } }, /* 166 */ - { 166, NULL, T_UTYPE, 1, 1, { RDATA_WF_BINARY }, { RDATA_ZF_UNKNOWN } }, + { 166, NULL, 1, 1, { RDATA_WF_BINARY }, { RDATA_ZF_UNKNOWN } }, /* 167 */ - { 167, NULL, T_UTYPE, 1, 1, { RDATA_WF_BINARY }, { RDATA_ZF_UNKNOWN } }, + { 167, NULL, 1, 1, { RDATA_WF_BINARY }, { RDATA_ZF_UNKNOWN } }, /* 168 */ - { 168, NULL, T_UTYPE, 1, 1, { RDATA_WF_BINARY }, { RDATA_ZF_UNKNOWN } }, + { 168, NULL, 1, 1, { RDATA_WF_BINARY }, { RDATA_ZF_UNKNOWN } }, /* 169 */ - { 169, NULL, T_UTYPE, 1, 1, { RDATA_WF_BINARY }, { RDATA_ZF_UNKNOWN } }, + { 169, NULL, 1, 1, { RDATA_WF_BINARY }, { RDATA_ZF_UNKNOWN } }, /* 170 */ - { 170, NULL, T_UTYPE, 1, 1, { RDATA_WF_BINARY }, { RDATA_ZF_UNKNOWN } }, + { 170, NULL, 1, 1, { RDATA_WF_BINARY }, { RDATA_ZF_UNKNOWN } }, /* 171 */ - { 171, NULL, T_UTYPE, 1, 1, { RDATA_WF_BINARY }, { RDATA_ZF_UNKNOWN } }, + { 171, NULL, 1, 1, { RDATA_WF_BINARY }, { RDATA_ZF_UNKNOWN } }, /* 172 */ - { 172, NULL, T_UTYPE, 1, 1, { RDATA_WF_BINARY }, { RDATA_ZF_UNKNOWN } }, + { 172, NULL, 1, 1, { RDATA_WF_BINARY }, { RDATA_ZF_UNKNOWN } }, /* 173 */ - { 173, NULL, T_UTYPE, 1, 1, { RDATA_WF_BINARY }, { RDATA_ZF_UNKNOWN } }, + { 173, NULL, 1, 1, { RDATA_WF_BINARY }, { RDATA_ZF_UNKNOWN } }, /* 174 */ - { 174, NULL, T_UTYPE, 1, 1, { RDATA_WF_BINARY }, { RDATA_ZF_UNKNOWN } }, + { 174, NULL, 1, 1, { RDATA_WF_BINARY }, { RDATA_ZF_UNKNOWN } }, /* 175 */ - { 175, NULL, T_UTYPE, 1, 1, { RDATA_WF_BINARY }, { RDATA_ZF_UNKNOWN } }, + { 175, NULL, 1, 1, { RDATA_WF_BINARY }, { RDATA_ZF_UNKNOWN } }, /* 176 */ - { 176, NULL, T_UTYPE, 1, 1, { RDATA_WF_BINARY }, { RDATA_ZF_UNKNOWN } }, + { 176, NULL, 1, 1, { RDATA_WF_BINARY }, { RDATA_ZF_UNKNOWN } }, /* 177 */ - { 177, NULL, T_UTYPE, 1, 1, { RDATA_WF_BINARY }, { RDATA_ZF_UNKNOWN } }, + { 177, NULL, 1, 1, { RDATA_WF_BINARY }, { RDATA_ZF_UNKNOWN } }, /* 178 */ - { 178, NULL, T_UTYPE, 1, 1, { RDATA_WF_BINARY }, { RDATA_ZF_UNKNOWN } }, + { 178, NULL, 1, 1, { RDATA_WF_BINARY }, { RDATA_ZF_UNKNOWN } }, /* 179 */ - { 179, NULL, T_UTYPE, 1, 1, { RDATA_WF_BINARY }, { RDATA_ZF_UNKNOWN } }, + { 179, NULL, 1, 1, { RDATA_WF_BINARY }, { RDATA_ZF_UNKNOWN } }, /* 180 */ - { 180, NULL, T_UTYPE, 1, 1, { RDATA_WF_BINARY }, { RDATA_ZF_UNKNOWN } }, + { 180, NULL, 1, 1, { RDATA_WF_BINARY }, { RDATA_ZF_UNKNOWN } }, /* 181 */ - { 181, NULL, T_UTYPE, 1, 1, { RDATA_WF_BINARY }, { RDATA_ZF_UNKNOWN } }, + { 181, NULL, 1, 1, { RDATA_WF_BINARY }, { RDATA_ZF_UNKNOWN } }, /* 182 */ - { 182, NULL, T_UTYPE, 1, 1, { RDATA_WF_BINARY }, { RDATA_ZF_UNKNOWN } }, + { 182, NULL, 1, 1, { RDATA_WF_BINARY }, { RDATA_ZF_UNKNOWN } }, /* 183 */ - { 183, NULL, T_UTYPE, 1, 1, { RDATA_WF_BINARY }, { RDATA_ZF_UNKNOWN } }, + { 183, NULL, 1, 1, { RDATA_WF_BINARY }, { RDATA_ZF_UNKNOWN } }, /* 184 */ - { 184, NULL, T_UTYPE, 1, 1, { RDATA_WF_BINARY }, { RDATA_ZF_UNKNOWN } }, + { 184, NULL, 1, 1, { RDATA_WF_BINARY }, { RDATA_ZF_UNKNOWN } }, /* 185 */ - { 185, NULL, T_UTYPE, 1, 1, { RDATA_WF_BINARY }, { RDATA_ZF_UNKNOWN } }, + { 185, NULL, 1, 1, { RDATA_WF_BINARY }, { RDATA_ZF_UNKNOWN } }, /* 186 */ - { 186, NULL, T_UTYPE, 1, 1, { RDATA_WF_BINARY }, { RDATA_ZF_UNKNOWN } }, + { 186, NULL, 1, 1, { RDATA_WF_BINARY }, { RDATA_ZF_UNKNOWN } }, /* 187 */ - { 187, NULL, T_UTYPE, 1, 1, { RDATA_WF_BINARY }, { RDATA_ZF_UNKNOWN } }, + { 187, NULL, 1, 1, { RDATA_WF_BINARY }, { RDATA_ZF_UNKNOWN } }, /* 188 */ - { 188, NULL, T_UTYPE, 1, 1, { RDATA_WF_BINARY }, { RDATA_ZF_UNKNOWN } }, + { 188, NULL, 1, 1, { RDATA_WF_BINARY }, { RDATA_ZF_UNKNOWN } }, /* 189 */ - { 189, NULL, T_UTYPE, 1, 1, { RDATA_WF_BINARY }, { RDATA_ZF_UNKNOWN } }, + { 189, NULL, 1, 1, { RDATA_WF_BINARY }, { RDATA_ZF_UNKNOWN } }, /* 190 */ - { 190, NULL, T_UTYPE, 1, 1, { RDATA_WF_BINARY }, { RDATA_ZF_UNKNOWN } }, + { 190, NULL, 1, 1, { RDATA_WF_BINARY }, { RDATA_ZF_UNKNOWN } }, /* 191 */ - { 191, NULL, T_UTYPE, 1, 1, { RDATA_WF_BINARY }, { RDATA_ZF_UNKNOWN } }, + { 191, NULL, 1, 1, { RDATA_WF_BINARY }, { RDATA_ZF_UNKNOWN } }, /* 192 */ - { 192, NULL, T_UTYPE, 1, 1, { RDATA_WF_BINARY }, { RDATA_ZF_UNKNOWN } }, + { 192, NULL, 1, 1, { RDATA_WF_BINARY }, { RDATA_ZF_UNKNOWN } }, /* 193 */ - { 193, NULL, T_UTYPE, 1, 1, { RDATA_WF_BINARY }, { RDATA_ZF_UNKNOWN } }, + { 193, NULL, 1, 1, { RDATA_WF_BINARY }, { RDATA_ZF_UNKNOWN } }, /* 194 */ - { 194, NULL, T_UTYPE, 1, 1, { RDATA_WF_BINARY }, { RDATA_ZF_UNKNOWN } }, + { 194, NULL, 1, 1, { RDATA_WF_BINARY }, { RDATA_ZF_UNKNOWN } }, /* 195 */ - { 195, NULL, T_UTYPE, 1, 1, { RDATA_WF_BINARY }, { RDATA_ZF_UNKNOWN } }, + { 195, NULL, 1, 1, { RDATA_WF_BINARY }, { RDATA_ZF_UNKNOWN } }, /* 196 */ - { 196, NULL, T_UTYPE, 1, 1, { RDATA_WF_BINARY }, { RDATA_ZF_UNKNOWN } }, + { 196, NULL, 1, 1, { RDATA_WF_BINARY }, { RDATA_ZF_UNKNOWN } }, /* 197 */ - { 197, NULL, T_UTYPE, 1, 1, { RDATA_WF_BINARY }, { RDATA_ZF_UNKNOWN } }, + { 197, NULL, 1, 1, { RDATA_WF_BINARY }, { RDATA_ZF_UNKNOWN } }, /* 198 */ - { 198, NULL, T_UTYPE, 1, 1, { RDATA_WF_BINARY }, { RDATA_ZF_UNKNOWN } }, + { 198, NULL, 1, 1, { RDATA_WF_BINARY }, { RDATA_ZF_UNKNOWN } }, /* 199 */ - { 199, NULL, T_UTYPE, 1, 1, { RDATA_WF_BINARY }, { RDATA_ZF_UNKNOWN } }, + { 199, NULL, 1, 1, { RDATA_WF_BINARY }, { RDATA_ZF_UNKNOWN } }, /* 200 */ - { 200, NULL, T_UTYPE, 1, 1, { RDATA_WF_BINARY }, { RDATA_ZF_UNKNOWN } }, + { 200, NULL, 1, 1, { RDATA_WF_BINARY }, { RDATA_ZF_UNKNOWN } }, /* 201 */ - { 201, NULL, T_UTYPE, 1, 1, { RDATA_WF_BINARY }, { RDATA_ZF_UNKNOWN } }, + { 201, NULL, 1, 1, { RDATA_WF_BINARY }, { RDATA_ZF_UNKNOWN } }, /* 202 */ - { 202, NULL, T_UTYPE, 1, 1, { RDATA_WF_BINARY }, { RDATA_ZF_UNKNOWN } }, + { 202, NULL, 1, 1, { RDATA_WF_BINARY }, { RDATA_ZF_UNKNOWN } }, /* 203 */ - { 203, NULL, T_UTYPE, 1, 1, { RDATA_WF_BINARY }, { RDATA_ZF_UNKNOWN } }, + { 203, NULL, 1, 1, { RDATA_WF_BINARY }, { RDATA_ZF_UNKNOWN } }, /* 204 */ - { 204, NULL, T_UTYPE, 1, 1, { RDATA_WF_BINARY }, { RDATA_ZF_UNKNOWN } }, + { 204, NULL, 1, 1, { RDATA_WF_BINARY }, { RDATA_ZF_UNKNOWN } }, /* 205 */ - { 205, NULL, T_UTYPE, 1, 1, { RDATA_WF_BINARY }, { RDATA_ZF_UNKNOWN } }, + { 205, NULL, 1, 1, { RDATA_WF_BINARY }, { RDATA_ZF_UNKNOWN } }, /* 206 */ - { 206, NULL, T_UTYPE, 1, 1, { RDATA_WF_BINARY }, { RDATA_ZF_UNKNOWN } }, + { 206, NULL, 1, 1, { RDATA_WF_BINARY }, { RDATA_ZF_UNKNOWN } }, /* 207 */ - { 207, NULL, T_UTYPE, 1, 1, { RDATA_WF_BINARY }, { RDATA_ZF_UNKNOWN } }, + { 207, NULL, 1, 1, { RDATA_WF_BINARY }, { RDATA_ZF_UNKNOWN } }, /* 208 */ - { 208, NULL, T_UTYPE, 1, 1, { RDATA_WF_BINARY }, { RDATA_ZF_UNKNOWN } }, + { 208, NULL, 1, 1, { RDATA_WF_BINARY }, { RDATA_ZF_UNKNOWN } }, /* 209 */ - { 209, NULL, T_UTYPE, 1, 1, { RDATA_WF_BINARY }, { RDATA_ZF_UNKNOWN } }, + { 209, NULL, 1, 1, { RDATA_WF_BINARY }, { RDATA_ZF_UNKNOWN } }, /* 210 */ - { 210, NULL, T_UTYPE, 1, 1, { RDATA_WF_BINARY }, { RDATA_ZF_UNKNOWN } }, + { 210, NULL, 1, 1, { RDATA_WF_BINARY }, { RDATA_ZF_UNKNOWN } }, /* 211 */ - { 211, NULL, T_UTYPE, 1, 1, { RDATA_WF_BINARY }, { RDATA_ZF_UNKNOWN } }, + { 211, NULL, 1, 1, { RDATA_WF_BINARY }, { RDATA_ZF_UNKNOWN } }, /* 212 */ - { 212, NULL, T_UTYPE, 1, 1, { RDATA_WF_BINARY }, { RDATA_ZF_UNKNOWN } }, + { 212, NULL, 1, 1, { RDATA_WF_BINARY }, { RDATA_ZF_UNKNOWN } }, /* 213 */ - { 213, NULL, T_UTYPE, 1, 1, { RDATA_WF_BINARY }, { RDATA_ZF_UNKNOWN } }, + { 213, NULL, 1, 1, { RDATA_WF_BINARY }, { RDATA_ZF_UNKNOWN } }, /* 214 */ - { 214, NULL, T_UTYPE, 1, 1, { RDATA_WF_BINARY }, { RDATA_ZF_UNKNOWN } }, + { 214, NULL, 1, 1, { RDATA_WF_BINARY }, { RDATA_ZF_UNKNOWN } }, /* 215 */ - { 215, NULL, T_UTYPE, 1, 1, { RDATA_WF_BINARY }, { RDATA_ZF_UNKNOWN } }, + { 215, NULL, 1, 1, { RDATA_WF_BINARY }, { RDATA_ZF_UNKNOWN } }, /* 216 */ - { 216, NULL, T_UTYPE, 1, 1, { RDATA_WF_BINARY }, { RDATA_ZF_UNKNOWN } }, + { 216, NULL, 1, 1, { RDATA_WF_BINARY }, { RDATA_ZF_UNKNOWN } }, /* 217 */ - { 217, NULL, T_UTYPE, 1, 1, { RDATA_WF_BINARY }, { RDATA_ZF_UNKNOWN } }, + { 217, NULL, 1, 1, { RDATA_WF_BINARY }, { RDATA_ZF_UNKNOWN } }, /* 218 */ - { 218, NULL, T_UTYPE, 1, 1, { RDATA_WF_BINARY }, { RDATA_ZF_UNKNOWN } }, + { 218, NULL, 1, 1, { RDATA_WF_BINARY }, { RDATA_ZF_UNKNOWN } }, /* 219 */ - { 219, NULL, T_UTYPE, 1, 1, { RDATA_WF_BINARY }, { RDATA_ZF_UNKNOWN } }, + { 219, NULL, 1, 1, { RDATA_WF_BINARY }, { RDATA_ZF_UNKNOWN } }, /* 220 */ - { 220, NULL, T_UTYPE, 1, 1, { RDATA_WF_BINARY }, { RDATA_ZF_UNKNOWN } }, + { 220, NULL, 1, 1, { RDATA_WF_BINARY }, { RDATA_ZF_UNKNOWN } }, /* 221 */ - { 221, NULL, T_UTYPE, 1, 1, { RDATA_WF_BINARY }, { RDATA_ZF_UNKNOWN } }, + { 221, NULL, 1, 1, { RDATA_WF_BINARY }, { RDATA_ZF_UNKNOWN } }, /* 222 */ - { 222, NULL, T_UTYPE, 1, 1, { RDATA_WF_BINARY }, { RDATA_ZF_UNKNOWN } }, + { 222, NULL, 1, 1, { RDATA_WF_BINARY }, { RDATA_ZF_UNKNOWN } }, /* 223 */ - { 223, NULL, T_UTYPE, 1, 1, { RDATA_WF_BINARY }, { RDATA_ZF_UNKNOWN } }, + { 223, NULL, 1, 1, { RDATA_WF_BINARY }, { RDATA_ZF_UNKNOWN } }, /* 224 */ - { 224, NULL, T_UTYPE, 1, 1, { RDATA_WF_BINARY }, { RDATA_ZF_UNKNOWN } }, + { 224, NULL, 1, 1, { RDATA_WF_BINARY }, { RDATA_ZF_UNKNOWN } }, /* 225 */ - { 225, NULL, T_UTYPE, 1, 1, { RDATA_WF_BINARY }, { RDATA_ZF_UNKNOWN } }, + { 225, NULL, 1, 1, { RDATA_WF_BINARY }, { RDATA_ZF_UNKNOWN } }, /* 226 */ - { 226, NULL, T_UTYPE, 1, 1, { RDATA_WF_BINARY }, { RDATA_ZF_UNKNOWN } }, + { 226, NULL, 1, 1, { RDATA_WF_BINARY }, { RDATA_ZF_UNKNOWN } }, /* 227 */ - { 227, NULL, T_UTYPE, 1, 1, { RDATA_WF_BINARY }, { RDATA_ZF_UNKNOWN } }, + { 227, NULL, 1, 1, { RDATA_WF_BINARY }, { RDATA_ZF_UNKNOWN } }, /* 228 */ - { 228, NULL, T_UTYPE, 1, 1, { RDATA_WF_BINARY }, { RDATA_ZF_UNKNOWN } }, + { 228, NULL, 1, 1, { RDATA_WF_BINARY }, { RDATA_ZF_UNKNOWN } }, /* 229 */ - { 229, NULL, T_UTYPE, 1, 1, { RDATA_WF_BINARY }, { RDATA_ZF_UNKNOWN } }, + { 229, NULL, 1, 1, { RDATA_WF_BINARY }, { RDATA_ZF_UNKNOWN } }, /* 230 */ - { 230, NULL, T_UTYPE, 1, 1, { RDATA_WF_BINARY }, { RDATA_ZF_UNKNOWN } }, + { 230, NULL, 1, 1, { RDATA_WF_BINARY }, { RDATA_ZF_UNKNOWN } }, /* 231 */ - { 231, NULL, T_UTYPE, 1, 1, { RDATA_WF_BINARY }, { RDATA_ZF_UNKNOWN } }, + { 231, NULL, 1, 1, { RDATA_WF_BINARY }, { RDATA_ZF_UNKNOWN } }, /* 232 */ - { 232, NULL, T_UTYPE, 1, 1, { RDATA_WF_BINARY }, { RDATA_ZF_UNKNOWN } }, + { 232, NULL, 1, 1, { RDATA_WF_BINARY }, { RDATA_ZF_UNKNOWN } }, /* 233 */ - { 233, NULL, T_UTYPE, 1, 1, { RDATA_WF_BINARY }, { RDATA_ZF_UNKNOWN } }, + { 233, NULL, 1, 1, { RDATA_WF_BINARY }, { RDATA_ZF_UNKNOWN } }, /* 234 */ - { 234, NULL, T_UTYPE, 1, 1, { RDATA_WF_BINARY }, { RDATA_ZF_UNKNOWN } }, + { 234, NULL, 1, 1, { RDATA_WF_BINARY }, { RDATA_ZF_UNKNOWN } }, /* 235 */ - { 235, NULL, T_UTYPE, 1, 1, { RDATA_WF_BINARY }, { RDATA_ZF_UNKNOWN } }, + { 235, NULL, 1, 1, { RDATA_WF_BINARY }, { RDATA_ZF_UNKNOWN } }, /* 236 */ - { 236, NULL, T_UTYPE, 1, 1, { RDATA_WF_BINARY }, { RDATA_ZF_UNKNOWN } }, + { 236, NULL, 1, 1, { RDATA_WF_BINARY }, { RDATA_ZF_UNKNOWN } }, /* 237 */ - { 237, NULL, T_UTYPE, 1, 1, { RDATA_WF_BINARY }, { RDATA_ZF_UNKNOWN } }, + { 237, NULL, 1, 1, { RDATA_WF_BINARY }, { RDATA_ZF_UNKNOWN } }, /* 238 */ - { 238, NULL, T_UTYPE, 1, 1, { RDATA_WF_BINARY }, { RDATA_ZF_UNKNOWN } }, + { 238, NULL, 1, 1, { RDATA_WF_BINARY }, { RDATA_ZF_UNKNOWN } }, /* 239 */ - { 239, NULL, T_UTYPE, 1, 1, { RDATA_WF_BINARY }, { RDATA_ZF_UNKNOWN } }, + { 239, NULL, 1, 1, { RDATA_WF_BINARY }, { RDATA_ZF_UNKNOWN } }, /* 240 */ - { 240, NULL, T_UTYPE, 1, 1, { RDATA_WF_BINARY }, { RDATA_ZF_UNKNOWN } }, + { 240, NULL, 1, 1, { RDATA_WF_BINARY }, { RDATA_ZF_UNKNOWN } }, /* 241 */ - { 241, NULL, T_UTYPE, 1, 1, { RDATA_WF_BINARY }, { RDATA_ZF_UNKNOWN } }, + { 241, NULL, 1, 1, { RDATA_WF_BINARY }, { RDATA_ZF_UNKNOWN } }, /* 242 */ - { 242, NULL, T_UTYPE, 1, 1, { RDATA_WF_BINARY }, { RDATA_ZF_UNKNOWN } }, + { 242, NULL, 1, 1, { RDATA_WF_BINARY }, { RDATA_ZF_UNKNOWN } }, /* 243 */ - { 243, NULL, T_UTYPE, 1, 1, { RDATA_WF_BINARY }, { RDATA_ZF_UNKNOWN } }, + { 243, NULL, 1, 1, { RDATA_WF_BINARY }, { RDATA_ZF_UNKNOWN } }, /* 244 */ - { 244, NULL, T_UTYPE, 1, 1, { RDATA_WF_BINARY }, { RDATA_ZF_UNKNOWN } }, + { 244, NULL, 1, 1, { RDATA_WF_BINARY }, { RDATA_ZF_UNKNOWN } }, /* 245 */ - { 245, NULL, T_UTYPE, 1, 1, { RDATA_WF_BINARY }, { RDATA_ZF_UNKNOWN } }, + { 245, NULL, 1, 1, { RDATA_WF_BINARY }, { RDATA_ZF_UNKNOWN } }, /* 246 */ - { 246, NULL, T_UTYPE, 1, 1, { RDATA_WF_BINARY }, { RDATA_ZF_UNKNOWN } }, + { 246, NULL, 1, 1, { RDATA_WF_BINARY }, { RDATA_ZF_UNKNOWN } }, /* 247 */ - { 247, NULL, T_UTYPE, 1, 1, { RDATA_WF_BINARY }, { RDATA_ZF_UNKNOWN } }, + { 247, NULL, 1, 1, { RDATA_WF_BINARY }, { RDATA_ZF_UNKNOWN } }, /* 248 */ - { 248, NULL, T_UTYPE, 1, 1, { RDATA_WF_BINARY }, { RDATA_ZF_UNKNOWN } }, + { 248, NULL, 1, 1, { RDATA_WF_BINARY }, { RDATA_ZF_UNKNOWN } }, /* 249 - TKEY [RFC 2930] */ - { 249, NULL, T_UTYPE, 1, 1, { RDATA_WF_BINARY }, { RDATA_ZF_UNKNOWN } }, + { 249, NULL, 1, 1, { RDATA_WF_BINARY }, { RDATA_ZF_UNKNOWN } }, /* 250 - TSIG [RFC 2845] */ - { 250, NULL, T_UTYPE, 1, 1, { RDATA_WF_BINARY }, { RDATA_ZF_UNKNOWN } }, + { 250, NULL, 1, 1, { RDATA_WF_BINARY }, { RDATA_ZF_UNKNOWN } }, /* 251 - IXFR [RFC 1995] */ - { 251, NULL, T_UTYPE, 1, 1, { RDATA_WF_BINARY }, { RDATA_ZF_UNKNOWN } }, + { 251, NULL, 1, 1, { RDATA_WF_BINARY }, { RDATA_ZF_UNKNOWN } }, /* 252 - AXFR [RFC 1035, RFC 5936] */ - { 252, NULL, T_UTYPE, 1, 1, { RDATA_WF_BINARY }, { RDATA_ZF_UNKNOWN } }, + { 252, NULL, 1, 1, { RDATA_WF_BINARY }, { RDATA_ZF_UNKNOWN } }, /* 253 - MAILB [RFC 1035] */ - { 253, NULL, T_UTYPE, 1, 1, { RDATA_WF_BINARY }, { RDATA_ZF_UNKNOWN } }, + { 253, NULL, 1, 1, { RDATA_WF_BINARY }, { RDATA_ZF_UNKNOWN } }, /* 254 - MAILA [RFC 1035] */ - { 254, NULL, T_UTYPE, 1, 1, { RDATA_WF_BINARY }, { RDATA_ZF_UNKNOWN } }, + { 254, NULL, 1, 1, { RDATA_WF_BINARY }, { RDATA_ZF_UNKNOWN } }, /* 255 - * [RFC 1035, RFC 6895] */ - { 255, NULL, T_UTYPE, 1, 1, { RDATA_WF_BINARY }, { RDATA_ZF_UNKNOWN } }, + { 255, NULL, 1, 1, { RDATA_WF_BINARY }, { RDATA_ZF_UNKNOWN } }, /* 256 - URI */ - { TYPE_URI, "URI", T_URI, 3, 3, + { TYPE_URI, "URI", 3, 3, { RDATA_WF_SHORT, RDATA_WF_SHORT, RDATA_WF_LONG_TEXT }, { RDATA_ZF_SHORT, RDATA_ZF_SHORT, RDATA_ZF_LONG_TEXT } }, /* 257 - CAA [RFC 6844] */ - { TYPE_CAA, "CAA", T_CAA, 3, 3, + { TYPE_CAA, "CAA", 3, 3, { RDATA_WF_BYTE, RDATA_WF_TEXT, RDATA_WF_LONG_TEXT }, { RDATA_ZF_BYTE, RDATA_ZF_TAG, RDATA_ZF_LONG_TEXT } }, /* 258 - AVC */ - { TYPE_AVC, "AVC", T_AVC, 1, 1, + { TYPE_AVC, "AVC", 1, 1, { RDATA_WF_TEXTS }, { RDATA_ZF_TEXTS } }, /* 32768 - TA */ /* 32769 */ - { TYPE_DLV, "DLV", T_DLV, 4, 4, + { TYPE_DLV, "DLV", 4, 4, { RDATA_WF_SHORT, RDATA_WF_BYTE, RDATA_WF_BYTE, RDATA_WF_BINARY }, { RDATA_ZF_SHORT, RDATA_ZF_ALGORITHM, RDATA_ZF_BYTE, RDATA_ZF_HEX } }, }; diff --git a/dns.h b/dns.h index 924db3de0..15bd31997 100644 --- a/dns.h +++ b/dns.h @@ -265,7 +265,6 @@ struct rrtype_descriptor { uint16_t type; /* RR type */ const char *name; /* Textual name. */ - int token; /* Parser token. */ uint32_t minimum; /* Minimum number of RDATAs. */ uint32_t maximum; /* Maximum number of RDATAs. */ uint8_t wireformat[MAXRDATALEN]; /* rdata_wireformat_type */ @@ -296,13 +295,4 @@ uint16_t rrtype_from_string(const char *name); const char *rrclass_to_string(uint16_t rrclass); uint16_t rrclass_from_string(const char *name); -#ifdef __cplusplus -inline rr_section_type -operator++(rr_section_type &lhs) -{ - lhs = (rr_section_type) ((int) lhs + 1); - return lhs; -} -#endif /* __cplusplus */ - #endif /* DNS_H */ diff --git a/doc/ChangeLog b/doc/ChangeLog index 97df1a01b..d33208044 100644 --- a/doc/ChangeLog +++ b/doc/ChangeLog @@ -1,3 +1,6 @@ +16 April 2024: Jeroen + - Replace Flex+Bison based zone parser with simdzone. + 15 April 2024: Wouter - Unit test for dname subdomain test used by xfrd-tcp.c. diff --git a/doc/RELNOTES b/doc/RELNOTES index a7d13168b..67efe30ab 100644 --- a/doc/RELNOTES +++ b/doc/RELNOTES @@ -1,6 +1,6 @@ NSD RELEASE NOTES -4.9.2 (Upcoming) +4.10.0 (Upcoming) ================ FEATURES: BUG FIXES: @@ -13,6 +13,7 @@ BUG FIXES: - Fix IXFR requests upstream for zones with a long name. Thanks for the report to Yuuki Wakisaka from Internet Initiative Japan Inc. - Unit test for dname subdomain test used by xfrd-tcp.c. + - Merge #278: Replace Flex+Bison based zone parser with simdzone. 4.9.1 ================ diff --git a/ixfr.c b/ixfr.c index b4f59d636..6a56ac753 100644 --- a/ixfr.c +++ b/ixfr.c @@ -26,6 +26,7 @@ #include "axfr.h" #include "options.h" #include "zonec.h" +#include "zone.h" /* * For optimal compression IXFR response packets are limited in size @@ -2238,64 +2239,6 @@ void ixfr_write_to_file(struct zone* zone, const char* zfile) ixfr_write_files(zone, zfile); } -/* skip whitespace */ -static char* skipwhite(char* str) -{ - while(isspace((unsigned char)*str)) - str++; - return str; -} - -/* read one RR from file */ -static int ixfr_data_readrr(struct zone* zone, FILE* in, const char* ixfrfile, - struct region* tempregion, struct domain_table* temptable, - struct zone* tempzone, struct rr** rr) -{ - char line[65536]; - char* str; - struct domain* domain_parsed = NULL; - int num_rrs = 0; - line[sizeof(line)-1]=0; - while(!feof(in)) { - if(!fgets(line, sizeof(line), in)) { - if(errno == 0) { - log_msg(LOG_ERR, "zone %s IXFR data %s: " - "unexpected end of file", zone->opts->name, ixfrfile); - return 0; - } - log_msg(LOG_ERR, "zone %s IXFR data %s: " - "cannot read: %s", zone->opts->name, ixfrfile, - strerror(errno)); - return 0; - } - str = skipwhite(line); - if(str[0] == 0) { - /* empty line */ - continue; - } - if(str[0] == ';') { - /* comment line */ - continue; - } - if(zonec_parse_string(tempregion, temptable, tempzone, - line, &domain_parsed, &num_rrs)) { - log_msg(LOG_ERR, "zone %s IXFR data %s: parse error", - zone->opts->name, ixfrfile); - return 0; - } - if(num_rrs != 1) { - log_msg(LOG_ERR, "zone %s IXFR data %s: parse error", - zone->opts->name, ixfrfile); - return 0; - } - *rr = &domain_parsed->rrsets->rrs[0]; - return 1; - } - log_msg(LOG_ERR, "zone %s IXFR data %s: file too short, no newsoa", - zone->opts->name, ixfrfile); - return 0; -} - /* delete from domain table */ static void domain_table_delete(struct domain_table* table, struct domain* domain) @@ -2419,45 +2362,41 @@ static void clear_temp_table_of_rr(struct domain_table* temptable, /* read ixfr data new SOA */ static int ixfr_data_readnewsoa(struct ixfr_data* data, struct zone* zone, - FILE* in, const char* ixfrfile, struct region* tempregion, + struct rr *rr, zone_parser_t *parser, struct region* tempregion, struct domain_table* temptable, struct zone* tempzone, uint32_t dest_serial) { - struct rr* rr; size_t capacity = 0; - if(!ixfr_data_readrr(zone, in, ixfrfile, tempregion, temptable, - tempzone, &rr)) - return 0; if(rr->type != TYPE_SOA) { - log_msg(LOG_ERR, "zone %s ixfr data %s: IXFR data does not start with SOA", - zone->opts->name, ixfrfile); + zone_error(parser, "zone %s ixfr data: IXFR data does not start with SOA", + zone->opts->name); return 0; } if(rr->klass != CLASS_IN) { - log_msg(LOG_ERR, "zone %s ixfr data %s: IXFR data is not class IN", - zone->opts->name, ixfrfile); + zone_error(parser, "zone %s ixfr data: IXFR data is not class IN", + zone->opts->name); return 0; } if(!zone->apex) { - log_msg(LOG_ERR, "zone %s ixfr data %s: zone has no apex, no zone data", - zone->opts->name, ixfrfile); + zone_error(parser, "zone %s ixfr data: zone has no apex, no zone data", + zone->opts->name); return 0; } if(dname_compare(domain_dname(zone->apex), domain_dname(rr->owner)) != 0) { - log_msg(LOG_ERR, "zone %s ixfr data %s: IXFR data wrong SOA for zone %s", - zone->opts->name, ixfrfile, domain_to_string(rr->owner)); + zone_error(parser, "zone %s ixfr data: IXFR data wrong SOA for zone %s", + zone->opts->name, domain_to_string(rr->owner)); return 0; } data->newserial = soa_rr_get_serial(rr); if(data->newserial != dest_serial) { - log_msg(LOG_ERR, "zone %s ixfr data %s: IXFR data contains the wrong version, serial %u but want destination serial %u", - zone->opts->name, ixfrfile, data->newserial, + zone_error(parser, "zone %s ixfr data: IXFR data contains the wrong version, serial %u but want destination serial %u", + zone->opts->name, data->newserial, dest_serial); return 0; } if(!ixfr_putrr(domain_dname(rr->owner), rr->type, rr->klass, rr->ttl, rr->rdatas, rr->rdata_count, &data->newsoa, &data->newsoa_len, &capacity)) { - log_msg(LOG_ERR, "zone %s ixfr data %s: cannot allocate space", - zone->opts->name, ixfrfile); + zone_error(parser, "zone %s ixfr data: cannot allocate space", + zone->opts->name); return 0; } clear_temp_table_of_rr(temptable, tempzone, rr); @@ -2468,39 +2407,35 @@ static int ixfr_data_readnewsoa(struct ixfr_data* data, struct zone* zone, /* read ixfr data old SOA */ static int ixfr_data_readoldsoa(struct ixfr_data* data, struct zone* zone, - FILE* in, const char* ixfrfile, struct region* tempregion, + struct rr *rr, zone_parser_t *parser, struct region* tempregion, struct domain_table* temptable, struct zone* tempzone, uint32_t* dest_serial) { - struct rr* rr; size_t capacity = 0; - if(!ixfr_data_readrr(zone, in, ixfrfile, tempregion, temptable, - tempzone, &rr)) - return 0; if(rr->type != TYPE_SOA) { - log_msg(LOG_ERR, "zone %s ixfr data %s: IXFR data 2nd RR is not SOA", - zone->opts->name, ixfrfile); + zone_error(parser, "zone %s ixfr data: IXFR data 2nd RR is not SOA", + zone->opts->name); return 0; } if(rr->klass != CLASS_IN) { - log_msg(LOG_ERR, "zone %s ixfr data %s: IXFR data 2ndSOA is not class IN", - zone->opts->name, ixfrfile); + zone_error(parser, "zone %s ixfr data: IXFR data 2ndSOA is not class IN", + zone->opts->name); return 0; } if(!zone->apex) { - log_msg(LOG_ERR, "zone %s ixfr data %s: zone has no apex, no zone data", - zone->opts->name, ixfrfile); + zone_error(parser, "zone %s ixfr data: zone has no apex, no zone data", + zone->opts->name); return 0; } if(dname_compare(domain_dname(zone->apex), domain_dname(rr->owner)) != 0) { - log_msg(LOG_ERR, "zone %s ixfr data %s: IXFR data wrong 2nd SOA for zone %s", - zone->opts->name, ixfrfile, domain_to_string(rr->owner)); + zone_error(parser, "zone %s ixfr data: IXFR data wrong 2nd SOA for zone %s", + zone->opts->name, domain_to_string(rr->owner)); return 0; } data->oldserial = soa_rr_get_serial(rr); if(!ixfr_putrr(domain_dname(rr->owner), rr->type, rr->klass, rr->ttl, rr->rdatas, rr->rdata_count, &data->oldsoa, &data->oldsoa_len, &capacity)) { - log_msg(LOG_ERR, "zone %s ixfr data %s: cannot allocate space", - zone->opts->name, ixfrfile); + zone_error(parser, "zone %s ixfr data: cannot allocate space", + zone->opts->name); return 0; } clear_temp_table_of_rr(temptable, tempzone, rr); @@ -2512,76 +2447,166 @@ static int ixfr_data_readoldsoa(struct ixfr_data* data, struct zone* zone, /* read ixfr data del section */ static int ixfr_data_readdel(struct ixfr_data* data, struct zone* zone, - FILE* in, const char* ixfrfile, struct region* tempregion, + struct rr *rr, zone_parser_t *parser, struct region* tempregion, struct domain_table* temptable, struct zone* tempzone) { - struct rr* rr; size_t capacity = 0; - while(1) { - if(!ixfr_data_readrr(zone, in, ixfrfile, tempregion, temptable, - tempzone, &rr)) - return 0; - if(!ixfr_putrr(domain_dname(rr->owner), rr->type, rr->klass, rr->ttl, rr->rdatas, rr->rdata_count, &data->del, &data->del_len, &capacity)) { - log_msg(LOG_ERR, "zone %s ixfr data %s: cannot allocate space", - zone->opts->name, ixfrfile); - return 0; - } - /* check SOA and also serial, because there could be other - * add and del sections from older versions collated, we can - * see this del section end when it has the serial */ - if(rr->type == TYPE_SOA && - soa_rr_get_serial(rr) == data->newserial) { - /* end of del section. */ - clear_temp_table_of_rr(temptable, tempzone, rr); - region_free_all(tempregion); - break; - } - clear_temp_table_of_rr(temptable, tempzone, rr); - region_free_all(tempregion); + if(!ixfr_putrr(domain_dname(rr->owner), rr->type, rr->klass, rr->ttl, rr->rdatas, rr->rdata_count, &data->del, &data->del_len, &capacity)) { + zone_error(parser, "zone %s ixdr data: cannot allocate space", + zone->opts->name); + return 0; + } + clear_temp_table_of_rr(temptable, tempzone, rr); + region_free_all(tempregion); + /* check SOA and also serial, because there could be other + * add and del sections from older versions collated, we can + * see this del section end when it has the serial */ + if(rr->type != TYPE_SOA && soa_rr_get_serial(rr) != data->newserial) { + return 1; } ixfr_trim_capacity(&data->del, &data->del_len, &capacity); - return 1; + return 2; } /* read ixfr data add section */ static int ixfr_data_readadd(struct ixfr_data* data, struct zone* zone, - FILE* in, const char* ixfrfile, struct region* tempregion, + struct rr *rr, zone_parser_t *parser, struct region* tempregion, struct domain_table* temptable, struct zone* tempzone) { - struct rr* rr; size_t capacity = 0; - while(1) { - if(!ixfr_data_readrr(zone, in, ixfrfile, tempregion, temptable, - tempzone, &rr)) - return 0; - if(!ixfr_putrr(domain_dname(rr->owner), rr->type, rr->klass, rr->ttl, rr->rdatas, rr->rdata_count, &data->add, &data->add_len, &capacity)) { - log_msg(LOG_ERR, "zone %s ixfr data %s: cannot allocate space", - zone->opts->name, ixfrfile); - return 0; + if(!ixfr_putrr(domain_dname(rr->owner), rr->type, rr->klass, rr->ttl, rr->rdatas, rr->rdata_count, &data->add, &data->add_len, &capacity)) { + zone_error(parser, "zone %s ixfr data: cannot allocate space", + zone->opts->name); + return 0; + } + clear_temp_table_of_rr(temptable, tempzone, rr); + region_free_all(tempregion); + if(rr->type != TYPE_SOA || soa_rr_get_serial(rr) != data->newserial) { + return 1; + } + ixfr_trim_capacity(&data->add, &data->add_len, &capacity); + return 2; +} + +struct ixfr_data_state { + struct zone *zone; + struct ixfr_data *data; + struct region *tempregion, *stayregion; + struct domain_table *temptable; + struct zone *tempzone; + uint32_t *dest_serial; + size_t rr_count, soa_rr_count; +}; + +/* read one RR from file */ +static int32_t ixfr_data_accept( + zone_parser_t *parser, + const zone_name_t *name, + uint16_t type, + uint16_t class, + uint32_t ttl, + uint16_t rdlength, + const uint8_t *rdata, + void *user_data) +{ + struct rr *rr; + const struct dname *dname; + struct domain *domain; + struct buffer buffer; + union rdata_atom *rdatas; + ssize_t rdata_count; + struct ixfr_data_state *state = (struct ixfr_data_state *)user_data; + + assert(parser); + + buffer_create_from(&buffer, rdata, rdlength); + + dname = dname_make(state->tempregion, name->octets, 1); + assert(dname); + domain = domain_table_insert(state->temptable, dname); + assert(domain); + + rdata_count = rdata_wireformat_to_rdata_atoms( + state->tempregion, state->temptable, type, rdlength, &buffer, &rdatas); + assert(rdata_count > 0); + rr = region_alloc(state->tempregion, sizeof(*rr)); + assert(rr); + rr->owner = domain; + rr->rdatas = rdatas; + rr->ttl = ttl; + rr->type = type; + rr->klass = class; + rr->rdata_count = rdata_count; + + if (state->rr_count == 0) { + if (!ixfr_data_readnewsoa(state->data, state->zone, rr, parser, + state->tempregion, state->temptable, + state->tempzone, *state->dest_serial)) + return ZONE_SEMANTIC_ERROR; + } else if (state->rr_count == 1) { + if(!ixfr_data_readoldsoa(state->data, state->zone, rr, parser, + state->tempregion, state->temptable, + state->tempzone, state->dest_serial)) + return ZONE_SEMANTIC_ERROR; + } else if (state->soa_rr_count == 0) { + switch (ixfr_data_readdel(state->data, state->zone, rr, parser, + state->tempregion, state->temptable, + state->tempzone)) + { + case 0: + return ZONE_SEMANTIC_ERROR; + case 1: + break; + case 2: + state->soa_rr_count++; + break; } - if(rr->type == TYPE_SOA && - soa_rr_get_serial(rr) == data->newserial) { - /* end of add section. */ - clear_temp_table_of_rr(temptable, tempzone, rr); - region_free_all(tempregion); - break; + } else if (state->soa_rr_count == 1) { + switch (ixfr_data_readadd(state->data, state->zone, rr, parser, + state->tempregion, state->temptable, + state->tempzone)) + { + case 0: + return ZONE_SEMANTIC_ERROR; + case 1: + break; + case 2: + state->soa_rr_count++; + break; } - clear_temp_table_of_rr(temptable, tempzone, rr); - region_free_all(tempregion); } - ixfr_trim_capacity(&data->add, &data->add_len, &capacity); - return 1; + + state->rr_count++; + return 0; +} + +static void ixfr_data_log( + zone_parser_t *parser, + uint32_t category, + const char *file, + size_t line, + const char *message, + void *user_data) +{ + int priority = LOG_ERR; + (void)parser; + (void)file; + (void)line; + (void)user_data; + if (category == ZONE_WARNING) + priority = LOG_WARNING; + log_msg(priority, "%s", message); } /* read ixfr data from file */ -static int ixfr_data_read(struct nsd* nsd, struct zone* zone, FILE* in, +static int ixfr_data_read(struct nsd* nsd, struct zone* zone, const char* ixfrfile, uint32_t* dest_serial, int file_num) { - struct ixfr_data* data = NULL; - struct region* tempregion, *stayregion; - struct domain_table* temptable; - struct zone* tempzone; + struct ixfr_data_state state = { 0 }; + if(!zone->apex) { + return 0; + } if(zone->ixfr && zone->ixfr->data->count == zone->opts->pattern->ixfr_number) { VERBOSITY(3, (LOG_INFO, "zone %s skip %s IXFR data because only %d ixfr-number configured", @@ -2592,74 +2617,74 @@ static int ixfr_data_read(struct nsd* nsd, struct zone* zone, FILE* in, /* the file has header comments, new soa, old soa, delsection, * addsection. The delsection and addsection end in a SOA of oldver * and newver respectively. */ - data = xalloc_zero(sizeof(*data)); - data->file_num = file_num; + state.zone = zone; + state.data = xalloc_zero(sizeof(*state.data)); + state.data->file_num = file_num; + state.dest_serial = dest_serial; /* the temp region is cleared after every RR */ - tempregion = region_create(xalloc, free); + state.tempregion = region_create(xalloc, free); /* the stay region holds the temporary data that stays between RRs */ - stayregion = region_create(xalloc, free); - temptable = domain_table_create(stayregion); - tempzone = region_alloc_zero(stayregion, sizeof(zone_type)); + state.stayregion = region_create(xalloc, free); + state.temptable = domain_table_create(state.stayregion); + state.tempzone = region_alloc_zero(state.stayregion, sizeof(*state.tempzone)); if(!zone->apex) { - ixfr_data_free(data); - region_destroy(tempregion); - region_destroy(stayregion); + ixfr_data_free(state.data); + region_destroy(state.tempregion); + region_destroy(state.stayregion); return 0; } - tempzone->apex = domain_table_insert(temptable, + state.tempzone->apex = domain_table_insert(state.temptable, domain_dname(zone->apex)); - temptable->root->usage++; - tempzone->apex->usage++; - tempzone->opts = zone->opts; + state.temptable->root->usage++; + state.tempzone->apex->usage++; + state.tempzone->opts = zone->opts; /* switch to per RR region for new allocations in temp domain table */ - temptable->region = tempregion; - - if(!ixfr_data_readnewsoa(data, zone, in, ixfrfile, tempregion, - temptable, tempzone, *dest_serial)) { - ixfr_data_free(data); - region_destroy(tempregion); - region_destroy(stayregion); - return 0; - } - if(!ixfr_data_readoldsoa(data, zone, in, ixfrfile, tempregion, - temptable, tempzone, dest_serial)) { - ixfr_data_free(data); - region_destroy(tempregion); - region_destroy(stayregion); - return 0; - } - if(!ixfr_data_readdel(data, zone, in, ixfrfile, tempregion, temptable, - tempzone)) { - ixfr_data_free(data); - region_destroy(tempregion); - region_destroy(stayregion); - return 0; - } - if(!ixfr_data_readadd(data, zone, in, ixfrfile, tempregion, temptable, - tempzone)) { - ixfr_data_free(data); - region_destroy(tempregion); - region_destroy(stayregion); - return 0; + state.temptable->region = state.tempregion; + + { + const struct dname *origin; + zone_parser_t parser; + zone_options_t options; + zone_name_buffer_t name_buffer; + zone_rdata_buffer_t rdata_buffer; + zone_buffers_t buffers = { 1, &name_buffer, &rdata_buffer }; + memset(&options, 0, sizeof(options)); + + origin = domain_dname(zone->apex); + options.origin.octets = dname_name(origin); + options.origin.length = origin->name_size; + options.no_includes = true; + options.pretty_ttls = false; + options.default_ttl = DEFAULT_TTL; + options.default_class = CLASS_IN; + options.log.callback = &ixfr_data_log; + options.accept.callback = &ixfr_data_accept; + + if(zone_parse(&parser, &options, &buffers, ixfrfile, &state) != 0) { + ixfr_data_free(state.data); + region_destroy(state.tempregion); + region_destroy(state.stayregion); + return 0; + } } - region_destroy(tempregion); - region_destroy(stayregion); + region_destroy(state.tempregion); + region_destroy(state.stayregion); if(!zone->ixfr) zone->ixfr = zone_ixfr_create(nsd); if(zone->opts->pattern->ixfr_size != 0 && - zone->ixfr->total_size + ixfr_data_size(data) > + zone->ixfr->total_size + ixfr_data_size(state.data) > zone->opts->pattern->ixfr_size) { VERBOSITY(3, (LOG_INFO, "zone %s skip %s IXFR data because only ixfr-size: %u configured, and it is %u size", - zone->opts->name, ixfrfile, (unsigned)zone->opts->pattern->ixfr_size, (unsigned)ixfr_data_size(data))); - ixfr_data_free(data); + zone->opts->name, ixfrfile, (unsigned)zone->opts->pattern->ixfr_size, (unsigned)ixfr_data_size(state.data))); + ixfr_data_free(state.data); return 0; } - zone_ixfr_add(zone->ixfr, data, 0); + zone_ixfr_add(zone->ixfr, state.data, 0); VERBOSITY(3, (LOG_INFO, "zone %s read %s IXFR data of %u bytes", - zone->opts->name, ixfrfile, (unsigned)ixfr_data_size(data))); + zone->opts->name, ixfrfile, (unsigned)ixfr_data_size(state.data))); return 1; } @@ -2669,27 +2694,13 @@ static int ixfr_read_one_more_file(struct nsd* nsd, struct zone* zone, const char* zfile, int num_files, uint32_t *dest_serial) { char ixfrfile[1024+24]; - FILE* in; + struct stat statbuf; int file_num = num_files+1; make_ixfr_name(ixfrfile, sizeof(ixfrfile), zfile, file_num); - in = fopen(ixfrfile, "r"); - if(!in) { - if(errno == ENOENT) { - /* the file does not exist, we reached the end - * of the list of IXFR files */ - return 0; - } - log_msg(LOG_ERR, "could not read zone %s IXFR file %s: %s", - zone->opts->name, ixfrfile, strerror(errno)); + /* if the file does not exist, all transfers have been read */ + if (stat(ixfrfile, &statbuf) != 0 && errno == ENOENT) return 0; - } - warn_if_directory("IXFR data", in, ixfrfile); - if(!ixfr_data_read(nsd, zone, in, ixfrfile, dest_serial, file_num)) { - fclose(in); - return 0; - } - fclose(in); - return 1; + return ixfr_data_read(nsd, zone, ixfrfile, dest_serial, file_num); } void ixfr_read_from_file(struct nsd* nsd, struct zone* zone, const char* zfile) diff --git a/netio.h b/netio.h index 485435248..fc7f74c44 100644 --- a/netio.h +++ b/netio.h @@ -174,17 +174,4 @@ int netio_dispatch(netio_type *netio, const struct timespec *timeout, const sigset_t *sigmask); - -#ifdef __cplusplus -inline netio_event_types_type -operator | (netio_event_types_type lhs, netio_event_types_type rhs) { - return (netio_event_types_type) (lhs | rhs); -} -inline netio_event_types_type -operator |= (netio_event_types_type &lhs, netio_event_types_type rhs) { - lhs = (netio_event_types_type) (lhs | rhs); - return lhs; -} -#endif /* __cplusplus */ - #endif /* NETIO_H */ diff --git a/nsd-checkzone.c b/nsd-checkzone.c index e12f5931d..fd8cbaeb2 100644 --- a/nsd-checkzone.c +++ b/nsd-checkzone.c @@ -67,7 +67,7 @@ check_zone(struct nsd* nsd, const char* name, const char* fname, FILE *out, zone = namedb_zone_create(nsd->db, dname, zo); if(oldzone) { - errors = zonec_read(name, oldzone, zone); + errors = zonec_read(nsd->db, nsd->db->domains, name, oldzone, zone); if(errors > 0) { printf("zone %s file %s has %u errors\n", name, oldzone, errors); exit(1); @@ -80,7 +80,7 @@ check_zone(struct nsd* nsd, const char* name, const char* fname, FILE *out, } /* read the zone */ - errors = zonec_read(name, fname, zone); + errors = zonec_read(nsd->db, nsd->db->domains, name, fname, zone); if(errors > 0) { printf("zone %s file %s has %u errors\n", name, fname, errors); ixfr_create_cancel(ixfrcr); diff --git a/simdzone b/simdzone new file mode 160000 index 000000000..568448bc7 --- /dev/null +++ b/simdzone @@ -0,0 +1 @@ +Subproject commit 568448bc7436cd48093c95caed12650a4881e230 diff --git a/tpkg/cutest/cutest_namedb.c b/tpkg/cutest/cutest_namedb.c index 173cbf166..4b313ca57 100644 --- a/tpkg/cutest/cutest_namedb.c +++ b/tpkg/cutest/cutest_namedb.c @@ -21,6 +21,7 @@ #include "difffile.h" #include "zonec.h" #include "nsd.h" +#include "zone.h" static void namedb_1(CuTest *tc); static void namedb_2(CuTest *tc); @@ -555,31 +556,105 @@ check_namedb(CuTest *tc, namedb_type* db) check_walkdomains(tc, db); } +struct parse_rr_state { + size_t errors; + struct region *region; + const struct dname *owner; + uint16_t type; + uint16_t class; + uint32_t ttl; + uint16_t rdlength; + uint8_t rdata[MAX_RDLENGTH]; +}; + +/** parse a string into temporary storage */ +static int32_t parse_rr_accept( + zone_parser_t *parser, + const zone_name_t *owner, + uint16_t type, + uint16_t class, + uint32_t ttl, + uint16_t rdlength, + const uint8_t *rdata, + void *user_data) +{ + struct parse_rr_state *state = (struct parse_rr_state *)user_data; + + assert(state); + + (void)parser; + + assert(state->owner == NULL); + state->owner = dname_make(state->region, owner->octets, 1); + assert(state->owner != NULL); + state->type = type; + state->class = class; + state->ttl = ttl; + state->rdlength = rdlength; + memcpy(&state->rdata, rdata, rdlength); + return 0; +} + +static void parse_rr_log( + zone_parser_t *parser, + uint32_t category, + const char *file, + size_t line, + const char *message, + void *user_data) +{ + struct parse_rr_state *state = (struct parse_rr_state *)user_data; + + assert(state); + + (void)parser; + (void)category; + (void)file; + (void)line; + (void)message; + + assert(state->owner == NULL); + state->errors++; + return; +} + /* parse string into parts */ static int -parse_rr_str(region_type* temp, zone_type* zone, char* str, - rr_type** rr) +parse_rr_str(struct zone *zone, char *input, struct parse_rr_state *state) { - domain_table_type* temptable; - zone_type* tempzone; - domain_type* parsed = NULL; - int num_rrs = 0; - - temptable = domain_table_create(temp); - tempzone = region_alloc_zero(temp, sizeof(zone_type)); - tempzone->apex = domain_table_insert(temptable, - domain_dname(zone->apex)); - tempzone->opts = zone->opts; - - if(zonec_parse_string(temp, temptable, tempzone, str, &parsed, - &num_rrs)) { - return 0; - } - if(num_rrs != 1) { - return 0; - } - *rr = &parsed->rrsets->rrs[0]; - return 1; + int32_t code; + size_t length; + char *string; + const struct dname *origin; + zone_parser_t parser; + zone_options_t options; + zone_name_buffer_t name_buffer; + zone_rdata_buffer_t rdata_buffer; + zone_buffers_t buffers = { 1, &name_buffer, &rdata_buffer }; + + /* the temp region is cleared after every RR */ + memset(&options, 0, sizeof(options)); + + origin = domain_dname(zone->apex); + options.origin.octets = dname_name(origin); + options.origin.length = origin->name_size; + options.no_includes = true; + options.pretty_ttls = false; + options.default_ttl = DEFAULT_TTL; + options.default_class = CLASS_IN; + options.log.callback = &parse_rr_log; + options.accept.callback = &parse_rr_accept; + + length = strlen(input); + string = malloc(length + 1 + ZONE_BLOCK_SIZE); + memcpy(string, input, length); + string[length] = 0; + + /* Parse and process all RRs. */ + code = zone_parse_string(&parser, &options, &buffers, string, length, state); + free(string); + + return state->errors == 0 && code == 0; } /** find zone in namebd from string */ @@ -602,50 +677,48 @@ find_zone(namedb_type* db, char* z) static void add_str(namedb_type* db, zone_type* zone, char* str) { - region_type* temp = region_create(xalloc, free); - uint8_t rdata[MAX_RDLENGTH]; - size_t rdatalen; - buffer_type databuffer; + struct buffer buffer; + struct parse_rr_state state; int softfail = 0; - rr_type* rr; if(v) printf("add_str %s\n", str); - if(!parse_rr_str(temp, zone, str, &rr)) { + memset(&state, 0, sizeof(state)); + state.region = region_create(xalloc, free); + state.owner = NULL; + if(!parse_rr_str(zone, str, &state)) { printf("cannot parse RR: %s\n", str); exit(1); } - rdatalen = rr_marshal_rdata(rr, rdata, sizeof(rdata)); - buffer_create_from(&databuffer, rdata, rdatalen); - if(!add_RR(db, domain_dname(rr->owner), rr->type, rr->klass, rr->ttl, - &databuffer, rdatalen, zone, &softfail)) { + buffer_create_from(&buffer, state.rdata, state.rdlength); + if(!add_RR(db, state.owner, state.type, state.class, state.ttl, + &buffer, state.rdlength, zone, &softfail)) { printf("cannot add RR: %s\n", str); exit(1); } - region_destroy(temp); + region_destroy(state.region); } /* del an RR from string */ static void del_str(namedb_type* db, zone_type* zone, char* str) { - region_type* temp = region_create(xalloc, free); - uint8_t rdata[MAX_RDLENGTH]; - size_t rdatalen; - buffer_type databuffer; + struct buffer buffer; + struct parse_rr_state state; int softfail = 0; - rr_type* rr; if(v) printf("del_str %s\n", str); - if(!parse_rr_str(temp, zone, str, &rr)) { + memset(&state, 0, sizeof(state)); + state.region = region_create(xalloc, free); + state.owner = NULL; + if(!parse_rr_str(zone, str, &state)) { printf("cannot parse RR: %s\n", str); exit(1); } - rdatalen = rr_marshal_rdata(rr, rdata, sizeof(rdata)); - buffer_create_from(&databuffer, rdata, rdatalen); - if(!delete_RR(db, domain_dname(rr->owner), rr->type, rr->klass, - &databuffer, rdatalen, zone, temp, &softfail)) { + buffer_create_from(&buffer, state.rdata, state.rdlength); + if(!delete_RR(db, state.owner, state.type, state.class, + &buffer, state.rdlength, zone, state.region, &softfail)) { printf("cannot delete RR: %s\n", str); exit(1); } - region_destroy(temp); + region_destroy(state.region); } /* test the namedb, and add, remove items from it */ diff --git a/tpkg/rr-test.tdir/rr-test.zone b/tpkg/rr-test.tdir/rr-test.zone index e7047cac7..70e0074da 100644 --- a/tpkg/rr-test.tdir/rr-test.zone +++ b/tpkg/rr-test.tdir/rr-test.zone @@ -67,7 +67,7 @@ $ORIGIN blaat.nl. $ORIGIN blaat.nl. -dotted\.label IN MX 10 "foo bar.nl" +dotted\.label IN MX 10 foo\ bar\.nl low.low.low IN DNAME rt-host diff --git a/tpkg/soa_test.tdir/soa_test.test b/tpkg/soa_test.tdir/soa_test.test index e4731e59c..752a53012 100644 --- a/tpkg/soa_test.tdir/soa_test.test +++ b/tpkg/soa_test.tdir/soa_test.test @@ -14,6 +14,7 @@ if dig @127.0.0.1 -p $RND_PORT example1.com SOA | grep NOERROR; then echo OK else echo fail + cat nsd.log kill_from_pidfile nsd.pid exit 1 fi @@ -22,6 +23,7 @@ if dig @127.0.0.1 -p $RND_PORT example2.com SOA | grep NOERROR; then echo OK else echo fail + cat nsd.log kill_from_pidfile nsd.pid exit 1 fi @@ -30,6 +32,7 @@ if dig @127.0.0.1 -p $RND_PORT example3.com SOA | grep NOERROR; then echo OK else echo fail + cat nsd.log kill_from_pidfile nsd.pid exit 1 fi @@ -38,6 +41,7 @@ if dig @127.0.0.1 -p $RND_PORT example4.com SOA | grep NOERROR; then echo OK else echo fail + cat nsd.log kill_from_pidfile nsd.pid exit 1 fi @@ -46,6 +50,7 @@ if dig @127.0.0.1 -p $RND_PORT example5.com SOA | grep NOERROR; then echo OK else echo fail + cat nsd.log kill_from_pidfile nsd.pid exit 1 fi diff --git a/tpkg/soa_test.tdir/soa_test.zone5 b/tpkg/soa_test.tdir/soa_test.zone5 index ec9322f03..308e450bc 100644 --- a/tpkg/soa_test.tdir/soa_test.zone5 +++ b/tpkg/soa_test.tdir/soa_test.zone5 @@ -1,5 +1,5 @@ $TTL 1H - IN SOA elektron.atoom.net. miekg.atoom.net. ( +@ IN SOA elektron.atoom.net. miekg.atoom.net. ( 2002120700 ; Serial 6H ; Refresh 2H ; Retry diff --git a/tpkg/svcb.tdir/svcb.success-cases.zone b/tpkg/svcb.tdir/svcb.success-cases.zone index e8cfeaba9..16dfebe19 100644 --- a/tpkg/svcb.tdir/svcb.success-cases.zone +++ b/tpkg/svcb.tdir/svcb.success-cases.zone @@ -22,23 +22,27 @@ s03 HTTPS 0 . alpn="h2,h3" no-default-alpn ; SHOULD is not MUST (so allowed) ; Zone-file implementations SHOULD enforce self-consistency - -s04 HTTPS 0 . no-default-alpn +; +; disabled, simdzone enforces self-consistency (unless secondary) +;s04 HTTPS 0 . no-default-alpn ; SHOULD is not MUST (so allowed) ; (port and no-default-alpn are automatically mandatory keys with HTTPS) ; Other automatically mandatory keys SHOULD NOT appear in the list either. - -s05 HTTPS 0 . alpn="dot" no-default-alpn port=853 mandatory=port +; +; disabled, simdzone enforces self-consistency (unless secondary) +;s05 HTTPS 0 . alpn="dot" no-default-alpn port=853 mandatory=port ; Any valid base64 is okay for ech s06 HTTPS 0 . ech="aGVsbG93b3JsZCE=" ; echconfig is an alias for ech -s07 HTTPS 0 . echconfig="aGVsbG93b3JsZCE=" +; +; disabled, echconfig is not registered with IANA +;s07 HTTPS 0 . echconfig="aGVsbG93b3JsZCE=" ; dohpath can be (non-)quoted s08 HTTPS 0 . alpn=h2 dohpath="/dns-query{?dns}" -s09 HTTPS 0 . alpn=h2 dohpath=/dns-query{é?dns} \ No newline at end of file +s09 HTTPS 0 . alpn=h2 dohpath=/dns-query{é?dns} diff --git a/tpkg/svcb.tdir/svcb.success-cases.zone.cmp b/tpkg/svcb.tdir/svcb.success-cases.zone.cmp index d7d628067..966eb3bde 100644 --- a/tpkg/svcb.tdir/svcb.success-cases.zone.cmp +++ b/tpkg/svcb.tdir/svcb.success-cases.zone.cmp @@ -5,10 +5,7 @@ $ORIGIN success-cases. s01 3600 IN SVCB 0 . key123 s02 3600 IN SVCB 0 . ech s03 3600 IN HTTPS 0 . alpn="h2,h3" no-default-alpn -s04 3600 IN HTTPS 0 . no-default-alpn -s05 3600 IN HTTPS 0 . mandatory=port alpn="dot" no-default-alpn port=853 s06 3600 IN HTTPS 0 . ech=aGVsbG93b3JsZCE= -s07 3600 IN HTTPS 0 . ech=aGVsbG93b3JsZCE= s08 3600 IN HTTPS 0 . alpn="h2" dohpath="/dns-query{?dns}" s09 3600 IN HTTPS 0 . alpn="h2" dohpath="/dns-query{\195\169?dns}" ; zone success-cases is ok diff --git a/tpkg/zonec_tests.tdir/zonec_tests.test b/tpkg/zonec_tests.tdir/zonec_tests.test index adacbbba0..f9f3408de 100644 --- a/tpkg/zonec_tests.tdir/zonec_tests.test +++ b/tpkg/zonec_tests.tdir/zonec_tests.test @@ -42,7 +42,7 @@ fi cat nsd.log if grep "read with 2 errors" nsd.log && \ grep "zonec_tests.fail:3: only class IN is supported" nsd.log && - grep "zonec_tests.fail:4: invalid TTL value" nsd.log; then + grep "zonec_tests.fail:4: Invalid ttl in $TTL" nsd.log; then echo "errors checked ok" else echo "bad errors" @@ -62,7 +62,7 @@ if dig @127.0.0.1 -p $RND_PORT miek.nl SOA | grep NOERROR; then fi cat nsd.log if grep "read with 1 errors" nsd.log && \ - grep "zonec_tests.offbyone:13: domain name exceeds 255 character limit" nsd.log; then + grep "zonec_tests.offbyone:13: Invalid OWNER in RR" nsd.log; then echo "errors checked ok" else echo "bad errors" diff --git a/util.c b/util.c index 13a2ec9b4..f8107c844 100644 --- a/util.c +++ b/util.c @@ -508,113 +508,6 @@ timespec_subtract(struct timespec *left, } } -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': - if((i*10)/10 != i) - /* number too large, return i - * with *endptr != 0 as a failure*/ - return i; - i *= 10; - i += (**endptr - '0'); - break; - default: - return 0; - } - } - serial += i; - return serial; -} - -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; - /** - * According to RFC2308, Section 8, the MSB - * (sign bit) should be set to zero. - * If we encounter a value larger than 2^31 -1, - * we fall back to the default TTL. - */ - if ((seconds & MSB_32)) { - seconds = DEFAULT_TTL; - } - return seconds; - } - } - seconds += i; - if ((seconds & MSB_32)) { - seconds = DEFAULT_TTL; - } - return seconds; -} - - ssize_t hex_ntop(uint8_t const *src, size_t srclength, char *target, size_t targsize) { @@ -822,53 +715,6 @@ hexdigit_to_int(char ch) } } -/* 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; -} - /* code to calculate CRC. Lifted from BSD 4.4 crc.c in cksum(1). BSD license. http://www.tsfr.org/~orc/Code/bsd/bsd-current/cksum/crc.c. or http://gobsd.com/code/freebsd/usr.bin/cksum/crc.c diff --git a/util.h b/util.h index ab6315edf..6cb73233f 100644 --- a/util.h +++ b/util.h @@ -321,25 +321,6 @@ timeval_to_timespec(struct timespec *left, /* get the time */ void get_time(struct timespec* t); -/* - * Converts a string representation of a period of time into - * a long integer of seconds or serial value. - * - * Set the endptr to the first illegal character. - * - * Interface is similar as strtol(3) - * - * Returns: - * LONG_MIN if underflow occurs - * LONG_MAX if overflow occurs. - * otherwise number of seconds - * - * XXX These functions do not check the range. - * - */ -uint32_t strtoserial(const char *nptr, const char **endptr); -uint32_t strtottl(const char *nptr, const char **endptr); - /* * Convert binary data to a string of hexadecimal characters. */ @@ -365,12 +346,6 @@ void strip_string(char *str); */ int hexdigit_to_int(char ch); -/* - * Convert TM to seconds since epoch (midnight, January 1st, 1970). - * Like timegm(3), which is not always available. - */ -time_t mktime_from_utc(const struct tm *tm); - /* * Add bytes to given crc. Returns new CRC sum. * Start crc val with 0xffffffff on first call. XOR crc with diff --git a/xfrd-catalog-zones.c b/xfrd-catalog-zones.c index bc0baa078..aca612a5a 100644 --- a/xfrd-catalog-zones.c +++ b/xfrd-catalog-zones.c @@ -1111,8 +1111,8 @@ xfr_writer_init(struct xfrd_xfr_writer* xw, struct xfrd_catalog_producer_zone* producer_zone) { xw->producer_zone = producer_zone; - buffer_create_from( &xw->packet, &xw->packet_space - , sizeof(xw->packet_space)); + memset(&xw->packet, 0, sizeof(xw->packet)); + buffer_create_from(&xw->packet, xw->packet_space, sizeof(xw->packet_space)); buffer_write(&xw->packet, "\000\000\000\000\000\000" "\000\000\000\000\000\000", 12); /* header */ xw->seq_nr = 0; diff --git a/zlexer.lex b/zlexer.lex deleted file mode 100644 index fb6eadf07..000000000 --- a/zlexer.lex +++ /dev/null @@ -1,451 +0,0 @@ -%{ -/* - * zlexer.lex - lexical analyzer for (DNS) zone files - * - * Copyright (c) 2001-2006, NLnet Labs. All rights reserved - * - * See LICENSE for the license. - * - */ -/* because flex keeps having sign-unsigned compare problems that are unfixed*/ -#if defined(__clang__)||(defined(__GNUC__)&&((__GNUC__ >4)||(defined(__GNUC_MINOR__)&&(__GNUC__ ==4)&&(__GNUC_MINOR__ >=2)))) -#pragma GCC diagnostic ignored "-Wsign-compare" -#endif -/* ignore fallthrough warnings in the generated parse code case statements */ -#if defined(__clang__)||(defined(__GNUC__)&&(__GNUC__ >=7)) -#pragma GCC diagnostic ignored "-Wimplicit-fallthrough" -#endif - -#include "config.h" - -#include -#include -#include -#include - -#include "zonec.h" -#include "dname.h" -#include "zparser.h" - -#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 int parse_token(int token, char *yytext, enum lexer_state *lexer_state); - -static YY_BUFFER_STATE include_stack[MAXINCLUDES]; -static zparser_type zparser_stack[MAXINCLUDES]; -static int include_stack_ptr = 0; - -/* - * Saves the file specific variables on the include stack. - */ -static void -push_parser_state(FILE *input) -{ - 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)); - ++include_stack_ptr; -} - -/* - * Restores the file specific variables from the include stack. - */ -static void -pop_parser_state(void) -{ - if (parser->filename) - region_recycle(parser->region, (void *)parser->filename, - strlen(parser->filename)+1); - - --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); - yy_switch_to_buffer(include_stack[include_stack_ptr]); -} - -static YY_BUFFER_STATE oldstate; -/* Start string scan */ -void -parser_push_stringbuf(char* str) -{ - oldstate = YY_CURRENT_BUFFER; - yy_switch_to_buffer(yy_scan_string(str)); -} - -void -parser_pop_stringbuf(void) -{ - yy_delete_buffer(YY_CURRENT_BUFFER); - yy_switch_to_buffer(oldstate); - oldstate = NULL; -} - - static int paren_open = 0; - static enum lexer_state lexer_state = EXPECT_OWNER; -void -parser_flush(void) -{ - YY_FLUSH_BUFFER; - paren_open = 0; - lexer_state = EXPECT_OWNER; -} - -int at_eof(void) -{ - static int once = 1; - return (once = !once) ? 0 : NL; -} - -#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 noinput -%option nounput -%{ -#ifndef YY_NO_UNPUT -#define YY_NO_UNPUT 1 -#endif -#ifndef YY_NO_INPUT -#define YY_NO_INPUT 1 -#endif -%} - -SPACE [ \t] -LETTER [a-zA-Z] -NEWLINE [\n\r] -ZONESTR [^ \t\n\r();.\"\$]|\\.|\\\n -CHARSTR [^ \t\n\r();.\"]|\\.|\\\n -QUOTE \" -DOLLAR \$ -COMMENT ; -DOT \. -BIT [^\]\n]|\\. -ANY [^\"\n\\]|\\. - -%x incl bitlabel quotedstring - -%% -{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); - /* ignore case statement fallthrough on incl flex rule */ -} -\n | -<> { - 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; -} -.+ { - char *tmp; - 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) { - const dname_type *dname; - - /* split the original yytext */ - *tmp = '\0'; - strip_string(yytext); - - dname = dname_parse(parser->region, tmp + 1); - if (!dname) { - zc_error("incorrect include origin '%s'", - tmp + 1); - } else if (*(tmp + strlen(tmp + 1)) != '.') { - zc_error("$INCLUDE directive requires absolute domain name"); - } else { - 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"))) { - zc_error("cannot open include file '%s': %s", - yytext, strerror(errno)); - } else { - /* Initialize parser for include file. */ - char *filename = region_strdup(parser->region, yytext); - push_parser_state(input); /* Destroys yytext. */ - parser->filename = filename; - parser->line = 1; - parser->origin = origin; - lexer_state = EXPECT_OWNER; - } - } - - parser->error_occurred = error_occurred; -} -<> { - int eo = at_eof(); - yy_set_bol(1); /* Set beginning of line, so "^" rules match. */ - if (include_stack_ptr == 0) { - if(eo == NL) - return eo; - yyterminate(); - } else { - fclose(yyin); - pop_parser_state(); - if(eo == NL) - return eo; - } -} -^{DOLLAR}{LETTER}+ { zc_warning("Unknown directive: %s", yytext); } -{DOT} { - LEXOUT((". ")); - return parse_token('.', yytext, &lexer_state); -} -@ { - LEXOUT(("@ ")); - return parse_token('@', yytext, &lexer_state); -} -\\# { - LEXOUT(("\\# ")); - return parse_token(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); } -<> { - zc_error("EOF inside bitlabel"); - BEGIN(INITIAL); - yyrestart(yyin); /* this is so that lex does not give an internal err */ - yyterminate(); -} -{BIT}* { yymore(); } -\n { ++parser->line; yymore(); } -\] { - BEGIN(INITIAL); - yytext[yyleng - 1] = '\0'; - return parse_token(BITLAB, yytext, &lexer_state); -} - - /* Quoted strings. Strip leading and ending quotes. */ -{QUOTE} { BEGIN(quotedstring); LEXOUT(("\" ")); } -<> { - zc_error("EOF inside quoted string"); - BEGIN(INITIAL); - yyrestart(yyin); /* this is so that lex does not give an internal err */ - yyterminate(); -} -{ANY}* { LEXOUT(("QSTR ")); yymore(); } -\n { ++parser->line; yymore(); } -{QUOTE} { - LEXOUT(("\" ")); - BEGIN(INITIAL); - yytext[yyleng - 1] = '\0'; - return parse_token(QSTR, yytext, &lexer_state); -} - -{ZONESTR}({CHARSTR})* { - /* Any allowed word. */ - return parse_token(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 = rrtype_from_string(word); - if (t != 0) { - rrtype_descriptor_type *entry = rrtype_descriptor_by_type(t); - *type = t; - 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((unsigned char)s[1]) && isdigit((unsigned char)s[2]) && isdigit((unsigned char)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(int token, char *yytext, enum lexer_state *lexer_state) -{ - size_t len; - char *str; - - 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(yytext, &yylval.type); - if (token != 0) { - *lexer_state = PARSING_RDATA; - LEXOUT(("%d[%s] ", token, yytext)); - return token; - } - - /* class */ - rrclass = rrclass_from_string(yytext); - if (rrclass != 0) { - yylval.klass = rrclass; - LEXOUT(("CLASS ")); - return T_RRCLASS; - } - - /* ttl */ - yylval.ttl = strtottl(yytext, &t); - if (*t == '\0') { - LEXOUT(("TTL ")); - return T_TTL; - } - } - - str = region_strdup(parser->rr_region, yytext); - len = zoctet(str); - - yylval.data.str = str; - yylval.data.len = len; - - LEXOUT(("%d[%s] ", token, yytext)); - return token; -} diff --git a/zonec.c b/zonec.c index e868405da..3601994fe 100644 --- a/zonec.c +++ b/zonec.c @@ -9,6 +9,7 @@ #include "config.h" +#include #include #include #include @@ -21,7 +22,6 @@ #endif #include #include -#include #ifdef HAVE_SYS_STAT_H #include #endif @@ -40,1819 +40,9 @@ #include "rdata.h" #include "region-allocator.h" #include "util.h" -#include "zparser.h" #include "options.h" #include "nsec3.h" - -#define ILNP_MAXDIGITS 4 -#define ILNP_NUMGROUPS 4 -#define SVCB_MAX_COMMA_SEPARATED_VALUES 1000 - - -const dname_type *error_dname; -domain_type *error_domain; - -static time_t startzonec = 0; -static long int totalrrs = 0; - -extern uint8_t nsecbits[NSEC_WINDOW_COUNT][NSEC_WINDOW_BITS_SIZE]; -extern uint16_t nsec_highest_rcode; - - -/* - * Allocate SIZE+sizeof(uint16_t) bytes and store SIZE in the first - * element. Return a pointer to the allocation. - */ -static uint16_t * -alloc_rdata(region_type *region, size_t size) -{ - uint16_t *result = region_alloc(region, sizeof(uint16_t) + size); - *result = size; - return result; -} - -uint16_t * -alloc_rdata_init(region_type *region, const void *data, size_t size) -{ - uint16_t *result = region_alloc(region, sizeof(uint16_t) + size); - *result = size; - memcpy(result + 1, data, size); - return result; -} - -/* - * These are parser function for generic zone file stuff. - */ -uint16_t * -zparser_conv_hex(region_type *region, const char *hex, size_t len) -{ - /* convert a hex value to wireformat */ - uint16_t *r = NULL; - uint8_t *t; - int i; - - if(len == 1 && hex[0] == '0') { - /* single 0 represents empty buffer */ - return alloc_rdata(region, 0); - } - if (len % 2 != 0) { - zc_error_prev_line("number of hex digits must be a multiple of 2"); - } else if (len > MAX_RDLENGTH * 2) { - zc_error_prev_line("hex data exceeds maximum rdata length (%d)", - MAX_RDLENGTH); - } else { - /* the length part */ - r = alloc_rdata(region, len/2); - t = (uint8_t *)(r + 1); - - /* Now process octet by octet... */ - while (*hex) { - *t = 0; - for (i = 16; i >= 1; i -= 15) { - if (isxdigit((unsigned char)*hex)) { - *t += hexdigit_to_int(*hex) * i; - } else { - zc_error_prev_line( - "illegal hex character '%c'", - (int) *hex); - return NULL; - } - ++hex; - } - ++t; - } - } - return r; -} - -/* convert hex, precede by a 1-byte length */ -uint16_t * -zparser_conv_hex_length(region_type *region, 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"); - } else if (len > 255 * 2) { - zc_error_prev_line("hex data exceeds 255 bytes"); - } else { - uint8_t *l; - - /* the length part */ - r = alloc_rdata(region, len/2+1); - 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((unsigned char)*hex)) { - *t += hexdigit_to_int(*hex) * i; - } else { - zc_error_prev_line( - "illegal hex character '%c'", - (int) *hex); - return NULL; - } - ++hex; - } - ++t; - ++*l; - } - } - return r; -} - -uint16_t * -zparser_conv_time(region_type *region, 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"); - } else { - uint32_t l = htonl(mktime_from_utc(&tm)); - r = alloc_rdata_init(region, &l, sizeof(l)); - } - return r; -} - -uint16_t * -zparser_conv_services(region_type *region, 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); - return NULL; - } - - for (word = strtok(servicestr, sep); word; word = strtok(NULL, sep)) { - struct servent *service; - int port; - - service = getservbyname(word, proto->p_name); - if (service) { - /* Note: ntohs not ntohl! Strange but true. */ - port = ntohs((uint16_t) service->s_port); - } else { - char *end; - port = strtol(word, &end, 10); - if (*end != '\0') { - zc_error_prev_line("unknown service '%s' for protocol '%s'", - word, protostr); - continue; - } - } - - 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; - } - } - - r = alloc_rdata(region, sizeof(uint8_t) + max_port / 8 + 1); - p = (uint8_t *) (r + 1); - *p = proto->p_proto; - memcpy(p + 1, bitmap, *r-1); - - return r; -} - -uint16_t * -zparser_conv_serial(region_type *region, 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 or serial too big"); - } else { - serial = htonl(serial); - r = alloc_rdata_init(region, &serial, sizeof(serial)); - } - return r; -} - -uint16_t * -zparser_conv_period(region_type *region, 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"); - } else { - period = htonl(period); - r = alloc_rdata_init(region, &period, sizeof(period)); - } - return r; -} - -uint16_t * -zparser_conv_short(region_type *region, 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"); - } else { - r = alloc_rdata_init(region, &value, sizeof(value)); - } - return r; -} - -uint16_t * -zparser_conv_byte(region_type *region, 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"); - } else { - r = alloc_rdata_init(region, &value, sizeof(value)); - } - return r; -} - -uint16_t * -zparser_conv_algorithm(region_type *region, const char *text) -{ - const lookup_table_type *alg; - uint8_t id; - - alg = 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"); - return NULL; - } - } - - return alloc_rdata_init(region, &id, sizeof(id)); -} - -uint16_t * -zparser_conv_certificate_type(region_type *region, const char *text) -{ - /* convert an algorithm string to integer */ - const lookup_table_type *type; - uint16_t id; - - type = 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"); - return NULL; - } - } - - return alloc_rdata_init(region, &id, sizeof(id)); -} - -uint16_t * -zparser_conv_a(region_type *region, 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); - } else { - r = alloc_rdata_init(region, &address, sizeof(address)); - } - return r; -} - -uint16_t * -zparser_conv_aaaa(region_type *region, 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); - } else { - r = alloc_rdata_init(region, address, sizeof(address)); - } - return r; -} - - -uint16_t * -zparser_conv_ilnp64(region_type *region, const char *text) -{ - uint16_t *r = NULL; - int ngroups, num; - unsigned long hex; - const char *ch; - char digits[ILNP_MAXDIGITS+1]; - unsigned int ui[ILNP_NUMGROUPS]; - uint16_t a[ILNP_NUMGROUPS]; - - ngroups = 1; /* Always at least one group */ - num = 0; - for (ch = text; *ch != '\0'; ch++) { - if (*ch == ':') { - if (num <= 0) { - zc_error_prev_line("ilnp64: empty group of " - "digits is not allowed"); - return NULL; - } - digits[num] = '\0'; - hex = (unsigned long) strtol(digits, NULL, 16); - num = 0; - ui[ngroups - 1] = hex; - if (ngroups >= ILNP_NUMGROUPS) { - zc_error_prev_line("ilnp64: more than %d groups " - "of digits", ILNP_NUMGROUPS); - return NULL; - } - ngroups++; - } else { - /* Our grammar is stricter than the one accepted by - * strtol. */ - if (!isxdigit((unsigned char)*ch)) { - zc_error_prev_line("ilnp64: invalid " - "(non-hexadecimal) character %c", *ch); - return NULL; - } - if (num >= ILNP_MAXDIGITS) { - zc_error_prev_line("ilnp64: more than %d digits " - "in a group", ILNP_MAXDIGITS); - return NULL; - } - digits[num++] = *ch; - } - } - if (num <= 0) { - zc_error_prev_line("ilnp64: empty group of digits is not " - "allowed"); - return NULL; - } - digits[num] = '\0'; - hex = (unsigned long) strtol(digits, NULL, 16); - ui[ngroups - 1] = hex; - if (ngroups < 4) { - zc_error_prev_line("ilnp64: less than %d groups of digits", - ILNP_NUMGROUPS); - return NULL; - } - - a[0] = htons(ui[0]); - a[1] = htons(ui[1]); - a[2] = htons(ui[2]); - a[3] = htons(ui[3]); - r = alloc_rdata_init(region, a, sizeof(a)); - return r; -} - -static uint16_t * -zparser_conv_eui48(region_type *region, const char *text) -{ - uint8_t nums[6]; - uint16_t *r = NULL; - unsigned int a, b, c, d, e, f; - int l; - - if (sscanf(text, "%2x-%2x-%2x-%2x-%2x-%2x%n", - &a, &b, &c, &d, &e, &f, &l) != 6 || - l != (int)strlen(text)){ - zc_error_prev_line("eui48: invalid rr"); - return NULL; - } - nums[0] = (uint8_t)a; - nums[1] = (uint8_t)b; - nums[2] = (uint8_t)c; - nums[3] = (uint8_t)d; - nums[4] = (uint8_t)e; - nums[5] = (uint8_t)f; - r = alloc_rdata_init(region, nums, sizeof(nums)); - return r; -} - -static uint16_t * -zparser_conv_eui64(region_type *region, const char *text) -{ - uint8_t nums[8]; - uint16_t *r = NULL; - unsigned int a, b, c, d, e, f, g, h; - int l; - if (sscanf(text, "%2x-%2x-%2x-%2x-%2x-%2x-%2x-%2x%n", - &a, &b, &c, &d, &e, &f, &g, &h, &l) != 8 || - l != (int)strlen(text)) { - zc_error_prev_line("eui64: invalid rr"); - return NULL; - } - nums[0] = (uint8_t)a; - nums[1] = (uint8_t)b; - nums[2] = (uint8_t)c; - nums[3] = (uint8_t)d; - nums[4] = (uint8_t)e; - nums[5] = (uint8_t)f; - nums[6] = (uint8_t)g; - nums[7] = (uint8_t)h; - r = alloc_rdata_init(region, nums, sizeof(nums)); - return r; -} - -uint16_t * -zparser_conv_eui(region_type *region, const char *text, size_t len) -{ - uint16_t *r = NULL; - int nnum, num; - const char* ch; - - nnum = len/8; - num = 1; - for (ch = text; *ch != '\0'; ch++) { - if (*ch == '-') { - num++; - } else if (!isxdigit((unsigned char)*ch)) { - zc_error_prev_line("eui%u: invalid (non-hexadecimal) " - "character %c", (unsigned) len, *ch); - return NULL; - } - } - if (num != nnum) { - zc_error_prev_line("eui%u: wrong number of hex numbers", - (unsigned) len); - return NULL; - } - - switch (len) { - case 48: - r = zparser_conv_eui48(region, text); - break; - case 64: - r = zparser_conv_eui64(region, text); - break; - default: - zc_error_prev_line("eui%u: invalid length", - (unsigned) len); - return NULL; - break; - } - return r; -} - -uint16_t * -zparser_conv_text(region_type *region, const char *text, size_t len) -{ - uint16_t *r = NULL; - uint8_t *p; - - if (len > 255) { - zc_error_prev_line("text string is longer than 255 characters," - " try splitting it into multiple parts"); - len = 255; - } - r = alloc_rdata(region, len + 1); - p = (uint8_t *) (r + 1); - *p = len; - memcpy(p + 1, text, len); - return r; -} - -/* for CAA Value [RFC 6844] */ -uint16_t * -zparser_conv_long_text(region_type *region, const char *text, size_t len) -{ - uint16_t *r = NULL; - if (len > MAX_RDLENGTH) { - zc_error_prev_line("text string is longer than max rdlen"); - return NULL; - } - r = alloc_rdata_init(region, text, len); - return r; -} - -/* for CAA Tag [RFC 6844] */ -uint16_t * -zparser_conv_tag(region_type *region, const char *text, size_t len) -{ - uint16_t *r = NULL; - uint8_t *p; - const char* ptr; - - if (len < 1) { - zc_error_prev_line("invalid tag: zero length"); - return NULL; - } - if (len > 15) { - zc_error_prev_line("invalid tag %s: longer than 15 characters (%u)", - text, (unsigned) len); - return NULL; - } - for (ptr = text; *ptr; ptr++) { - if (!isdigit((unsigned char)*ptr) && !islower((unsigned char)*ptr)) { - zc_error_prev_line("invalid tag %s: contains invalid char %c", - text, *ptr); - return NULL; - } - } - r = alloc_rdata(region, len + 1); - p = (uint8_t *) (r + 1); - *p = len; - memmove(p + 1, text, len); - return r; -} - -uint16_t * -zparser_conv_dns_name(region_type *region, const uint8_t* name, size_t len) -{ - uint16_t* r = NULL; - uint8_t* p = NULL; - r = alloc_rdata(region, len); - p = (uint8_t *) (r + 1); - memcpy(p, name, len); - - return r; -} - -uint16_t * -zparser_conv_b32(region_type *region, const char *b32) -{ - uint8_t buffer[B64BUFSIZE]; - uint16_t *r = NULL; - int i; - - if(strcmp(b32, "-") == 0) { - return alloc_rdata_init(region, "", 1); - } - i = b32_pton(b32, buffer+1, B64BUFSIZE-1); - if (i == -1 || i > 255) { - zc_error_prev_line("invalid base32 data"); - } else { - buffer[0] = i; /* store length byte */ - r = alloc_rdata_init(region, buffer, i+1); - } - return r; -} - -uint16_t * -zparser_conv_b64(region_type *region, const char *b64) -{ - uint8_t buffer[B64BUFSIZE]; - uint16_t *r = NULL; - int i; - - if(strcmp(b64, "0") == 0) { - /* single 0 represents empty buffer */ - return alloc_rdata(region, 0); - } - i = b64_pton(b64, buffer, B64BUFSIZE); - if (i == -1) { - zc_error_prev_line("invalid base64 data"); - } else { - r = alloc_rdata_init(region, buffer, i); - } - return r; -} - -uint16_t * -zparser_conv_rrtype(region_type *region, const char *text) -{ - uint16_t *r = NULL; - uint16_t type = rrtype_from_string(text); - - if (type == 0) { - zc_error_prev_line("unrecognized RR type '%s'", text); - } else { - type = htons(type); - r = alloc_rdata_init(region, &type, sizeof(type)); - } - return r; -} - -uint16_t * -zparser_conv_nxt(region_type *region, 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; - } - - return alloc_rdata_init(region, nxtbits, last); -} - - -/* we potentially have 256 windows, each one is numbered. empty ones - * should be discarded - */ -uint16_t * -zparser_conv_nsec(region_type *region, - 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(region, total_size); - 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; -} - -static uint16_t -svcbparam_lookup_key(const char *key, size_t key_len) -{ - char buf[64]; - char *endptr; - unsigned long int key_value; - - if (key_len >= 4 && key_len <= 8 && !strncmp(key, "key", 3)) { - memcpy(buf, key + 3, key_len - 3); - buf[key_len - 3] = 0; - key_value = strtoul(buf, &endptr, 10); - if (endptr > buf /* digits seen */ - && *endptr == 0 /* no non-digit chars after digits */ - && key_value <= 65535) /* no overflow */ - return key_value; - - } else switch (key_len) { - case sizeof("mandatory")-1: - if (!strncmp(key, "mandatory", sizeof("mandatory")-1)) - return SVCB_KEY_MANDATORY; - if (!strncmp(key, "echconfig", sizeof("echconfig")-1)) - return SVCB_KEY_ECH; /* allow "echconfig" as well as "ech" */ - break; - - case sizeof("alpn")-1: - if (!strncmp(key, "alpn", sizeof("alpn")-1)) - return SVCB_KEY_ALPN; - if (!strncmp(key, "port", sizeof("port")-1)) - return SVCB_KEY_PORT; - break; - - case sizeof("no-default-alpn")-1: - if (!strncmp( key , "no-default-alpn" - , sizeof("no-default-alpn")-1)) - return SVCB_KEY_NO_DEFAULT_ALPN; - break; - - case sizeof("ipv4hint")-1: - if (!strncmp(key, "ipv4hint", sizeof("ipv4hint")-1)) - return SVCB_KEY_IPV4HINT; - if (!strncmp(key, "ipv6hint", sizeof("ipv6hint")-1)) - return SVCB_KEY_IPV6HINT; - break; - case sizeof("dohpath")-1: - if (!strncmp(key, "dohpath", sizeof("dohpath")-1)) - return SVCB_KEY_DOHPATH; - break; - case sizeof("ech")-1: - if (!strncmp(key, "ech", sizeof("ech")-1)) - return SVCB_KEY_ECH; - break; - default: - break; - } - if (key_len > sizeof(buf) - 1) - zc_error_prev_line("Unknown SvcParamKey"); - else { - memcpy(buf, key, key_len); - buf[key_len] = 0; - zc_error_prev_line("Unknown SvcParamKey: %s", buf); - } - /* Although the returned value might be used by the caller, - * the parser has erred, so the zone will not be loaded. - */ - return -1; -} - -static uint16_t * -zparser_conv_svcbparam_port_value(region_type *region, const char *val) -{ - unsigned long int port; - char *endptr; - uint16_t *r; - - port = strtoul(val, &endptr, 10); - if (endptr > val /* digits seen */ - && *endptr == 0 /* no non-digit chars after digits */ - && port <= 65535) { /* no overflow */ - - r = alloc_rdata(region, 3 * sizeof(uint16_t)); - r[1] = htons(SVCB_KEY_PORT); - r[2] = htons(sizeof(uint16_t)); - r[3] = htons(port); - return r; - } - zc_error_prev_line("Could not parse port SvcParamValue: \"%s\"", val); - return NULL; -} - -static uint16_t * -zparser_conv_svcbparam_ipv4hint_value(region_type *region, const char *val) -{ - uint16_t *r; - int count; - char ip_str[INET_ADDRSTRLEN+1]; - char *next_ip_str; - uint32_t *ip_wire_dst; - size_t i; - - for (i = 0, count = 1; val[i]; i++) { - if (val[i] == ',') - count += 1; - if (count > SVCB_MAX_COMMA_SEPARATED_VALUES) { - zc_error_prev_line("Too many IPV4 addresses in ipv4hint"); - return NULL; - } - } - - /* count == number of comma's in val + 1, so the actual number of IPv4 - * addresses in val - */ - r = alloc_rdata(region, 2 * sizeof(uint16_t) + IP4ADDRLEN * count); - r[1] = htons(SVCB_KEY_IPV4HINT); - r[2] = htons(IP4ADDRLEN * count); - ip_wire_dst = (void *)&r[3]; - - while (count) { - if (!(next_ip_str = strchr(val, ','))) { - if (inet_pton(AF_INET, val, ip_wire_dst) != 1) - break; - - assert(count == 1); - - } else if (next_ip_str - val >= (int)sizeof(ip_str)) - break; - - else { - memcpy(ip_str, val, next_ip_str - val); - ip_str[next_ip_str - val] = 0; - if (inet_pton(AF_INET, ip_str, ip_wire_dst) != 1) { - val = ip_str; /* to use in error reporting below */ - break; - } - - val = next_ip_str + 1; - } - ip_wire_dst++; - count--; - } - if (count) - zc_error_prev_line("Could not parse ipv4hint SvcParamValue: %s", val); - - return r; -} - -static uint16_t * -zparser_conv_svcbparam_ipv6hint_value(region_type *region, const char *val) -{ - uint16_t *r; - int i, count; - char ip6_str[INET6_ADDRSTRLEN+1]; - char *next_ip6_str; - uint8_t *ipv6_wire_dst; - - for (i = 0, count = 1; val[i]; i++) { - if (val[i] == ',') - count += 1; - if (count > SVCB_MAX_COMMA_SEPARATED_VALUES) { - zc_error_prev_line("Too many IPV6 addresses in ipv6hint"); - return NULL; - } - } - - /* count == number of comma's in val + 1 - * so actually the number of IPv6 addresses in val - */ - r = alloc_rdata(region, 2 * sizeof(uint16_t) + IP6ADDRLEN * count); - r[1] = htons(SVCB_KEY_IPV6HINT); - r[2] = htons(IP6ADDRLEN * count); - ipv6_wire_dst = (void *)&r[3]; - - while (count) { - if (!(next_ip6_str = strchr(val, ','))) { - if ((inet_pton(AF_INET6, val, ipv6_wire_dst) != 1)) - break; - - assert(count == 1); - - } else if (next_ip6_str - val >= (int)sizeof(ip6_str)) - break; - - else { - memcpy(ip6_str, val, next_ip6_str - val); - ip6_str[next_ip6_str - val] = 0; - if (inet_pton(AF_INET6, ip6_str, ipv6_wire_dst) != 1) { - val = ip6_str; /* for error reporting below */ - break; - } - - val = next_ip6_str + 1; /* skip the comma */ - } - ipv6_wire_dst += IP6ADDRLEN; - count--; - } - if (count) - zc_error_prev_line("Could not parse ipv6hint SvcParamValue: %s", val); - - return r; -} - -static int -network_uint16_cmp(const void *a, const void *b) -{ - return ((int)read_uint16(a)) - ((int)read_uint16(b)); -} - -static uint16_t * -zparser_conv_svcbparam_mandatory_value(region_type *region, - const char *val, size_t val_len) -{ - uint16_t *r; - size_t i, count; - char* next_key; - uint16_t* key_dst; - - for (i = 0, count = 1; val[i]; i++) { - if (val[i] == ',') - count += 1; - if (count > SVCB_MAX_COMMA_SEPARATED_VALUES) { - zc_error_prev_line("Too many keys in mandatory"); - return NULL; - } - } - - r = alloc_rdata(region, (2 + count) * sizeof(uint16_t)); - r[1] = htons(SVCB_KEY_MANDATORY); - r[2] = htons(sizeof(uint16_t) * count); - key_dst = (void *)&r[3]; - - for(;;) { - if (!(next_key = strchr(val, ','))) { - *key_dst = htons(svcbparam_lookup_key(val, val_len)); - break; - } else { - *key_dst = htons(svcbparam_lookup_key(val, next_key - val)); - } - - val_len -= next_key - val + 1; - val = next_key + 1; /* skip the comma */ - key_dst += 1; - } - - /* In draft-ietf-dnsop-svcb-https-04 Section 7: - * - * In wire format, the keys are represented by their numeric - * values in network byte order, concatenated in ascending order. - */ - qsort((void *)&r[3], count, sizeof(uint16_t), network_uint16_cmp); - - return r; -} - -static uint16_t * -zparser_conv_svcbparam_ech_value(region_type *region, const char *b64) -{ - uint8_t buffer[B64BUFSIZE]; - uint16_t *r = NULL; - int wire_len; - - if(strcmp(b64, "0") == 0) { - /* single 0 represents empty buffer */ - return alloc_rdata(region, 0); - } - wire_len = b64_pton(b64, buffer, B64BUFSIZE); - if (wire_len == -1) { - zc_error_prev_line("invalid base64 data in ech"); - } else { - r = alloc_rdata(region, 2 * sizeof(uint16_t) + wire_len); - r[1] = htons(SVCB_KEY_ECH); - r[2] = htons(wire_len); - memcpy(&r[3], buffer, wire_len); - } - - return r; -} - -static const char* parse_alpn_next_unescaped_comma(const char *val) -{ - while (*val) { - /* Only return when the comma is not escaped*/ - if (*val == '\\'){ - ++val; - if (!*val) - break; - } else if (*val == ',') - return val; - - val++; - } - return NULL; -} - -static size_t -parse_alpn_copy_unescaped(uint8_t *dst, const char *src, size_t len) -{ - uint8_t *orig_dst = dst; - - while (len) { - if (*src == '\\') { - src++; - len--; - if (!len) - break; - } - *dst++ = *src++; - len--; - } - return (size_t)(dst - orig_dst); -} - -static uint16_t * -zparser_conv_svcbparam_alpn_value(region_type *region, - const char *val, size_t val_len) -{ - uint8_t unescaped_dst[65536]; - uint8_t *dst = unescaped_dst; - const char *next_str; - size_t str_len; - size_t dst_len; - uint16_t *r = NULL; - - if (val_len > sizeof(unescaped_dst)) { - zc_error_prev_line("invalid alpn"); - return r; - } - while (val_len) { - size_t dst_len; - - str_len = (next_str = parse_alpn_next_unescaped_comma(val)) - ? (size_t)(next_str - val) : val_len; - - if (str_len > 255) { - zc_error_prev_line("alpn strings need to be" - " smaller than 255 chars"); - return r; - } - dst_len = parse_alpn_copy_unescaped(dst + 1, val, str_len); - *dst++ = dst_len; - dst += dst_len; - - if (!next_str) - break; - - /* skip the comma for the next iteration */ - val_len -= next_str - val + 1; - val = next_str + 1; - } - dst_len = dst - unescaped_dst; - r = alloc_rdata(region, 2 * sizeof(uint16_t) + dst_len); - r[1] = htons(SVCB_KEY_ALPN); - r[2] = htons(dst_len); - memcpy(&r[3], unescaped_dst, dst_len); - return r; -} - -static uint16_t * -zparser_conv_svcbparam_key_value(region_type *region, - const char *key, size_t key_len, const char *val, size_t val_len) -{ - uint16_t svcparamkey = svcbparam_lookup_key(key, key_len); - uint16_t *r; - - switch (svcparamkey) { - case SVCB_KEY_PORT: - return zparser_conv_svcbparam_port_value(region, val); - case SVCB_KEY_IPV4HINT: - return zparser_conv_svcbparam_ipv4hint_value(region, val); - case SVCB_KEY_IPV6HINT: - return zparser_conv_svcbparam_ipv6hint_value(region, val); - case SVCB_KEY_MANDATORY: - return zparser_conv_svcbparam_mandatory_value(region, val, val_len); - case SVCB_KEY_NO_DEFAULT_ALPN: - if(zone_is_slave(parser->current_zone->opts)) - zc_warning_prev_line("no-default-alpn should not have a value"); - else - zc_error_prev_line("no-default-alpn should not have a value"); - break; - case SVCB_KEY_ECH: - return zparser_conv_svcbparam_ech_value(region, val); - case SVCB_KEY_ALPN: - return zparser_conv_svcbparam_alpn_value(region, val, val_len); - case SVCB_KEY_DOHPATH: - /* fallthrough */ - default: - break; - } - r = alloc_rdata(region, 2 * sizeof(uint16_t) + val_len); - r[1] = htons(svcparamkey); - r[2] = htons(val_len); - memcpy(r + 3, val, val_len); - return r; -} - -uint16_t * -zparser_conv_svcbparam(region_type *region, const char *key, size_t key_len - , const char *val, size_t val_len) -{ - const char *eq; - uint16_t *r; - uint16_t svcparamkey; - - /* Form ="" (or at least with quoted value) */ - if (val && val_len) { - /* Does key end with '=' */ - if (key_len && key[key_len - 1] == '=') - return zparser_conv_svcbparam_key_value( - region, key, key_len - 1, val, val_len); - - zc_error_prev_line( "SvcParam syntax error in param: %s\"%s\"" - , key, val); - } - assert(val == NULL); - if ((eq = memchr(key, '=', key_len))) { - size_t new_key_len = eq - key; - - if (key_len - new_key_len - 1 > 0) - return zparser_conv_svcbparam_key_value(region, - key, new_key_len, eq+1, key_len - new_key_len - 1); - key_len = new_key_len; - } - /* Some SvcParamKeys require values */ - svcparamkey = svcbparam_lookup_key(key, key_len); - switch (svcparamkey) { - case SVCB_KEY_MANDATORY: - case SVCB_KEY_ALPN: - case SVCB_KEY_PORT: - case SVCB_KEY_IPV4HINT: - case SVCB_KEY_IPV6HINT: - case SVCB_KEY_DOHPATH: - if(zone_is_slave(parser->current_zone->opts)) - zc_warning_prev_line("value expected for SvcParam: %s", key); - else - zc_error_prev_line("value expected for SvcParam: %s", key); - break; - default: - break; - } - /* SvcParam is only a SvcParamKey */ - r = alloc_rdata(region, 2 * sizeof(uint16_t)); - r[1] = htons(svcparamkey); - r[2] = 0; - 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) -{ - *result = (int) strtol(str, end, 10); - if (*result < min || *result > max) { - zc_error_prev_line("%s must be within the range [%d .. %d]", - name, - min, - max); - return 0; - } else { - return 1; - } -} - -/* RFC1876 conversion routines */ -static unsigned int 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((unsigned char)*cp)) - mval = mval * 10 + hexdigit_to_int(*cp++); - - if (*cp == '.') { /* centimeters */ - cp++; - if (isdigit((unsigned char)*cp)) { - cmval = hexdigit_to_int(*cp++) * 10; - if (isdigit((unsigned char)*cp)) { - cmval += hexdigit_to_int(*cp++); - } - } - } - - if(mval >= poweroften[7]) { - assert(poweroften[7] != 0); - /* 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; - - assert(poweroften[exponent] != 0); - 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(region_type *region, 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((unsigned char)*str)) { - zc_error_prev_line("space expected after degrees"); - return NULL; - } - ++str; - - /* Minutes? */ - if (isdigit((unsigned char)*str)) { - if (!parse_int(str, &str, &min, "minutes", 0, 60)) - return NULL; - if (!isspace((unsigned char)*str)) { - zc_error_prev_line("space expected after minutes"); - return NULL; - } - ++str; - } - - /* Seconds? */ - if (isdigit((unsigned char)*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((unsigned char)*str)) { - zc_error_prev_line("space expected after seconds"); - return NULL; - } - /* No need for precision specifiers, it's a double */ - if (sscanf(start, "%lf", &d) != 1) { - 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((unsigned char)*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((unsigned char)*str)) { - zc_error_prev_line("space expected before altitude"); - return NULL; - } - ++str; - - start = str; - - /* Sign */ - if (*str == '+' || *str == '-') { - ++str; - } - - /* Meters of altitude... */ - if(strtol(str, &str, 10) == LONG_MAX) { - zc_error_prev_line("altitude too large, number overflow"); - return NULL; - } - switch(*str) { - case ' ': - case '\0': - case 'm': - break; - case '.': - if (!parse_int(str + 1, &str, &i, "altitude fraction", 0, 99)) { - return NULL; - } - if (!isspace((unsigned char)*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((unsigned char)*str) && *str != '\0') - ++str; - - if (sscanf(start, "%lf", &d) != 1) { - zc_error_prev_line("error parsing altitude"); - } - - alt = (uint32_t) (10000000.0 + d * 100 + 0.5); - - if (!isspace((unsigned char)*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((unsigned char)*str) && i <= 3; i++) { - vszhpvp[i] = precsize_aton(str + 1, &str); - - if (!isspace((unsigned char)*str) && *str != '\0') { - zc_error_prev_line("invalid size or precision"); - return NULL; - } - } - - /* Allocate required space... */ - r = alloc_rdata(region, 16); - 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(region_type *region, 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("address family separator is missing"); - return NULL; - } - if (!slash) { - zc_error("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("invalid address family '%s'", str); - return NULL; - } - - rc = inet_pton(af, colon + 1, address); - if (rc == 0) { - zc_error("invalid address '%s'", colon + 1); - return NULL; - } else if (rc == -1) { - zc_error("inet_pton failed: %s", strerror(errno)); - 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("prefix not in the range 0 .. %d", maximum_prefix); - return NULL; - } else if (*end != '\0') { - zc_error("invalid prefix '%s'", slash + 1); - return NULL; - } - prefix = (uint8_t) p; - - rdlength = (sizeof(address_family) + sizeof(prefix) + sizeof(length) - + length); - r = alloc_rdata(region, rdlength); - 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) -{ - if (parser->current_rr.rdata_count >= MAXRDATALEN) { - zc_error_prev_line("too many rdata elements"); - } else { - parser->current_rr.rdatas[parser->current_rr.rdata_count].data - = data; - ++parser->current_rr.rdata_count; - } -} - -/** - * Used for TXT RR's to grow with undefined number of strings. - */ -void -zadd_rdata_txt_wireformat(uint16_t *data, int first) -{ - rdata_atom_type *rd; - if (parser->current_rr.rdata_count >= MAXRDATALEN) { - zc_error_prev_line("too many rdata txt elements"); - return; - } - - /* First STR in str_seq, allocate 65K in first unused rdata - * else find last used rdata */ - if (first) { - rd = &parser->current_rr.rdatas[parser->current_rr.rdata_count]; - if ((rd->data = (uint16_t *) region_alloc(parser->rr_region, - sizeof(uint16_t) + 65535 * sizeof(uint8_t))) == NULL) { - zc_error_prev_line("Could not allocate memory for TXT RR"); - return; - } - parser->current_rr.rdata_count++; - rd->data[0] = 0; - } - else - rd = &parser->current_rr.rdatas[parser->current_rr.rdata_count-1]; - - if ((size_t)rd->data[0] + (size_t)data[0] > 65535) { - zc_error_prev_line("too large rdata element"); - return; - } - - memcpy((uint8_t *)rd->data + 2 + rd->data[0], data + 1, data[0]); - rd->data[0] += data[0]; -} - -/** - * Clean up after last call of zadd_rdata_txt_wireformat - */ -void -zadd_rdata_txt_clean_wireformat() -{ - uint16_t *tmp_data; - rdata_atom_type *rd = &parser->current_rr.rdatas[parser->current_rr.rdata_count-1]; - if(!rd || !rd->data) - return; /* previous syntax failure */ - if ((tmp_data = (uint16_t *) region_alloc(parser->region, - ((size_t)rd->data[0]) + ((size_t)2))) != NULL) { - memcpy(tmp_data, rd->data, rd->data[0] + 2); - /* rd->data of u16+65535 freed when rr_region is freed */ - rd->data = tmp_data; - } - else { - /* We could not get memory in non-volatile region */ - zc_error_prev_line("could not allocate memory for rdata"); - return; - } -} - -static int -svcparam_key_cmp(const void *a, const void *b) -{ - return ((int)read_uint16(rdata_atom_data(*(rdata_atom_type *)a))) - - ((int)read_uint16(rdata_atom_data(*(rdata_atom_type *)b))); -} - -void -zadd_rdata_svcb_check_wireformat() -{ - size_t i; - uint8_t paramkeys[65536]; - int prev_key = - 1; - int key = 0; - size_t size; - uint16_t *mandatory_values; - - if (parser->current_rr.rdata_count <= 2) { - if (!parser->error_occurred) - zc_error_prev_line("invalid SVCB or HTTPS rdata"); - return; - } else for (i = 2; i < parser->current_rr.rdata_count; i++) { - if (parser->current_rr.rdatas[i].data == NULL - || rdata_atom_data(parser->current_rr.rdatas[i]) == NULL - || rdata_atom_size(parser->current_rr.rdatas[i]) < 4) { - if (!parser->error_occurred) - zc_error_prev_line("invalid SVCB or HTTPS rdata"); - return; - } - } - /* After this point, all rdatas do have data larger than 4 bytes. - * So we may assume a uint16_t SVCB key followed by uint16_t length - * in each rdata in the remainder of this function. - */ - memset(paramkeys, 0, sizeof(paramkeys)); - /* - * In draft-ietf-dnsop-svcb-https-04 Section 7: - * In wire format, the keys are represented by their numeric values in - * network byte order, concatenated in ascending order. - * - * svcparam_key_cmp assumes the rdatas to have a SVCB key, which is - * safe because we checked. - * - */ - qsort( (void *)&parser->current_rr.rdatas[2] - , parser->current_rr.rdata_count - 2 - , sizeof(rdata_atom_type) - , svcparam_key_cmp - ); - - for (i = 2; i < parser->current_rr.rdata_count; i++) { - assert(parser->current_rr.rdatas[i].data); - assert(rdata_atom_data(parser->current_rr.rdatas[i])); - assert(rdata_atom_size(parser->current_rr.rdatas[i]) >= sizeof(uint16_t)); - - key = read_uint16(rdata_atom_data(parser->current_rr.rdatas[i])); - - /* In draft-ietf-dnsop-svcb-https-04 Section 7: - * - * Keys (...) MUST NOT appear more than once. - * - * If they key has already been seen, we have a duplicate - */ - if (!paramkeys[key]) - /* keep track of keys that are present */ - paramkeys[key] = 1; - - else if (key < SVCPARAMKEY_COUNT) { - if(zone_is_slave(parser->current_zone->opts)) - zc_warning_prev_line( - "Duplicate key found: %s", - svcparamkey_strs[key]); - else { - zc_error_prev_line( - "Duplicate key found: %s", - svcparamkey_strs[key]); - } - } else if(zone_is_slave(parser->current_zone->opts)) - zc_warning_prev_line( - "Duplicate key found: key%d", key); - else - zc_error_prev_line( - "Duplicate key found: key%d", key); - } - /* Checks when a mandatory key is present */ - if (!paramkeys[SVCB_KEY_MANDATORY]) - return; - - size = rdata_atom_size(parser->current_rr.rdatas[2]); - assert(size >= 4); - mandatory_values = (void*)rdata_atom_data(parser->current_rr.rdatas[2]); - mandatory_values += 2; /* skip the key type and length */ - - if (size % 2) - zc_error_prev_line("mandatory rdata must be a multiple of shorts"); - - else for (i = 0; i < (size - 4)/2; i++) { - key = ntohs(mandatory_values[i]); - - if (paramkeys[key]) - ; /* pass */ - - else if (key < SVCPARAMKEY_COUNT) { - if(zone_is_slave(parser->current_zone->opts)) - zc_warning_prev_line("mandatory SvcParamKey: %s is missing " - "the record", svcparamkey_strs[key]); - else - zc_error_prev_line("mandatory SvcParamKey: %s is missing " - "the record", svcparamkey_strs[key]); - } else { - if(zone_is_slave(parser->current_zone->opts)) - zc_warning_prev_line("mandatory SvcParamKey: key%d is missing " - "the record", key); - else - zc_error_prev_line("mandatory SvcParamKey: key%d is missing " - "the record", key); - } - - /* In draft-ietf-dnsop-svcb-https-04 Section 8 - * automatically mandatory MUST NOT appear in its own value-list - */ - if (key == SVCB_KEY_MANDATORY) { - if(zone_is_slave(parser->current_zone->opts)) - zc_warning_prev_line("mandatory MUST not be included" - " as mandatory parameter"); - else - zc_error_prev_line("mandatory MUST not be included" - " as mandatory parameter"); - } - if (key == prev_key) { - if(zone_is_slave(parser->current_zone->opts)) - zc_warning_prev_line("Keys inSvcParam mandatory " - "MUST NOT appear more than once."); - else - zc_error_prev_line("Keys in SvcParam mandatory " - "MUST NOT appear more than once."); - } - prev_key = key; - } -} - -void -zadd_rdata_domain(domain_type *domain) -{ - if (parser->current_rr.rdata_count >= MAXRDATALEN) { - zc_error_prev_line("too many rdata elements"); - } else { - parser->current_rr.rdatas[parser->current_rr.rdata_count].domain - = domain; - domain->usage ++; /* new reference to domain */ - ++parser->current_rr.rdata_count; - } -} - -void -parse_unknown_rdata(uint16_t type, uint16_t *wireformat) -{ - buffer_type packet; - uint16_t size; - ssize_t rdata_count; - ssize_t i; - rdata_atom_type *rdatas; - - if (wireformat) { - size = *wireformat; - } else { - return; - } - - buffer_create_from(&packet, wireformat + 1, *wireformat); - rdata_count = rdata_wireformat_to_rdata_atoms(parser->region, - parser->db->domains, - type, - size, - &packet, - &rdatas); - if (rdata_count == -1) { - zc_error_prev_line("bad unknown RDATA"); - return; - } - - for (i = 0; i < rdata_count; ++i) { - if (rdata_atom_is_domain(type, i)) { - zadd_rdata_domain(rdatas[i].domain); - } else { - zadd_rdata_wireformat(rdatas[i].data); - } - } - region_recycle(parser->region, rdatas, - rdata_count*sizeof(rdata_atom_type)); -} - +#include "zone.h" /* * Compares two rdata arrays. @@ -1864,42 +54,40 @@ parse_unknown_rdata(uint16_t type, uint16_t *wireformat) * */ static int -zrdatacmp(uint16_t type, rr_type *a, rr_type *b) +zrdatacmp(uint16_t type, const union rdata_atom *rdatas, size_t rdata_count, rr_type *b) { - int i = 0; - - assert(a); + assert(rdatas); assert(b); /* One is shorter than another */ - if (a->rdata_count != b->rdata_count) + if (rdata_count != b->rdata_count) return 1; /* Compare element by element */ - for (i = 0; i < a->rdata_count; ++i) { + for (size_t i = 0; i < rdata_count; ++i) { if (rdata_atom_is_domain(type, i)) { - if (rdata_atom_domain(a->rdatas[i]) + if (rdata_atom_domain(rdatas[i]) != rdata_atom_domain(b->rdatas[i])) { return 1; } } else if(rdata_atom_is_literal_domain(type, i)) { - if (rdata_atom_size(a->rdatas[i]) + if (rdata_atom_size(rdatas[i]) != rdata_atom_size(b->rdatas[i])) return 1; - if (!dname_equal_nocase(rdata_atom_data(a->rdatas[i]), + if (!dname_equal_nocase(rdata_atom_data(rdatas[i]), rdata_atom_data(b->rdatas[i]), - rdata_atom_size(a->rdatas[i]))) + rdata_atom_size(rdatas[i]))) return 1; } else { - if (rdata_atom_size(a->rdatas[i]) + if (rdata_atom_size(rdatas[i]) != rdata_atom_size(b->rdatas[i])) { return 1; } - if (memcmp(rdata_atom_data(a->rdatas[i]), + if (memcmp(rdata_atom_data(rdatas[i]), rdata_atom_data(b->rdatas[i]), - rdata_atom_size(a->rdatas[i])) != 0) + rdata_atom_size(rdatas[i])) != 0) { return 1; } @@ -1911,52 +99,55 @@ zrdatacmp(uint16_t type, rr_type *a, rr_type *b) } /* - * - * Opens a zone file. - * - * Returns: - * - * - pointer to the parser structure - * - NULL on error and errno set - * + * Find rrset type for any zone */ -static int -zone_open(const char *filename, uint32_t ttl, uint16_t klass, - const dname_type *origin) +static rrset_type* +domain_find_rrset_any(domain_type *domain, uint16_t type) { - /* Open the zone file... */ - if (strcmp(filename, "-") == 0) { - yyin = stdin; - filename = ""; - warn_if_directory("zonefile from stdin", yyin, filename); - } else { - if (!(yyin = fopen(filename, "r"))) { - return 0; + rrset_type *result = domain->rrsets; + while (result) { + if (rrset_rrtype(result) == type) { + return result; } - warn_if_directory("zonefile", yyin, filename); + result = result->next; } - - zparser_init(filename, ttl, klass, origin); - - return 1; + return NULL; } - -void -set_bitnsec(uint8_t bits[NSEC_WINDOW_COUNT][NSEC_WINDOW_BITS_SIZE], - uint16_t index) +/* + * Check for DNAME type. Nothing is allowed below it + */ +static int +check_dname(zone_type* zone) { - /* - * 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; + domain_type* domain; + for(domain = zone->apex; domain && domain_is_subdomain(domain, + zone->apex); domain=domain_next(domain)) + { + if(domain->is_existing) { + /* there may not be DNAMEs above it */ + domain_type* parent = domain->parent; +#ifdef NSEC3 + if(domain_has_only_NSEC3(domain, NULL)) + continue; +#endif + while(parent) { + if(domain_find_rrset_any(parent, TYPE_DNAME)) { + log_msg(LOG_ERR, "While checking node %s,", + domain_to_string(domain)); + log_msg(LOG_ERR, "DNAME at %s has data below it. " + "This is not allowed (rfc 2672).", + domain_to_string(parent)); + return 0; + } + parent = parent->parent; + } + } + } - bits[window][bit / 8] |= (1 << (7 - bit % 8)); + return 1; } - static int has_soa(domain_type* domain) { @@ -1968,226 +159,202 @@ has_soa(domain_type* domain) return 0; } -int -process_rr(void) -{ - zone_type *zone = parser->current_zone; - rr_type *rr = &parser->current_rr; - rrset_type *rrset; - size_t max_rdlength; - int i; - rrtype_descriptor_type *descriptor - = rrtype_descriptor_by_type(rr->type); +struct zonec_state { + struct namedb *database; + struct domain_table *domains; + struct region *rr_region; + struct zone *zone; + struct domain *domain; + size_t errors; + size_t records; +}; + +int32_t zonec_accept( + zone_parser_t *parser, + const zone_name_t *owner, + uint16_t type, + uint16_t class, + uint32_t ttl, + uint16_t rdlength, + const uint8_t *rdata, + void *user_data) +{ + struct rr *rr; + struct rrset *rrset; + const struct dname *dname; + struct domain *domain; + struct buffer buffer; + int priority; + union rdata_atom *rdatas; + ssize_t rdata_count; + struct zonec_state *state = (struct zonec_state *)user_data; - /* We only support IN class */ - if (rr->klass != CLASS_IN) { - if(zone_is_slave(zone->opts)) - zc_warning_prev_line("only class IN is supported"); - else - zc_error_prev_line("only class IN is supported"); - return 0; - } + assert(state); - /* Make sure the maximum RDLENGTH does not exceed 65535 bytes. */ - max_rdlength = rdata_maximum_wireformat_size( - descriptor, rr->rdata_count, rr->rdatas); + // emulate packet buffer to leverage rdata_wireformat_to_rdata_atoms + buffer_create_from(&buffer, rdata, rdlength); - if (max_rdlength > MAX_RDLENGTH) { - zc_error_prev_line("maximum rdata length exceeds %d octets", MAX_RDLENGTH); - return 0; - } + priority = parser->options.secondary ? ZONE_WARNING : ZONE_ERROR; + // limit to IN class + if (class != CLASS_IN) + zone_log(parser, priority, "only class IN is supported"); - /* We cannot print invalid owner names, - * so error on that before it is used in printing other errors. - */ - if (rr->owner == error_domain - || domain_dname(rr->owner) == error_dname) { - zc_error_prev_line("invalid owner name"); - return 0; - } + dname = dname_make(state->rr_region, owner->octets, 1); + assert(dname); + domain = domain_table_insert(state->domains, dname); + assert(domain); + + rdatas = NULL; + rdata_count = rdata_wireformat_to_rdata_atoms( + state->database->region, state->domains, type, rdlength, &buffer, &rdatas); + // number of atoms must not exceed maximum of 65535 (all empty strings) + assert(rdata_count >= 0); + assert(rdata_count <= MAX_RDLENGTH); /* we have the zone already */ - assert(zone); - if (rr->type == TYPE_SOA) { - if (rr->owner != zone->apex) { + if (type == TYPE_SOA) { + if (domain != state->zone->apex) { char s[MAXDOMAINLEN*5]; - snprintf(s, sizeof(s), "%s", domain_to_string(zone->apex)); - zc_error_prev_line( - "SOA record with invalid domain name, '%s' is not '%s'", domain_to_string(rr->owner), s); - return 0; + snprintf(s, sizeof(s), "%s", domain_to_string(domain)); + zone_log(parser, priority, "SOA record with invalid domain name, '%s' is not '%s'", + domain_to_string(state->zone->apex), s); + } else if (has_soa(domain)) { + zone_log(parser, priority, "this SOA record was already encountered"); } - if(has_soa(rr->owner)) { - if(zone_is_slave(zone->opts)) - zc_warning_prev_line("this SOA record was already encountered"); - else - zc_error_prev_line("this SOA record was already encountered"); - return 0; - } - rr->owner->is_apex = 1; + domain->is_apex = 1; } - if (!domain_is_subdomain(rr->owner, zone->apex)) - { + if (!domain_is_subdomain(domain, state->zone->apex)) { char s[MAXDOMAINLEN*5]; - snprintf(s, sizeof(s), "%s", domain_to_string(zone->apex)); - if(zone_is_slave(zone->opts)) - zc_warning_prev_line("out of zone data: %s is outside the zone for fqdn %s", domain_to_string(rr->owner), s); - else - zc_error_prev_line("out of zone data: %s is outside the zone for fqdn %s", domain_to_string(rr->owner), s); - return 0; + snprintf(s, sizeof(s), "%s", domain_to_string(state->zone->apex)); + zone_log(parser, priority, "out of zone data: %s is outside the zone for fqdn %s", + s, domain_to_string(domain)); + if (!parser->options.secondary) { + region_free_all(state->rr_region); + return ZONE_SEMANTIC_ERROR; + } } /* Do we have this type of rrset already? */ - rrset = domain_find_rrset(rr->owner, zone, rr->type); + rrset = domain_find_rrset(domain, state->zone, type); if (!rrset) { - rrset = (rrset_type *) region_alloc(parser->region, - sizeof(rrset_type)); - rrset->zone = zone; - rrset->rr_count = 1; - rrset->rrs = (rr_type *) region_alloc(parser->region, - sizeof(rr_type)); - rrset->rrs[0] = *rr; + rrset = region_alloc(state->database->region, sizeof(*rrset)); + rrset->zone = state->zone; + rrset->rr_count = 0; + rrset->rrs = region_alloc(state->database->region, sizeof(*rr)); + + switch (type) { + case TYPE_CNAME: + if (!domain_find_non_cname_rrset(domain, state->zone)) + break; + zone_log(parser, priority, "CNAME and other data at the same name"); + break; + case TYPE_RRSIG: + case TYPE_NXT: + case TYPE_SIG: + case TYPE_NSEC: + case TYPE_NSEC3: + break; + default: + if (!domain_find_rrset(domain, state->zone, TYPE_CNAME)) + break; + zone_log(parser, priority, "CNAME and other data at the same name"); + break; + } /* Add it */ - domain_add_rrset(rr->owner, rrset); + domain_add_rrset(domain, rrset); } else { - rr_type* o; - if (rr->type != TYPE_RRSIG && rrset->rrs[0].ttl != rr->ttl) { - zc_warning_prev_line( - "%s TTL %u does not match the TTL %u of the %s RRset", - domain_to_string(rr->owner), (unsigned)rr->ttl, - (unsigned)rrset->rrs[0].ttl, - rrtype_to_string(rr->type)); + struct rr *rrs; + if (type != TYPE_RRSIG && ttl != rrset->rrs[0].ttl) { + zone_log(parser, priority, "%s TTL %"PRIu32" does not match TTL %u of %s RRset", + domain_to_string(domain), ttl, rrset->rrs[0].ttl, + rrtype_to_string(type)); } /* Search for possible duplicates... */ - for (i = 0; i < rrset->rr_count; i++) { - if (!zrdatacmp(rr->type, rr, &rrset->rrs[i])) { - break; - } - } - - /* Discard the duplicates... */ - if (i < rrset->rr_count) { - /* add rdatas to recycle bin. */ - size_t i; - for (i = 0; i < rr->rdata_count; i++) { - if(!rdata_atom_is_domain(rr->type, i)) - region_recycle(parser->region, rr->rdatas[i].data, - rdata_atom_size(rr->rdatas[i]) - + sizeof(uint16_t)); + for (int i = 0; i < rrset->rr_count; i++) { + if (zrdatacmp(type, rdatas, rdata_count, &rrset->rrs[i]) != 0) + continue; + /* Discard the duplicates... */ + for (size_t j = 0; j < (size_t)rdata_count; j++) { + size_t size; + if (rdata_atom_is_domain(type, j)) + continue; + size = rdata_atom_size(rdatas[j]) + sizeof(uint16_t); + region_recycle(state->database->region, rdatas[j].data, size); } - region_recycle(parser->region, rr->rdatas, - sizeof(rdata_atom_type)*rr->rdata_count); + region_recycle(state->database->region, rdatas, sizeof(*rdatas) * rdata_count); + region_free_all(state->rr_region); return 0; } - if(rrset->rr_count == 65535) { - zc_error_prev_line("too many RRs for domain RRset"); - return 0; + + switch (type) { + case TYPE_CNAME: + zone_log(parser, priority, "multiple CNAMEs at the same name"); + break; + case TYPE_DNAME: + zone_log(parser, priority, "multiple DNAMEs at the same name"); + break; + default: + break; } /* Add it... */ - o = rrset->rrs; - rrset->rrs = (rr_type *) region_alloc_array(parser->region, - (rrset->rr_count + 1), sizeof(rr_type)); - memcpy(rrset->rrs, o, (rrset->rr_count) * sizeof(rr_type)); - region_recycle(parser->region, o, - (rrset->rr_count) * sizeof(rr_type)); - rrset->rrs[rrset->rr_count] = *rr; - ++rrset->rr_count; + rrs = rrset->rrs; + rrset->rrs = region_alloc_array(state->database->region, rrset->rr_count + 1, sizeof(*rr)); + memcpy(rrset->rrs, rrs, rrset->rr_count * sizeof(*rr)); + region_recycle(state->database->region, rrs, rrset->rr_count * sizeof(*rr)); } - if(rr->type == TYPE_DNAME && rrset->rr_count > 1) { - if(zone_is_slave(zone->opts)) - zc_warning_prev_line("multiple DNAMEs at the same name"); - else - zc_error_prev_line("multiple DNAMEs at the same name"); - } - if(rr->type == TYPE_CNAME && rrset->rr_count > 1) { - if(zone_is_slave(zone->opts)) - zc_warning_prev_line("multiple CNAMEs at the same name"); - else - zc_error_prev_line("multiple CNAMEs at the same name"); - } - if((rr->type == TYPE_DNAME && domain_find_rrset(rr->owner, zone, TYPE_CNAME)) - ||(rr->type == TYPE_CNAME && domain_find_rrset(rr->owner, zone, TYPE_DNAME))) { - if(zone_is_slave(zone->opts)) - zc_warning_prev_line("DNAME and CNAME at the same name"); - else - zc_error_prev_line("DNAME and CNAME at the same name"); - } - if(domain_find_rrset(rr->owner, zone, TYPE_CNAME) && - domain_find_non_cname_rrset(rr->owner, zone)) { - if(zone_is_slave(zone->opts)) - zc_warning_prev_line("CNAME and other data at the same name"); - else - zc_error_prev_line("CNAME and other data at the same name"); - } + rr = &rrset->rrs[rrset->rr_count++]; + rr->owner = domain; + rr->rdatas = rdatas; + rr->ttl = ttl; + rr->type = type; + rr->klass = class; + rr->rdata_count = rdata_count; /* Check we have SOA */ - if(rr->owner == zone->apex) - apex_rrset_checks(parser->db, rrset, rr->owner); + if (rr->owner == state->zone->apex) + apex_rrset_checks(state->database, rrset, rr->owner); - if(parser->line % ZONEC_PCT_COUNT == 0 && time(NULL) > startzonec + ZONEC_PCT_TIME) { - struct stat buf; - startzonec = time(NULL); - buf.st_size = 0; - fstat(fileno(yyin), &buf); - if(buf.st_size == 0) buf.st_size = 1; - VERBOSITY(1, (LOG_INFO, "parse %s %d %%", - parser->current_zone->opts->name, - (int)((uint64_t)ftell(yyin)*(uint64_t)100/(uint64_t)buf.st_size))); - } - ++totalrrs; - return 1; + state->records++; + region_free_all(state->rr_region); + return 0; } -/* - * Find rrset type for any zone - */ -static rrset_type* -domain_find_rrset_any(domain_type *domain, uint16_t type) +static void zonec_log( + zone_parser_t *parser, + uint32_t category, + const char *file, + size_t line, + const char *message, + void *user_data) { - rrset_type *result = domain->rrsets; - while (result) { - if (rrset_rrtype(result) == type) { - return result; - } - result = result->next; - } - return NULL; -} + int priority; + struct zonec_state *state = (struct zonec_state *)user_data; -/* - * Check for DNAME type. Nothing is allowed below it - */ -static void -check_dname(zone_type* zone) -{ - domain_type* domain; - for(domain = zone->apex; domain && domain_is_subdomain(domain, - zone->apex); domain=domain_next(domain)) - { - if(domain->is_existing) { - /* there may not be DNAMEs above it */ - domain_type* parent = domain->parent; -#ifdef NSEC3 - if(domain_has_only_NSEC3(domain, NULL)) - continue; -#endif - while(parent) { - if(domain_find_rrset_any(parent, TYPE_DNAME)) { - zc_error("While checking node %s,", - domain_to_string(domain)); - zc_error("DNAME at %s has data below it. " - "This is not allowed (rfc 2672).", - domain_to_string(parent)); - return; - } - parent = parent->parent; - } - } + assert(state); + (void)parser; + + switch (category) { + case ZONE_INFO: + priority = LOG_INFO; + break; + case ZONE_WARNING: + priority = LOG_WARNING; + break; + default: + priority = LOG_ERR; + state->errors++; + break; } + + if (file) + log_msg(priority, "%s:%zu: %s", file, line, message); + else + log_msg(priority, "%s", message); } /* @@ -2195,178 +362,64 @@ check_dname(zone_type* zone) * nsd_options can be NULL if no config file is passed. */ unsigned int -zonec_read(const char* name, const char* zonefile, zone_type* zone) -{ - const dname_type *dname; - - totalrrs = 0; - startzonec = time(NULL); - parser->errors = 0; - - dname = dname_parse(parser->rr_region, name); - if (!dname) { - zc_error("incorrect zone name '%s'", name); - return 1; - } - - /* Open the zone file */ - if (!zone_open(zonefile, 3600, CLASS_IN, dname)) { - zc_error("cannot open '%s': %s", zonefile, strerror(errno)); - return 1; - } - parser->current_zone = zone; +zonec_read( + struct namedb *database, + struct domain_table *domains, + const char *name, + const char *zonefile, + struct zone *zone) +{ + const struct dname *origin; + zone_parser_t parser; + zone_options_t options; + zone_name_buffer_t name_buffer; + zone_rdata_buffer_t rdata_buffer; + struct zonec_state state; + zone_buffers_t buffers = { 1, &name_buffer, &rdata_buffer }; + + state.database = database; + state.domains = domains; + state.rr_region = region_create(xalloc, free); + state.zone = zone; + state.domain = NULL; + state.errors = 0; + state.records = 0; + + origin = domain_dname(zone->apex); + memset(&options, 0, sizeof(options)); + options.origin.octets = dname_name(origin); + options.origin.length = origin->name_size; + options.default_ttl = DEFAULT_TTL; + options.default_class = CLASS_IN; + options.secondary = zone_is_slave(zone->opts) != 0; + options.pretty_ttls = true; /* non-standard, for backwards compatibility */ + options.log.callback = &zonec_log; + options.accept.callback = &zonec_accept; /* Parse and process all RRs. */ - yyparse(); - - /* remove origin if it was unused */ - if(parser->origin != error_domain) - domain_table_deldomain(parser->db, parser->origin); - /* rr_region has been emptied by now */ - dname = dname_parse(parser->rr_region, name); - - /* check if zone file contained a correct SOA record */ - if (!parser->current_zone) { - zc_error("zone configured as '%s' has no content.", name); - } else if(!parser->current_zone->soa_rrset || - parser->current_zone->soa_rrset->rr_count == 0) { - zc_error("zone configured as '%s' has no SOA record.", name); - } else if(dname_compare(domain_dname( - parser->current_zone->soa_rrset->rrs[0].owner), dname) != 0) { - zc_error("zone configured as '%s', but SOA has owner '%s'.", - name, domain_to_string( - parser->current_zone->soa_rrset->rrs[0].owner)); + if (zone_parse(&parser, &options, &buffers, zonefile, &state) != 0) { + region_destroy(state.rr_region); + return state.errors; } - region_free_all(parser->rr_region); - - parser_flush(); - fclose(yyin); - if(!zone_is_slave(zone->opts)) - check_dname(zone); - - parser->filename = NULL; - return parser->errors; -} - -/* - * setup parse - */ -void -zonec_setup_parser(namedb_type* db) -{ - region_type* rr_region = region_create(xalloc, free); - parser = zparser_create(db->region, rr_region, db); - assert(parser); - /* Unique pointers used to mark errors. */ - error_dname = (dname_type *) region_alloc(db->region, 1); - error_domain = (domain_type *) region_alloc(db->region, 1); - /* Open the network database */ - setprotoent(1); - setservent(1); -} - -/** desetup parse */ -void -zonec_desetup_parser(void) -{ - if(parser) { - endservent(); - endprotoent(); - region_destroy(parser->rr_region); - /* removed when parser->region(=db->region) is destroyed: - * region_recycle(parser->region, (void*)error_dname, 1); - * region_recycle(parser->region, (void*)error_domain, 1); */ - /* clear memory for exit, but this is not portable to - * other versions of lex. yylex_destroy(); */ -#ifdef MEMCLEAN /* OS collects memory pages */ - yylex_destroy(); -#endif + /* Check if zone file contained a correct SOA record */ + if (!zone) { + log_msg(LOG_ERR, "zone configured as '%s' has no content.", name); + state.errors++; + } else if (!zone->soa_rrset || zone->soa_rrset->rr_count == 0) { + log_msg(LOG_ERR, "zone configured as '%s' has no SOA record", name); + state.errors++; + } else if (dname_compare(domain_dname(zone->soa_rrset->rrs[0].owner), origin) != 0) { + log_msg(LOG_ERR, "zone configured as '%s', but SOA has owner '%s'", + name, domain_to_string(zone->soa_rrset->rrs[0].owner)); + state.errors++; } -} - -static domain_table_type* orig_domains = NULL; -static region_type* orig_region = NULL; -static region_type* orig_dbregion = NULL; - -/** setup for string parse */ -void -zonec_setup_string_parser(region_type* region, domain_table_type* domains) -{ - assert(parser); /* global parser must be setup */ - orig_domains = parser->db->domains; - orig_region = parser->region; - orig_dbregion = parser->db->region; - parser->region = region; - parser->db->region = region; - parser->db->domains = domains; - zparser_init("string", 3600, CLASS_IN, domain_dname(domains->root)); -} -/** desetup string parse */ -void -zonec_desetup_string_parser(void) -{ - parser->region = orig_region; - parser->db->domains = orig_domains; - parser->db->region = orig_dbregion; -} - -/** parse a string into temporary storage */ -int -zonec_parse_string(region_type* region, domain_table_type* domains, - zone_type* zone, char* str, domain_type** parsed, int* num_rrs) -{ - int errors; - zonec_setup_string_parser(region, domains); - parser->current_zone = zone; - parser->errors = 0; - totalrrs = 0; - startzonec = time(NULL)+100000; /* disable */ - parser_push_stringbuf(str); - yyparse(); - parser_pop_stringbuf(); - errors = parser->errors; - *num_rrs = totalrrs; - if(*num_rrs == 0) - *parsed = NULL; - else *parsed = parser->prev_dname; - /* remove origin if it was not used during the parse */ - if(parser->origin != error_domain) - domain_table_deldomain(parser->db, parser->origin); - region_free_all(parser->rr_region); - zonec_desetup_string_parser(); - parser_flush(); - return errors; -} + if(!zone_is_slave(zone->opts) && !check_dname(zone)) + state.errors++; -/** check SSHFP type for failures and emit warnings */ -void check_sshfp(void) -{ - uint8_t hash; - uint16_t size; - if(parser->current_rr.rdata_count < 3) - return; /* cannot check it, too few rdata elements */ - if(!parser->current_rr.rdatas[0].data || - !parser->current_rr.rdatas[1].data || - !parser->current_rr.rdatas[2].data || - !parser->current_rr.owner) - return; /* cannot check, NULLs (due to earlier errors) */ - if(rdata_atom_size(parser->current_rr.rdatas[1]) != 1) - return; /* wrong size of the hash type rdata element */ - hash = rdata_atom_data(parser->current_rr.rdatas[1])[0]; - size = rdata_atom_size(parser->current_rr.rdatas[2]); - if(hash == 1 && size != 20) { - zc_warning_prev_line("SSHFP %s of type SHA1 has hash of " - "wrong length, %d bytes, should be 20", - domain_to_string(parser->current_rr.owner), - (int)size); - } else if(hash == 2 && size != 32) { - zc_warning_prev_line("SSHFP %s of type SHA256 has hash of " - "wrong length, %d bytes, should be 32", - domain_to_string(parser->current_rr.owner), - (int)size); - } + region_destroy(state.rr_region); + return state.errors; } void diff --git a/zonec.h b/zonec.h index d4db32e0f..2f51be436 100644 --- a/zonec.h +++ b/zonec.h @@ -12,10 +12,6 @@ #include "namedb.h" -#define MAXTOKENSLEN 512 /* Maximum number of tokens per entry */ -#define B64BUFSIZE 65535 /* Buffer size for b64 conversion */ -#define ROOT (const uint8_t *)"\001" - #define NSEC_WINDOW_COUNT 256 #define NSEC_WINDOW_BITS_COUNT 256 #define NSEC_WINDOW_BITS_SIZE (NSEC_WINDOW_BITS_COUNT / 8) @@ -27,124 +23,17 @@ #define LINEBUFSZ 1024 -struct lex_data { - size_t len; /* holds the label length */ - char *str; /* holds the data */ -}; - #define DEFAULT_TTL 3600 -/* administration struct */ -typedef struct zparser zparser_type; -struct zparser { - region_type *region; /* Allocate for parser lifetime data. */ - region_type *rr_region; /* Allocate RR lifetime data. */ - namedb_type *db; - - const char *filename; - uint32_t default_ttl; - uint16_t default_class; - zone_type *current_zone; - domain_type *origin; - domain_type *prev_dname; - - int error_occurred; - unsigned int errors; - unsigned int line; - - rr_type current_rr; - rdata_atom_type *temporary_rdatas; -}; - -extern zparser_type *parser; - -/* used in zonec.lex */ -extern FILE *yyin; - -/* - * Used to mark bad domains and domain names. Do not dereference - * these pointers! - */ -extern const dname_type *error_dname; -extern domain_type *error_domain; - -int yyparse(void); -int yylex(void); -int yylex_destroy(void); -/*int yyerror(const char *s);*/ -void yyrestart(FILE *); - -void zc_warning(const char *fmt, ...) ATTR_FORMAT(printf, 1, 2); -void zc_warning_prev_line(const char *fmt, ...) ATTR_FORMAT(printf, 1, 2); -void zc_error(const char *fmt, ...) ATTR_FORMAT(printf, 1, 2); -void zc_error_prev_line(const char *fmt, ...) ATTR_FORMAT(printf, 1, 2); - -void parser_push_stringbuf(char* str); -void parser_pop_stringbuf(void); -void parser_flush(void); - -int process_rr(void); -uint16_t *zparser_conv_hex(region_type *region, const char *hex, size_t len); -uint16_t *zparser_conv_hex_length(region_type *region, const char *hex, size_t len); -uint16_t *zparser_conv_time(region_type *region, const char *time); -uint16_t *zparser_conv_services(region_type *region, const char *protostr, char *servicestr); -uint16_t *zparser_conv_serial(region_type *region, const char *periodstr); -uint16_t *zparser_conv_period(region_type *region, const char *periodstr); -uint16_t *zparser_conv_short(region_type *region, const char *text); -uint16_t *zparser_conv_long(region_type *region, const char *text); -uint16_t *zparser_conv_byte(region_type *region, const char *text); -uint16_t *zparser_conv_a(region_type *region, const char *text); -uint16_t *zparser_conv_aaaa(region_type *region, const char *text); -uint16_t *zparser_conv_ilnp64(region_type *region, const char *text); -uint16_t *zparser_conv_eui(region_type *region, const char *text, size_t len); -uint16_t *zparser_conv_text(region_type *region, const char *text, size_t len); -uint16_t *zparser_conv_long_text(region_type *region, const char *text, size_t len); -uint16_t *zparser_conv_tag(region_type *region, const char *text, size_t len); -uint16_t *zparser_conv_dns_name(region_type *region, const uint8_t* name, size_t len); -uint16_t *zparser_conv_b32(region_type *region, const char *b32); -uint16_t *zparser_conv_b64(region_type *region, const char *b64); -uint16_t *zparser_conv_rrtype(region_type *region, const char *rr); -uint16_t *zparser_conv_nxt(region_type *region, uint8_t nxtbits[]); -uint16_t *zparser_conv_nsec(region_type *region, uint8_t nsecbits[NSEC_WINDOW_COUNT][NSEC_WINDOW_BITS_SIZE]); -uint16_t *zparser_conv_loc(region_type *region, char *str); -uint16_t *zparser_conv_algorithm(region_type *region, const char *algstr); -uint16_t *zparser_conv_certificate_type(region_type *region, - const char *typestr); -uint16_t *zparser_conv_apl_rdata(region_type *region, char *str); -uint16_t *zparser_conv_svcbparam(region_type *region, - const char *key, size_t key_len, const char *value, size_t value_len); - -void parse_unknown_rdata(uint16_t type, uint16_t *wireformat); - -uint32_t zparser_ttl2int(const char *ttlstr, int* error); -void zadd_rdata_wireformat(uint16_t *data); -void zadd_rdata_txt_wireformat(uint16_t *data, int first); -void zadd_rdata_txt_clean_wireformat(void); -void zadd_rdata_svcb_check_wireformat(void); -void zadd_rdata_domain(domain_type *domain); - -void set_bitnsec(uint8_t bits[NSEC_WINDOW_COUNT][NSEC_WINDOW_BITS_SIZE], - uint16_t index); -uint16_t *alloc_rdata_init(region_type *region, const void *data, size_t size); - -/* zparser.y */ -zparser_type *zparser_create(region_type *region, region_type *rr_region, - namedb_type *db); -void zparser_init(const char *filename, uint32_t ttl, uint16_t klass, - const dname_type *origin); - -/* parser start and stop to parse a zone */ -void zonec_setup_parser(namedb_type* db); -void zonec_desetup_parser(void); /* parse a zone into memory. name is origin. zonefile is file to read. * returns number of errors; failure may have read a partial zone */ -unsigned int zonec_read(const char *name, const char *zonefile, zone_type* zone); -/* parse a string into the region. and with given domaintable. global parser - * is restored afterwards. zone needs apex set. returns last domain name - * parsed and the number rrs parse. return number of errors, 0 is success. - * The string must end with a newline after the RR. */ -int zonec_parse_string(region_type* region, domain_table_type* domains, - zone_type* zone, char* str, domain_type** parsed, int* num_rrs); +unsigned int zonec_read( + struct namedb *database, + struct domain_table *domains, + const char *name, + const char *zonefile, + struct zone *zone); + /** check SSHFP type for failures and emit warnings */ void check_sshfp(void); void apex_rrset_checks(struct namedb* db, rrset_type* rrset, diff --git a/zparser.y b/zparser.y deleted file mode 100644 index 79cd61018..000000000 --- a/zparser.y +++ /dev/null @@ -1,1363 +0,0 @@ -%{ -/* - * zyparser.y -- yacc grammar for (DNS) zone files - * - * Copyright (c) 2001-2006, NLnet Labs. All rights reserved. - * - * See LICENSE for the license. - * - */ - -#include "config.h" - -#include -#include -#include - -#include "dname.h" -#include "namedb.h" -#include "zonec.h" - -/* these need to be global, otherwise they cannot be used inside yacc */ -zparser_type *parser; - -#ifdef __cplusplus -extern "C" -#endif /* __cplusplus */ -int yywrap(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 yyerror(const char *message); - -#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 */ - -%} -%union { - domain_type *domain; - const dname_type *dname; - struct lex_data data; - uint32_t ttl; - uint16_t klass; - uint16_t type; - uint16_t *unknown; -} - -/* - * Tokens to represent the known RR types of DNS. - */ -%token T_A T_NS T_MX T_TXT T_CNAME T_AAAA T_PTR T_NXT T_KEY T_SOA T_SIG -%token T_SRV T_CERT T_LOC T_MD T_MF T_MB T_MG T_MR T_NULL T_WKS T_HINFO -%token T_MINFO T_RP T_AFSDB T_X25 T_ISDN T_RT T_NSAP T_NSAP_PTR T_PX -%token T_GPOS T_EID T_NIMLOC T_ATMA T_NAPTR T_KX T_A6 T_DNAME T_SINK -%token T_OPT T_APL T_UINFO T_UID T_GID T_UNSPEC T_TKEY T_TSIG T_IXFR -%token T_AXFR T_MAILB T_MAILA T_DS T_DLV T_SSHFP T_RRSIG T_NSEC T_DNSKEY -%token T_SPF T_NSEC3 T_IPSECKEY T_DHCID T_NSEC3PARAM T_TLSA T_URI -%token T_NID T_L32 T_L64 T_LP T_EUI48 T_EUI64 T_CAA T_CDS T_CDNSKEY -%token T_OPENPGPKEY T_CSYNC T_ZONEMD T_AVC T_SMIMEA T_SVCB T_HTTPS - -/* other tokens */ -%token DOLLAR_TTL DOLLAR_ORIGIN NL SP -%token QSTR STR PREV BITLAB -%token T_TTL -%token T_RRCLASS - -/* unknown RRs */ -%token URR -%token T_UTYPE - -%type type_and_rdata -%type owner dname abs_dname -%type rel_dname label -%type wire_dname wire_abs_dname wire_rel_dname wire_label -%type str concatenated_str_seq str_sp_seq str_dot_seq -%type unquoted_dotted_str dotted_str svcparam svcparams -%type nxt_seq nsec_more -%type rdata_unknown - -%% -lines: /* empty file */ - | lines line - ; - -line: NL - | sp NL - | PREV NL {} /* Lines containing only whitespace. */ - | ttl_directive - { - region_free_all(parser->rr_region); - parser->current_rr.type = 0; - parser->current_rr.rdata_count = 0; - parser->current_rr.rdatas = parser->temporary_rdatas; - parser->error_occurred = 0; - } - | origin_directive - { - region_free_all(parser->rr_region); - parser->current_rr.type = 0; - parser->current_rr.rdata_count = 0; - parser->current_rr.rdatas = parser->temporary_rdatas; - parser->error_occurred = 0; - } - | rr - { /* rr should be fully parsed */ - if (!parser->error_occurred) { - parser->current_rr.rdatas - =(rdata_atom_type *)region_alloc_array_init( - parser->region, - parser->current_rr.rdatas, - parser->current_rr.rdata_count, - sizeof(rdata_atom_type)); - - process_rr(); - } - - region_free_all(parser->rr_region); - - parser->current_rr.type = 0; - parser->current_rr.rdata_count = 0; - parser->current_rr.rdatas = parser->temporary_rdatas; - parser->error_occurred = 0; - } - | error NL - ; - -/* needed to cope with ( and ) in arbitrary places */ -sp: SP - | sp SP - ; - -str: STR | QSTR; - -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; - } - } - ; - -origin_directive: DOLLAR_ORIGIN sp abs_dname trail - { - /* if previous origin is unused, remove it, do not leak it */ - if(parser->origin != error_domain && parser->origin != $3) { - /* protect $3 from deletion, because deldomain walks up */ - $3->usage ++; - domain_table_deldomain(parser->db, parser->origin); - $3->usage --; - } - parser->origin = $3; - } - | DOLLAR_ORIGIN sp rel_dname trail - { - zc_error_prev_line("$ORIGIN directive requires absolute domain name"); - } - ; - -rr: owner classttl type_and_rdata - { - parser->current_rr.owner = $1; - parser->current_rr.type = $3; - } - ; - -owner: dname sp - { - parser->prev_dname = $1; - $$ = $1; - } - | PREV - { - $$ = parser->prev_dname; - } - ; - -classttl: /* empty - fill in the default, def. ttl and IN class */ - { - parser->current_rr.ttl = parser->default_ttl; - parser->current_rr.klass = parser->default_class; - } - | T_RRCLASS sp /* no ttl */ - { - parser->current_rr.ttl = parser->default_ttl; - parser->current_rr.klass = $1; - } - | T_TTL sp /* no class */ - { - parser->current_rr.ttl = $1; - parser->current_rr.klass = parser->default_class; - } - | T_TTL sp T_RRCLASS sp /* the lot */ - { - parser->current_rr.ttl = $1; - parser->current_rr.klass = $3; - } - | T_RRCLASS sp T_TTL sp /* the lot - reversed */ - { - parser->current_rr.ttl = $3; - parser->current_rr.klass = $1; - } - ; - -dname: abs_dname - | rel_dname - { - if ($1 == error_dname) { - $$ = error_domain; - } else if(parser->origin == error_domain) { - zc_error("cannot concatenate origin to domain name, because origin failed to parse"); - $$ = error_domain; - } else if ($1->name_size + domain_dname(parser->origin)->name_size - 1 > MAXDOMAINLEN) { - zc_error("domain name exceeds %d character limit", MAXDOMAINLEN); - $$ = error_domain; - } else { - $$ = domain_table_insert( - parser->db->domains, - dname_concatenate( - parser->rr_region, - $1, - domain_dname(parser->origin))); - } - } - ; - -abs_dname: '.' - { - $$ = parser->db->domains->root; - } - | '@' - { - $$ = parser->origin; - } - | rel_dname '.' - { - if ($1 != error_dname) { - $$ = domain_table_insert(parser->db->domains, $1); - } else { - $$ = error_domain; - } - } - ; - -label: str - { - if ($1.len > MAXLABELLEN) { - zc_error("label exceeds %d character limit", MAXLABELLEN); - $$ = error_dname; - } else if ($1.len <= 0) { - zc_error("zero label length"); - $$ = error_dname; - } else { - $$ = dname_make_from_label(parser->rr_region, - (uint8_t *) $1.str, - $1.len); - } - } - | BITLAB - { - zc_error("bitlabels are now deprecated. RFC2673 is obsoleted."); - $$ = error_dname; - } - ; - -rel_dname: label - | rel_dname '.' label - { - if ($1 == error_dname || $3 == error_dname) { - $$ = error_dname; - } else if ($1->name_size + $3->name_size - 1 > MAXDOMAINLEN) { - zc_error("domain name exceeds %d character limit", - MAXDOMAINLEN); - $$ = error_dname; - } else { - $$ = dname_concatenate(parser->rr_region, $1, $3); - } - } - ; - -/* - * Some dnames in rdata are handled as opaque blobs - */ - -wire_dname: wire_abs_dname - | wire_rel_dname - { - /* terminate in root label and copy the origin in there */ - if(parser->origin && domain_dname(parser->origin)) { - $$.len = $1.len + domain_dname(parser->origin)->name_size; - if ($$.len > MAXDOMAINLEN) - zc_error("domain name exceeds %d character limit", - MAXDOMAINLEN); - $$.str = (char *) region_alloc(parser->rr_region, $$.len); - memmove($$.str, $1.str, $1.len); - memmove($$.str + $1.len, dname_name(domain_dname(parser->origin)), - domain_dname(parser->origin)->name_size); - } else { - $$.len = $1.len + 1; - if ($$.len > MAXDOMAINLEN) - zc_error("domain name exceeds %d character limit", - MAXDOMAINLEN); - $$.str = (char *) region_alloc(parser->rr_region, $$.len); - memmove($$.str, $1.str, $1.len); - $$.str[ $1.len ] = 0; - } - } - ; - -wire_abs_dname: '.' - { - char *result = (char *) region_alloc(parser->rr_region, 1); - result[0] = 0; - $$.str = result; - $$.len = 1; - } - | '@' - { - if(parser->origin && domain_dname(parser->origin)) { - $$.len = domain_dname(parser->origin)->name_size; - $$.str = (char *) region_alloc(parser->rr_region, $$.len); - memmove($$.str, dname_name(domain_dname(parser->origin)), $$.len); - } else { - $$.len = 1; - $$.str = (char *) region_alloc(parser->rr_region, $$.len); - $$.str[0] = 0; - } - } - | wire_rel_dname '.' - { - $$.len = $1.len + 1; - if ($$.len > MAXDOMAINLEN) - zc_error("domain name exceeds %d character limit", - MAXDOMAINLEN); - $$.str = (char *) region_alloc(parser->rr_region, $$.len); - memcpy($$.str, $1.str, $1.len); - $$.str[$1.len] = 0; - } - ; - -wire_label: str - { - char *result = (char *) region_alloc(parser->rr_region, - $1.len + 1); - - if ($1.len > MAXLABELLEN) - zc_error("label exceeds %d character limit", MAXLABELLEN); - - /* make label anyway */ - result[0] = $1.len; - memmove(result+1, $1.str, $1.len); - - $$.str = result; - $$.len = $1.len + 1; - } - ; - -wire_rel_dname: wire_label - | wire_rel_dname '.' wire_label - { - $$.len = $1.len + $3.len; - if ($$.len > MAXDOMAINLEN) - zc_error("domain name exceeds %d character limit", - MAXDOMAINLEN); - $$.str = (char *) region_alloc(parser->rr_region, $$.len); - memmove($$.str, $1.str, $1.len); - memmove($$.str + $1.len, $3.str, $3.len); - } - ; - -str_seq: unquoted_dotted_str - { - zadd_rdata_txt_wireformat(zparser_conv_text(parser->rr_region, $1.str, $1.len), 1); - } - | QSTR - { - zadd_rdata_txt_wireformat(zparser_conv_text(parser->rr_region, $1.str, $1.len), 1); - } - | QSTR unquoted_dotted_str - { - zadd_rdata_txt_wireformat(zparser_conv_text(parser->rr_region, $1.str, $1.len), 1); - zadd_rdata_txt_wireformat(zparser_conv_text(parser->rr_region, $2.str, $2.len), 0); - } - | str_seq QSTR - { - zadd_rdata_txt_wireformat(zparser_conv_text(parser->rr_region, $2.str, $2.len), 0); - } - | str_seq QSTR unquoted_dotted_str - { - zadd_rdata_txt_wireformat(zparser_conv_text(parser->rr_region, $2.str, $2.len), 0); - zadd_rdata_txt_wireformat(zparser_conv_text(parser->rr_region, $3.str, $3.len), 0); - } - | str_seq sp unquoted_dotted_str - { - zadd_rdata_txt_wireformat(zparser_conv_text(parser->rr_region, $3.str, $3.len), 0); - } - | str_seq sp QSTR - { - zadd_rdata_txt_wireformat(zparser_conv_text(parser->rr_region, $3.str, $3.len), 0); - } - | str_seq sp QSTR unquoted_dotted_str - { - zadd_rdata_txt_wireformat(zparser_conv_text(parser->rr_region, $3.str, $3.len), 0); - zadd_rdata_txt_wireformat(zparser_conv_text(parser->rr_region, $4.str, $4.len), 0); - } - ; - -/* - * Generate a single string from multiple STR tokens, separated by - * spaces or dots. - */ -concatenated_str_seq: str - | '.' - { - $$.len = 1; - $$.str = region_strdup(parser->rr_region, "."); - } - | concatenated_str_seq sp str - { - $$.len = $1.len + $3.len + 1; - $$.str = (char *) region_alloc(parser->rr_region, $$.len + 1); - memcpy($$.str, $1.str, $1.len); - memcpy($$.str + $1.len, " ", 1); - memcpy($$.str + $1.len + 1, $3.str, $3.len); - $$.str[$$.len] = '\0'; - } - | concatenated_str_seq '.' str - { - $$.len = $1.len + $3.len + 1; - $$.str = (char *) region_alloc(parser->rr_region, $$.len + 1); - memcpy($$.str, $1.str, $1.len); - memcpy($$.str + $1.len, ".", 1); - memcpy($$.str + $1.len + 1, $3.str, $3.len); - $$.str[$$.len] = '\0'; - } - ; - -/* used to convert a nxt list of types */ -nxt_seq: str - { - uint16_t type = 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); - } - } - | nxt_seq sp str - { - uint16_t type = 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); - } - } - ; - -nsec_more: SP nsec_more - { - } - | NL - { - } - | str nsec_seq - { - uint16_t type = 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); - } - } - ; - -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 = (char *) region_alloc(parser->rr_region, - $1.len + $3.len + 1); - memcpy(result, $1.str, $1.len); - memcpy(result + $1.len, $3.str, $3.len); - $$.str = result; - $$.len = $1.len + $3.len; - $$.str[$$.len] = '\0'; - } - ; - -/* - * Sequence of STR tokens separated by dots. The dots are not - * preserved during concatenation. - */ -str_dot_seq: str - | str_dot_seq '.' str - { - char *result = (char *) region_alloc(parser->rr_region, - $1.len + $3.len + 1); - memcpy(result, $1.str, $1.len); - memcpy(result + $1.len, $3.str, $3.len); - $$.str = result; - $$.len = $1.len + $3.len; - $$.str[$$.len] = '\0'; - } - ; - -/* - * A string that can contain dots. - */ -unquoted_dotted_str: STR - | '.' - { - $$.str = "."; - $$.len = 1; - } - | unquoted_dotted_str '.' - { - char *result = (char *) region_alloc(parser->rr_region, - $1.len + 2); - memcpy(result, $1.str, $1.len); - result[$1.len] = '.'; - $$.str = result; - $$.len = $1.len + 1; - $$.str[$$.len] = '\0'; - } - | unquoted_dotted_str '.' STR - { - char *result = (char *) region_alloc(parser->rr_region, - $1.len + $3.len + 2); - 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'; - } - ; - -/* - * A string that can contain dots or a quoted string. - */ -dotted_str: unquoted_dotted_str | QSTR - -/* 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_AVC sp rdata_txt - | T_AVC 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); check_sshfp(); } - | 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_DNSKEY sp rdata_dnskey - | T_DNSKEY 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_SMIMEA sp rdata_smimea - | T_SMIMEA sp rdata_unknown { $$ = $1; parse_unknown_rdata($1, $3); } - | T_NID sp rdata_nid - | T_NID sp rdata_unknown { $$ = $1; parse_unknown_rdata($1, $3); } - | T_L32 sp rdata_l32 - | T_L32 sp rdata_unknown { $$ = $1; parse_unknown_rdata($1, $3); } - | T_L64 sp rdata_l64 - | T_L64 sp rdata_unknown { $$ = $1; parse_unknown_rdata($1, $3); } - | T_LP sp rdata_lp - | T_LP sp rdata_unknown { $$ = $1; parse_unknown_rdata($1, $3); } - | T_EUI48 sp rdata_eui48 - | T_EUI48 sp rdata_unknown { $$ = $1; parse_unknown_rdata($1, $3); } - | T_EUI64 sp rdata_eui64 - | T_EUI64 sp rdata_unknown { $$ = $1; parse_unknown_rdata($1, $3); } - | T_CAA sp rdata_caa - | T_CAA sp rdata_unknown { $$ = $1; parse_unknown_rdata($1, $3); } - | T_CDS sp rdata_ds - | T_CDS sp rdata_unknown { $$ = $1; parse_unknown_rdata($1, $3); } - | T_CDNSKEY sp rdata_dnskey - | T_CDNSKEY sp rdata_unknown { $$ = $1; parse_unknown_rdata($1, $3); } - | T_OPENPGPKEY sp rdata_openpgpkey - | T_OPENPGPKEY sp rdata_unknown { $$ = $1; parse_unknown_rdata($1, $3); } - | T_CSYNC sp rdata_csync - | T_CSYNC sp rdata_unknown { $$ = $1; parse_unknown_rdata($1, $3); } - | T_ZONEMD sp rdata_zonemd - | T_ZONEMD sp rdata_unknown { $$ = $1; parse_unknown_rdata($1, $3); } - | T_SVCB sp rdata_svcb - | T_SVCB sp rdata_unknown { $$ = $1; parse_unknown_rdata($1, $3); } - | T_HTTPS sp rdata_svcb - | T_HTTPS sp rdata_unknown { $$ = $1; parse_unknown_rdata($1, $3); } - | T_URI sp rdata_uri - | T_URI 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); - } - ; - -/* - * - * below are all the definition for all the different rdata - * - */ - -rdata_a: dotted_str trail - { - zadd_rdata_wireformat(zparser_conv_a(parser->region, $1.str)); - } - ; - -rdata_domain_name: dname trail - { - /* convert a single dname record */ - zadd_rdata_domain($1); - } - ; - -rdata_soa: dname sp dname sp str sp str sp str sp str sp str trail - { - /* convert the soa data */ - zadd_rdata_domain($1); /* prim. ns */ - zadd_rdata_domain($3); /* email */ - zadd_rdata_wireformat(zparser_conv_serial(parser->region, $5.str)); /* serial */ - zadd_rdata_wireformat(zparser_conv_period(parser->region, $7.str)); /* refresh */ - zadd_rdata_wireformat(zparser_conv_period(parser->region, $9.str)); /* retry */ - zadd_rdata_wireformat(zparser_conv_period(parser->region, $11.str)); /* expire */ - zadd_rdata_wireformat(zparser_conv_period(parser->region, $13.str)); /* minimum */ - } - ; - -rdata_wks: dotted_str sp str sp concatenated_str_seq trail - { - zadd_rdata_wireformat(zparser_conv_a(parser->region, $1.str)); /* address */ - zadd_rdata_wireformat(zparser_conv_services(parser->region, $3.str, $5.str)); /* protocol and services */ - } - ; - -rdata_hinfo: str sp str trail - { - zadd_rdata_wireformat(zparser_conv_text(parser->region, $1.str, $1.len)); /* CPU */ - zadd_rdata_wireformat(zparser_conv_text(parser->region, $3.str, $3.len)); /* OS*/ - } - ; - -rdata_minfo: dname sp dname trail - { - /* convert a single dname record */ - zadd_rdata_domain($1); - zadd_rdata_domain($3); - } - ; - -rdata_mx: str sp dname trail - { - zadd_rdata_wireformat(zparser_conv_short(parser->region, $1.str)); /* priority */ - zadd_rdata_domain($3); /* MX host */ - } - ; - -rdata_txt: str_seq trail - { - zadd_rdata_txt_clean_wireformat(); - } - ; - -/* RFC 1183 */ -rdata_rp: dname sp dname trail - { - zadd_rdata_domain($1); /* mbox d-name */ - zadd_rdata_domain($3); /* txt d-name */ - } - ; - -/* RFC 1183 */ -rdata_afsdb: str sp dname trail - { - zadd_rdata_wireformat(zparser_conv_short(parser->region, $1.str)); /* subtype */ - zadd_rdata_domain($3); /* domain name */ - } - ; - -/* RFC 1183 */ -rdata_x25: str trail - { - zadd_rdata_wireformat(zparser_conv_text(parser->region, $1.str, $1.len)); /* X.25 address. */ - } - ; - -/* RFC 1183 */ -rdata_isdn: str trail - { - zadd_rdata_wireformat(zparser_conv_text(parser->region, $1.str, $1.len)); /* address */ - } - | str sp str trail - { - zadd_rdata_wireformat(zparser_conv_text(parser->region, $1.str, $1.len)); /* address */ - zadd_rdata_wireformat(zparser_conv_text(parser->region, $3.str, $3.len)); /* sub-address */ - } - ; - -/* RFC 1183 */ -rdata_rt: str sp dname trail - { - zadd_rdata_wireformat(zparser_conv_short(parser->region, $1.str)); /* preference */ - zadd_rdata_domain($3); /* intermediate host */ - } - ; - -/* 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(parser->region, $1.str + 2, $1.len - 2)); /* NSAP */ - } - } - ; - -/* RFC 2163 */ -rdata_px: str sp dname sp dname trail - { - zadd_rdata_wireformat(zparser_conv_short(parser->region, $1.str)); /* preference */ - zadd_rdata_domain($3); /* MAP822 */ - zadd_rdata_domain($5); /* MAPX400 */ - } - ; - -rdata_aaaa: dotted_str trail - { - zadd_rdata_wireformat(zparser_conv_aaaa(parser->region, $1.str)); /* IPv6 address */ - } - ; - -rdata_loc: concatenated_str_seq trail - { - zadd_rdata_wireformat(zparser_conv_loc(parser->region, $1.str)); /* Location */ - } - ; - -rdata_nxt: dname sp nxt_seq trail - { - zadd_rdata_domain($1); /* nxt name */ - zadd_rdata_wireformat(zparser_conv_nxt(parser->region, nxtbits)); /* nxt bitlist */ - memset(nxtbits, 0, sizeof(nxtbits)); - } - ; - -rdata_srv: str sp str sp str sp dname trail - { - zadd_rdata_wireformat(zparser_conv_short(parser->region, $1.str)); /* prio */ - zadd_rdata_wireformat(zparser_conv_short(parser->region, $3.str)); /* weight */ - zadd_rdata_wireformat(zparser_conv_short(parser->region, $5.str)); /* port */ - zadd_rdata_domain($7); /* target name */ - } - ; - -/* RFC 2915 */ -rdata_naptr: str sp str sp str sp str sp str sp dname trail - { - zadd_rdata_wireformat(zparser_conv_short(parser->region, $1.str)); /* order */ - zadd_rdata_wireformat(zparser_conv_short(parser->region, $3.str)); /* preference */ - zadd_rdata_wireformat(zparser_conv_text(parser->region, $5.str, $5.len)); /* flags */ - zadd_rdata_wireformat(zparser_conv_text(parser->region, $7.str, $7.len)); /* service */ - zadd_rdata_wireformat(zparser_conv_text(parser->region, $9.str, $9.len)); /* regexp */ - zadd_rdata_domain($11); /* target name */ - } - ; - -/* RFC 2230 */ -rdata_kx: str sp dname trail - { - zadd_rdata_wireformat(zparser_conv_short(parser->region, $1.str)); /* preference */ - zadd_rdata_domain($3); /* exchanger */ - } - ; - -/* RFC 2538 */ -rdata_cert: str sp str sp str sp str_sp_seq trail - { - zadd_rdata_wireformat(zparser_conv_certificate_type(parser->region, $1.str)); /* type */ - zadd_rdata_wireformat(zparser_conv_short(parser->region, $3.str)); /* key tag */ - zadd_rdata_wireformat(zparser_conv_algorithm(parser->region, $5.str)); /* algorithm */ - zadd_rdata_wireformat(zparser_conv_b64(parser->region, $7.str)); /* certificate or CRL */ - } - ; - -/* RFC 3123 */ -rdata_apl: rdata_apl_seq trail - ; - -rdata_apl_seq: dotted_str - { - zadd_rdata_wireformat(zparser_conv_apl_rdata(parser->region, $1.str)); - } - | rdata_apl_seq sp dotted_str - { - zadd_rdata_wireformat(zparser_conv_apl_rdata(parser->region, $3.str)); - } - ; - -rdata_ds: str sp str sp str sp str_sp_seq trail - { - zadd_rdata_wireformat(zparser_conv_short(parser->region, $1.str)); /* keytag */ - zadd_rdata_wireformat(zparser_conv_algorithm(parser->region, $3.str)); /* alg */ - zadd_rdata_wireformat(zparser_conv_byte(parser->region, $5.str)); /* type */ - zadd_rdata_wireformat(zparser_conv_hex(parser->region, $7.str, $7.len)); /* hash */ - } - ; - -rdata_dlv: str sp str sp str sp str_sp_seq trail - { - zadd_rdata_wireformat(zparser_conv_short(parser->region, $1.str)); /* keytag */ - zadd_rdata_wireformat(zparser_conv_algorithm(parser->region, $3.str)); /* alg */ - zadd_rdata_wireformat(zparser_conv_byte(parser->region, $5.str)); /* type */ - zadd_rdata_wireformat(zparser_conv_hex(parser->region, $7.str, $7.len)); /* hash */ - } - ; - -rdata_sshfp: str sp str sp str_sp_seq trail - { - zadd_rdata_wireformat(zparser_conv_byte(parser->region, $1.str)); /* alg */ - zadd_rdata_wireformat(zparser_conv_byte(parser->region, $3.str)); /* fp type */ - zadd_rdata_wireformat(zparser_conv_hex(parser->region, $5.str, $5.len)); /* hash */ - check_sshfp(); - } - ; - -rdata_dhcid: str_sp_seq trail - { - zadd_rdata_wireformat(zparser_conv_b64(parser->region, $1.str)); /* data blob */ - } - ; - -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(parser->region, $1.str)); /* rr covered */ - zadd_rdata_wireformat(zparser_conv_algorithm(parser->region, $3.str)); /* alg */ - zadd_rdata_wireformat(zparser_conv_byte(parser->region, $5.str)); /* # labels */ - zadd_rdata_wireformat(zparser_conv_period(parser->region, $7.str)); /* # orig TTL */ - zadd_rdata_wireformat(zparser_conv_time(parser->region, $9.str)); /* sig exp */ - zadd_rdata_wireformat(zparser_conv_time(parser->region, $11.str)); /* sig inc */ - zadd_rdata_wireformat(zparser_conv_short(parser->region, $13.str)); /* key id */ - zadd_rdata_wireformat(zparser_conv_dns_name(parser->region, - (const uint8_t*) $15.str,$15.len)); /* sig name */ - zadd_rdata_wireformat(zparser_conv_b64(parser->region, $17.str)); /* sig data */ - } - ; - -rdata_nsec: wire_dname nsec_seq - { - zadd_rdata_wireformat(zparser_conv_dns_name(parser->region, - (const uint8_t*) $1.str, $1.len)); /* nsec name */ - zadd_rdata_wireformat(zparser_conv_nsec(parser->region, 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); - - zadd_rdata_wireformat(zparser_conv_b32(parser->region, $9.str)); /* next hashed name */ - zadd_rdata_wireformat(zparser_conv_nsec(parser->region, nsecbits)); /* nsec bitlist */ - memset(nsecbits, 0, sizeof(nsecbits)); - nsec_highest_rcode = 0; -#else - zc_error_prev_line("nsec3 not supported"); -#endif /* NSEC3 */ - } - ; - -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 */ - } - ; - -rdata_tlsa: str sp str sp str sp str_sp_seq trail - { - zadd_rdata_wireformat(zparser_conv_byte(parser->region, $1.str)); /* usage */ - zadd_rdata_wireformat(zparser_conv_byte(parser->region, $3.str)); /* selector */ - zadd_rdata_wireformat(zparser_conv_byte(parser->region, $5.str)); /* matching type */ - zadd_rdata_wireformat(zparser_conv_hex(parser->region, $7.str, $7.len)); /* ca data */ - } - ; - -rdata_smimea: str sp str sp str sp str_sp_seq trail - { - zadd_rdata_wireformat(zparser_conv_byte(parser->region, $1.str)); /* usage */ - zadd_rdata_wireformat(zparser_conv_byte(parser->region, $3.str)); /* selector */ - zadd_rdata_wireformat(zparser_conv_byte(parser->region, $5.str)); /* matching type */ - zadd_rdata_wireformat(zparser_conv_hex(parser->region, $7.str, $7.len)); /* ca data */ - } - ; - -rdata_dnskey: str sp str sp str sp str_sp_seq trail - { - zadd_rdata_wireformat(zparser_conv_short(parser->region, $1.str)); /* flags */ - zadd_rdata_wireformat(zparser_conv_byte(parser->region, $3.str)); /* proto */ - zadd_rdata_wireformat(zparser_conv_algorithm(parser->region, $5.str)); /* alg */ - zadd_rdata_wireformat(zparser_conv_b64(parser->region, $7.str)); /* hash */ - } - ; - -rdata_ipsec_base: str sp str sp str sp dotted_str - { - const dname_type* name = 0; - zadd_rdata_wireformat(zparser_conv_byte(parser->region, $1.str)); /* precedence */ - zadd_rdata_wireformat(zparser_conv_byte(parser->region, $3.str)); /* gateway type */ - zadd_rdata_wireformat(zparser_conv_byte(parser->region, $5.str)); /* algorithm */ - switch(atoi($3.str)) { - case IPSECKEY_NOGATEWAY: - zadd_rdata_wireformat(alloc_rdata_init(parser->region, "", 0)); - break; - case IPSECKEY_IP4: - zadd_rdata_wireformat(zparser_conv_a(parser->region, $7.str)); - break; - case IPSECKEY_IP6: - zadd_rdata_wireformat(zparser_conv_aaaa(parser->region, $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"); - if(!(name = dname_parse(parser->region, $7.str))) { - zc_error_prev_line("IPSECKEY bad gateway dname %s", $7.str); - break; - } - if($7.str[strlen($7.str)-1] != '.') { - if(parser->origin == error_domain) { - zc_error("cannot concatenate origin to domain name, because origin failed to parse"); - break; - } else if(name->name_size + domain_dname(parser->origin)->name_size - 1 > MAXDOMAINLEN) { - zc_error("ipsec gateway name exceeds %d character limit", - MAXDOMAINLEN); - break; - } - name = dname_concatenate(parser->rr_region, name, - domain_dname(parser->origin)); - } - zadd_rdata_wireformat(alloc_rdata_init(parser->region, - dname_name(name), name->name_size)); - 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(parser->region, $3.str)); /* public key */ - } - | rdata_ipsec_base trail - ; - -/* RFC 6742 */ -rdata_nid: str sp dotted_str trail - { - zadd_rdata_wireformat(zparser_conv_short(parser->region, $1.str)); /* preference */ - zadd_rdata_wireformat(zparser_conv_ilnp64(parser->region, $3.str)); /* NodeID */ - } - ; - -rdata_l32: str sp dotted_str trail - { - zadd_rdata_wireformat(zparser_conv_short(parser->region, $1.str)); /* preference */ - zadd_rdata_wireformat(zparser_conv_a(parser->region, $3.str)); /* Locator32 */ - } - ; - -rdata_l64: str sp dotted_str trail - { - zadd_rdata_wireformat(zparser_conv_short(parser->region, $1.str)); /* preference */ - zadd_rdata_wireformat(zparser_conv_ilnp64(parser->region, $3.str)); /* Locator64 */ - } - ; - -rdata_lp: str sp dname trail - { - zadd_rdata_wireformat(zparser_conv_short(parser->region, $1.str)); /* preference */ - zadd_rdata_domain($3); /* FQDN */ - } - ; - -rdata_eui48: str trail - { - zadd_rdata_wireformat(zparser_conv_eui(parser->region, $1.str, 48)); - } - ; - -rdata_eui64: str trail - { - zadd_rdata_wireformat(zparser_conv_eui(parser->region, $1.str, 64)); - } - ; - -/* RFC7553 */ -rdata_uri: str sp str sp dotted_str trail - { - zadd_rdata_wireformat(zparser_conv_short(parser->region, $1.str)); /* priority */ - zadd_rdata_wireformat(zparser_conv_short(parser->region, $3.str)); /* weight */ - zadd_rdata_wireformat(zparser_conv_long_text(parser->region, $5.str, $5.len)); /* target */ - } - ; - -/* RFC 6844 */ -rdata_caa: str sp str sp dotted_str trail - { - zadd_rdata_wireformat(zparser_conv_byte(parser->region, $1.str)); /* Flags */ - zadd_rdata_wireformat(zparser_conv_tag(parser->region, $3.str, $3.len)); /* Tag */ - zadd_rdata_wireformat(zparser_conv_long_text(parser->region, $5.str, $5.len)); /* Value */ - } - ; - -/* RFC7929 */ -rdata_openpgpkey: str_sp_seq trail - { - zadd_rdata_wireformat(zparser_conv_b64(parser->region, $1.str)); - } - ; - -/* RFC7477 */ -rdata_csync: str sp str nsec_seq - { - zadd_rdata_wireformat(zparser_conv_serial(parser->region, $1.str)); - zadd_rdata_wireformat(zparser_conv_short(parser->region, $3.str)); - zadd_rdata_wireformat(zparser_conv_nsec(parser->region, nsecbits)); /* nsec bitlist */ - memset(nsecbits, 0, sizeof(nsecbits)); - nsec_highest_rcode = 0; - } - ; - -/* draft-ietf-dnsop-dns-zone-digest */ -rdata_zonemd: str sp str sp str sp str_sp_seq trail - { - zadd_rdata_wireformat(zparser_conv_serial(parser->region, $1.str)); /* serial */ - zadd_rdata_wireformat(zparser_conv_byte(parser->region, $3.str)); /* scheme */ - zadd_rdata_wireformat(zparser_conv_byte(parser->region, $5.str)); /* hash algorithm */ - zadd_rdata_wireformat(zparser_conv_hex(parser->region, $7.str, $7.len)); /* digest */ - } - ; - -svcparam: dotted_str QSTR - { - zadd_rdata_wireformat(zparser_conv_svcbparam( - parser->region, $1.str, $1.len, $2.str, $2.len)); - } - | dotted_str - { - zadd_rdata_wireformat(zparser_conv_svcbparam( - parser->region, $1.str, $1.len, NULL, 0)); - } - ; -svcparams: svcparam - | svcparams sp svcparam - ; -/* draft-ietf-dnsop-svcb-https */ -rdata_svcb_base: str sp dname - { - /* SvcFieldPriority */ - zadd_rdata_wireformat(zparser_conv_short(parser->region, $1.str)); - /* SvcDomainName */ - zadd_rdata_domain($3); - }; -rdata_svcb: rdata_svcb_base sp svcparams trail - { - zadd_rdata_svcb_check_wireformat(); - } - | rdata_svcb_base trail - ; - -rdata_unknown: URR sp str sp str_sp_seq trail - { - /* $2 is the number of octets, currently ignored */ - $$ = zparser_conv_hex(parser->rr_region, $5.str, $5.len); - - } - | URR sp str trail - { - $$ = zparser_conv_hex(parser->rr_region, "", 0); - } - | URR error NL - { - $$ = zparser_conv_hex(parser->rr_region, "", 0); - } - ; -%% - -int -yywrap(void) -{ - return 1; -} - -/* - * Create the parser. - */ -zparser_type * -zparser_create(region_type *region, region_type *rr_region, namedb_type *db) -{ - zparser_type *result; - - result = (zparser_type *) region_alloc(region, sizeof(zparser_type)); - result->region = region; - result->rr_region = rr_region; - result->db = db; - - result->filename = NULL; - result->current_zone = NULL; - result->origin = NULL; - result->prev_dname = NULL; - - result->temporary_rdatas = (rdata_atom_type *) region_alloc_array( - result->region, MAXRDATALEN, sizeof(rdata_atom_type)); - - return result; -} - -/* - * Initialize the parser for a new zone file. - */ -void -zparser_init(const char *filename, uint32_t ttl, uint16_t klass, - const dname_type *origin) -{ - memset(nxtbits, 0, sizeof(nxtbits)); - memset(nsecbits, 0, sizeof(nsecbits)); - nsec_highest_rcode = 0; - - parser->default_ttl = ttl; - parser->default_class = klass; - parser->current_zone = NULL; - parser->origin = domain_table_insert(parser->db->domains, origin); - parser->prev_dname = parser->origin; - parser->error_occurred = 0; - parser->errors = 0; - parser->line = 1; - parser->filename = filename; - parser->current_rr.rdata_count = 0; - parser->current_rr.rdatas = parser->temporary_rdatas; -} - -void -yyerror(const char *message) -{ - zc_error("%s", message); -} - -static void -error_va_list(unsigned line, const char *fmt, va_list args) -{ - if (parser->filename) { - char message[MAXSYSLOGMSGLEN]; - vsnprintf(message, sizeof(message), fmt, args); - log_msg(LOG_ERR, "%s:%u: %s", parser->filename, line, message); - } - else log_vmsg(LOG_ERR, fmt, args); - - ++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) -{ - if (parser->filename) { - char m[MAXSYSLOGMSGLEN]; - vsnprintf(m, sizeof(m), fmt, args); - log_msg(LOG_WARNING, "%s:%u: %s", parser->filename, line, m); - } - else log_vmsg(LOG_WARNING, fmt, args); -} - -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(parser->region, hashalgo_str)); - zadd_rdata_wireformat(zparser_conv_byte(parser->region, flag_str)); - zadd_rdata_wireformat(zparser_conv_short(parser->region, iter_str)); - - /* salt */ - if(strcmp(salt_str, "-") != 0) - zadd_rdata_wireformat(zparser_conv_hex_length(parser->region, - salt_str, salt_len)); - else - zadd_rdata_wireformat(alloc_rdata_init(parser->region, "", 1)); -} -#endif /* NSEC3 */