From a903095bf4512dae561c7f6fc7854a51bebf334a Mon Sep 17 00:00:00 2001 From: Mark Andrews Date: Mon, 20 Jun 2005 01:05:33 +0000 Subject: [PATCH] 1817. [func] add support for additional zone file formats for improving loading performance. The masterfile-format option in named.conf can be used to specify a non-default format. A new separate command named-compilezone was provided to generate zone files in a new format. --- CHANGES | 7 +- bin/check/Makefile.in | 4 +- bin/check/check-tool.c | 12 +- bin/check/check-tool.h | 11 +- bin/check/named-checkconf.c | 35 +- bin/check/named-checkzone.c | 107 +++- bin/check/named-checkzone.docbook | 104 +++- bin/named/zoneconf.c | 19 +- bin/tests/system/conf.sh.in | 4 +- bin/tests/system/masterformat/clean.sh | 22 + bin/tests/system/masterformat/ns1/compile.sh | 17 + bin/tests/system/masterformat/ns1/example.db | 38 ++ bin/tests/system/masterformat/ns1/named.conf | 36 ++ bin/tests/system/masterformat/ns2/named.conf | 35 ++ bin/tests/system/masterformat/setup.sh | 19 + bin/tests/system/masterformat/tests.sh | 80 +++ configure | 30 +- configure.in | 3 +- doc/arm/Bv9ARM-book.xml | 101 +++- lib/bind9/check.c | 3 +- lib/dns/db.c | 15 +- lib/dns/include/dns/db.h | 9 +- lib/dns/include/dns/master.h | 56 ++- lib/dns/include/dns/masterdump.h | 39 +- lib/dns/include/dns/types.h | 8 +- lib/dns/include/dns/zone.h | 33 +- lib/dns/master.c | 486 +++++++++++++++++-- lib/dns/masterdump.c | 294 +++++++++-- lib/dns/rbtdb.c | 11 +- lib/dns/sdb.c | 6 +- lib/dns/zone.c | 86 ++-- lib/isccfg/namedconf.c | 9 +- make/rules.in | 3 +- 33 files changed, 1571 insertions(+), 171 deletions(-) create mode 100755 bin/tests/system/masterformat/clean.sh create mode 100755 bin/tests/system/masterformat/ns1/compile.sh create mode 100644 bin/tests/system/masterformat/ns1/example.db create mode 100644 bin/tests/system/masterformat/ns1/named.conf create mode 100644 bin/tests/system/masterformat/ns2/named.conf create mode 100755 bin/tests/system/masterformat/setup.sh create mode 100755 bin/tests/system/masterformat/tests.sh diff --git a/CHANGES b/CHANGES index 92337a6ca1..a516f81107 100644 --- a/CHANGES +++ b/CHANGES @@ -178,7 +178,12 @@ 1818. [bug] 'named-checkconf -z' triggered an INSIST. [RT #13599] -1817. [placeholder] rt13587 +1817. [func] add support for additional zone file formats for + improving loading performance. The masterfile-format + option in named.conf can be used to specify a + non-default format. A new separate command + named-compilezone was provided to generate zone files + in a new format. 1816. [port] UnixWare: failed to compile lib/isc/unix/net.c. [RT #13597] diff --git a/bin/check/Makefile.in b/bin/check/Makefile.in index 7ad13a70fe..d2dd07eeb3 100644 --- a/bin/check/Makefile.in +++ b/bin/check/Makefile.in @@ -13,7 +13,7 @@ # OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR # PERFORMANCE OF THIS SOFTWARE. -# $Id: Makefile.in,v 1.25 2004/07/20 07:13:33 marka Exp $ +# $Id: Makefile.in,v 1.26 2005/06/20 01:03:47 marka Exp $ srcdir = @srcdir@ VPATH = @srcdir@ @@ -89,7 +89,9 @@ installdirs: install:: named-checkconf@EXEEXT@ named-checkzone@EXEEXT@ installdirs ${LIBTOOL_MODE_INSTALL} ${INSTALL_PROGRAM} named-checkconf@EXEEXT@ ${DESTDIR}${sbindir} ${LIBTOOL_MODE_INSTALL} ${INSTALL_PROGRAM} named-checkzone@EXEEXT@ ${DESTDIR}${sbindir} + cd ${DESTDIR}${sbindir}; ${LINK_PROGRAM} named-checkzone@EXEEXT@ named-compilezone@EXEEXT@ for m in ${MANPAGES}; do ${INSTALL_DATA} ${srcdir}/$$m ${DESTDIR}${mandir}/man8; done + cd ${DESTDIR}${mandir}/man8; ${LINK_PROGRAM} named-checkzone.8 named-compilezone.8 clean distclean:: rm -f ${TARGETS} r1.htm diff --git a/bin/check/check-tool.c b/bin/check/check-tool.c index 305bb5eefd..0bf37db577 100644 --- a/bin/check/check-tool.c +++ b/bin/check/check-tool.c @@ -15,7 +15,7 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: check-tool.c,v 1.17 2005/05/19 04:58:59 marka Exp $ */ +/* $Id: check-tool.c,v 1.18 2005/06/20 01:03:48 marka Exp $ */ /*! \file */ @@ -389,7 +389,8 @@ setup_logging(isc_mem_t *mctx, isc_log_t **logp) { /*% load the zone */ isc_result_t load_zone(isc_mem_t *mctx, const char *zonename, const char *filename, - const char *classname, dns_zone_t **zonep) + dns_masterformat_t fileformat, const char *classname, + dns_zone_t **zonep) { isc_result_t result; dns_rdataclass_t rdclass; @@ -417,7 +418,7 @@ load_zone(isc_mem_t *mctx, const char *zonename, const char *filename, ISC_FALSE, NULL)); CHECK(dns_zone_setorigin(zone, origin)); CHECK(dns_zone_setdbtype(zone, 1, (const char * const *) dbtype)); - CHECK(dns_zone_setfile(zone, filename)); + CHECK(dns_zone_setfile2(zone, filename, fileformat)); DE_CONST(classname, region.base); region.length = strlen(classname); @@ -447,7 +448,8 @@ load_zone(isc_mem_t *mctx, const char *zonename, const char *filename, /*% dump the zone */ isc_result_t -dump_zone(const char *zonename, dns_zone_t *zone, const char *filename) +dump_zone(const char *zonename, dns_zone_t *zone, const char *filename, + dns_masterformat_t fileformat, const dns_master_style_t *style) { isc_result_t result; FILE *output = stdout; @@ -470,7 +472,7 @@ dump_zone(const char *zonename, dns_zone_t *zone, const char *filename) } } - result = dns_zone_fulldumptostream(zone, output); + result = dns_zone_dumptostream2(zone, output, fileformat, style); if (filename != NULL) (void)isc_stdio_close(output); diff --git a/bin/check/check-tool.h b/bin/check/check-tool.h index bfd8a409e2..d6b78ad426 100644 --- a/bin/check/check-tool.h +++ b/bin/check/check-tool.h @@ -15,7 +15,7 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: check-tool.h,v 1.10 2005/05/19 04:58:59 marka Exp $ */ +/* $Id: check-tool.h,v 1.11 2005/06/20 01:03:48 marka Exp $ */ #ifndef CHECK_TOOL_H #define CHECK_TOOL_H @@ -23,8 +23,9 @@ /*! \file */ #include - #include + +#include #include ISC_LANG_BEGINDECLS @@ -34,10 +35,12 @@ setup_logging(isc_mem_t *mctx, isc_log_t **logp); isc_result_t load_zone(isc_mem_t *mctx, const char *zonename, const char *filename, - const char *classname, dns_zone_t **zonep); + dns_masterformat_t fileformat, const char *classname, + dns_zone_t **zonep); isc_result_t -dump_zone(const char *zonename, dns_zone_t *zone, const char *filename); +dump_zone(const char *zonename, dns_zone_t *zone, const char *filename, + dns_masterformat_t fileformat, const dns_master_style_t *style); extern int debug; extern isc_boolean_t nomerge; diff --git a/bin/check/named-checkconf.c b/bin/check/named-checkconf.c index 9cda04ca49..7f137a3f92 100644 --- a/bin/check/named-checkconf.c +++ b/bin/check/named-checkconf.c @@ -15,7 +15,7 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: named-checkconf.c,v 1.33 2005/06/17 02:22:43 marka Exp $ */ +/* $Id: named-checkconf.c,v 1.34 2005/06/20 01:03:48 marka Exp $ */ /*! \file */ @@ -134,23 +134,37 @@ get_checknames(cfg_obj_t **maps, cfg_obj_t **obj) { } } +static isc_result_t +config_get(cfg_obj_t **maps, const char *name, cfg_obj_t **obj) { + int i; + + for (i = 0;; i++) { + if (maps[i] == NULL) + return (ISC_R_NOTFOUND); + if (cfg_map_get(maps[i], name, obj) == ISC_R_SUCCESS) + return (ISC_R_SUCCESS); + } +} + /*% configure the zone */ static isc_result_t configure_zone(const char *vclass, const char *view, cfg_obj_t *zconfig, cfg_obj_t *vconfig, cfg_obj_t *config, isc_mem_t *mctx) { + int i = 0; isc_result_t result; const char *zclass; const char *zname; const char *zfile; + cfg_obj_t *maps[4]; cfg_obj_t *zoptions = NULL; cfg_obj_t *classobj = NULL; cfg_obj_t *typeobj = NULL; cfg_obj_t *fileobj = NULL; cfg_obj_t *dbobj = NULL; cfg_obj_t *obj = NULL; - cfg_obj_t *maps[4]; - int i = 0; + cfg_obj_t *fmtobj = NULL; + dns_masterformat_t masterformat; zone_options = DNS_ZONEOPT_CHECKNS | DNS_ZONEOPT_MANYERRORS | @@ -223,7 +237,20 @@ configure_zone(const char *vclass, const char *view, cfg_obj_t *zconfig, zone_options |= DNS_ZONEOPT_CHECKNAMESFAIL; } - result = load_zone(mctx, zname, zfile, zclass, NULL); + masterformat = dns_masterformat_text; + fmtobj = NULL; + result = config_get(maps, "masterfile-format", &fmtobj); + if (result == ISC_R_SUCCESS) { + char *masterformatstr = cfg_obj_asstring(fmtobj); + if (strcasecmp(masterformatstr, "text") == 0) + masterformat = dns_masterformat_text; + else if (strcasecmp(masterformatstr, "raw") == 0) + masterformat = dns_masterformat_raw; + else + INSIST(0); + } + + result = load_zone(mctx, zname, zfile, masterformat, zclass, NULL); if (result != ISC_R_SUCCESS) fprintf(stderr, "%s/%s/%s: %s\n", view, zname, zclass, dns_result_totext(result)); diff --git a/bin/check/named-checkzone.c b/bin/check/named-checkzone.c index 99c405f28f..aa348cf28a 100644 --- a/bin/check/named-checkzone.c +++ b/bin/check/named-checkzone.c @@ -15,7 +15,7 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: named-checkzone.c,v 1.35 2005/05/19 04:58:59 marka Exp $ */ +/* $Id: named-checkzone.c,v 1.36 2005/06/20 01:03:48 marka Exp $ */ /*! \file */ @@ -39,10 +39,12 @@ #include #include #include +#include #include #include #include #include +#include #include #include "check-tool.h" @@ -54,6 +56,9 @@ dns_zone_t *zone = NULL; dns_zonetype_t zonetype = dns_zone_master; static int dumpzone = 0; static const char *output_filename; +static char *prog_name = NULL; +static const dns_master_style_t *outputstyle = &dns_master_style_full; +static enum { progmode_check, progmode_compile } progmode; #define ERRRET(result, function) \ do { \ @@ -68,11 +73,12 @@ static const char *output_filename; static void usage(void) { fprintf(stderr, - "usage: named-checkzone [-djqvD] [-c class] [-o output] " + "usage: %s [-djqvD] [-c class] [-o output] " + "[-f inputformat] [-F outputformat] " "[-t directory] [-w directory] [-k (ignore|warn|fail)] " "[-n (ignore|warn|fail)] [-m (ignore|warn|fail)] " "[-i (full|local|none)] [-W (ignore|warn)] " - "zonename filename\n"); + "zonename filename\n", prog_name); exit(1); } @@ -93,9 +99,35 @@ main(int argc, char **argv) { char classname_in[] = "IN"; char *classname = classname_in; const char *workdir = NULL; + const char *inputformatstr = NULL; + const char *outputformatstr = NULL; + dns_masterformat_t inputformat = dns_masterformat_text; + dns_masterformat_t outputformat = dns_masterformat_text; + + prog_name = strrchr(argv[0], '/'); + if (prog_name != NULL) + prog_name++; + else + prog_name = argv[0]; + if (strcmp(prog_name, "named-checkzone") == 0) + progmode = progmode_check; + else if (strcmp(prog_name, "named-compilezone") == 0) + progmode = progmode_compile; + else + INSIST(0); + + /* Compilation specific defaults */ + if (progmode == progmode_compile) { + zone_options |= (DNS_ZONEOPT_CHECKNS | + DNS_ZONEOPT_FATALNS | + DNS_ZONEOPT_CHECKNAMES | + DNS_ZONEOPT_CHECKNAMESFAIL | + DNS_ZONEOPT_CHECKWILDCARD); + } while ((c = isc_commandline_parse(argc, argv, - "c:di:jk:m:n:qst:o:vw:DW:")) != EOF) { + "c:df:i:jk:m:n:qst:o:vw:DF:W:")) + != EOF) { switch (c) { case 'c': classname = isc_commandline_argument; @@ -130,6 +162,14 @@ main(int argc, char **argv) { } break; + case 'f': + inputformatstr = isc_commandline_argument; + break; + + case 'F': + outputformatstr = isc_commandline_argument; + break; + case 'j': nomerge = ISC_FALSE; break; @@ -209,6 +249,20 @@ main(int argc, char **argv) { } break; + case 's': + if (strcmp(isc_commandline_argument, "full") == 0) + outputstyle = &dns_master_style_full; + else if (strcmp(isc_commandline_argument, + "default") == 0) { + outputstyle = &dns_master_style_default; + } else { + fprintf(stderr, + "unknown or unsupported style: %s\n", + isc_commandline_argument); + exit(1); + } + break; + case 'o': output_filename = isc_commandline_argument; break; @@ -237,6 +291,15 @@ main(int argc, char **argv) { } } + if (progmode == progmode_compile) { + dumpzone = 1; /* always dump */ + if (output_filename == NULL) { + fprintf(stderr, + "output file required, but not specified\n"); + usage(); + } + } + if (workdir != NULL) { result = isc_dir_chdir(workdir); if (result != ISC_R_SUCCESS) { @@ -246,6 +309,30 @@ main(int argc, char **argv) { } } + if (inputformatstr != NULL) { + if (strcasecmp(inputformatstr, "text") == 0) + inputformat = dns_masterformat_text; + else if (strcasecmp(inputformatstr, "raw") == 0) + inputformat = dns_masterformat_raw; + else { + fprintf(stderr, "unknown file format: %s\n", + inputformatstr); + exit(1); + } + } + + if (outputformatstr != NULL) { + if (strcasecmp(outputformatstr, "text") == 0) + outputformat = dns_masterformat_text; + else if (strcasecmp(outputformatstr, "raw") == 0) + outputformat = dns_masterformat_raw; + else { + fprintf(stderr, "unknown file format: %s\n", + outputformatstr); + exit(1); + } + } + if (isc_commandline_index + 2 > argc) usage(); @@ -263,10 +350,18 @@ main(int argc, char **argv) { origin = argv[isc_commandline_index++]; filename = argv[isc_commandline_index++]; - result = load_zone(mctx, origin, filename, classname, &zone); + result = load_zone(mctx, origin, filename, inputformat, classname, + &zone); if (result == ISC_R_SUCCESS && dumpzone) { - result = dump_zone(origin, zone, output_filename); + if (!quiet && progmode == progmode_compile) { + fprintf(stdout, "dump zone to %s...", output_filename); + fflush(stdout); + } + result = dump_zone(origin, zone, output_filename, + outputformat, outputstyle); + if (!quiet && progmode == progmode_compile) + fprintf(stdout, "done\n"); } if (!quiet && result == ISC_R_SUCCESS) diff --git a/bin/check/named-checkzone.docbook b/bin/check/named-checkzone.docbook index 121b2bc94c..0539f69cb1 100644 --- a/bin/check/named-checkzone.docbook +++ b/bin/check/named-checkzone.docbook @@ -18,7 +18,7 @@ - PERFORMANCE OF THIS SOFTWARE. --> - + June 13, 2000 @@ -46,7 +46,8 @@ named-checkzone - zone file validity checking tool + named-compilezone + zone file validity checking or converting tool @@ -57,11 +58,36 @@ + + + + + + + + zonename + filename + + + named-compilezone + + + + + + + + + + + + + @@ -79,6 +105,16 @@ zone. This makes named-checkzone useful for checking zone files before configuring them into a name server. + + named-compilezone is similar to + named-checkzone, but it always dumps the + zone contents to a specified file in a specified format. + Additionally, it applies stricter check levels by default, + since the dump output will be used as an actual zone file + loaded by named. + When manaully specified otherwise, the check levels must at + least be as strict as those specified in the + named configuration file. @@ -167,14 +203,41 @@ + + -f format + + + Specify the format of the zone file. + Possible formats are "text" (default) + and "raw". + + + + + + -F format + + + Specify the format of the output file specified. + Possible formats are "text" (default) + and "raw". + For named-checkzone, + this does not cause any effects unless it dumps the zone + contents. + + + + -k mode - Perform "check-name" checks with - the specified failure mode. - Possible modes are "fail", - "warn" (default) and + Perform "check-name" checks with the + specified failure mode. + Possible modes are "fail" + (default for named-compilezone), + "warn" + (default for named-checkzone) and "ignore". @@ -197,8 +260,11 @@ Specify whether NS records should be checked to see if they - are addresses. Possible modes are "fail", - "warn" (default) and + are addresses. + Possible modes are "fail" + (default for named-compilezone), + "warn" + (default for named-checkzone) and "ignore". @@ -209,10 +275,31 @@ Write zone output to filename. + This is mandatory for named-compilezone. + + -s style + + + Specify the style of the dumped zone file. + Possible styles are "full" (default) + and "default". + The full format is most suitable for processing + automatically by a separate script. + On the other hand, the default format is more + human-readable and is thus suitable for editing by hand. + For named-checkzone + this does not cause any effects unless it dumps the zone + contents. + It also does not have any meaning if the output format + is not text. + + + + -t directory @@ -243,6 +330,7 @@ Dump zone file in canonical format. + This is always enabled for named-compilezone. diff --git a/bin/named/zoneconf.c b/bin/named/zoneconf.c index d64bd7f55b..fb02988cdb 100644 --- a/bin/named/zoneconf.c +++ b/bin/named/zoneconf.c @@ -15,7 +15,7 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: zoneconf.c,v 1.121 2005/05/19 04:59:01 marka Exp $ */ +/* $Id: zoneconf.c,v 1.122 2005/06/20 01:03:49 marka Exp $ */ /*% */ @@ -341,6 +341,7 @@ ns_zone_configure(cfg_obj_t *config, cfg_obj_t *vconfig, cfg_obj_t *zconfig, dns_view_t *view; isc_boolean_t check = ISC_FALSE, fail = ISC_FALSE; isc_boolean_t ixfrdiff; + dns_masterformat_t masterformat; i = 0; if (zconfig != NULL) { @@ -395,7 +396,21 @@ ns_zone_configure(cfg_obj_t *config, cfg_obj_t *vconfig, cfg_obj_t *zconfig, result = cfg_map_get(zoptions, "file", &obj); if (result == ISC_R_SUCCESS) filename = cfg_obj_asstring(obj); - RETERR(dns_zone_setfile(zone, filename)); + + masterformat = dns_masterformat_text; + obj = NULL; + result= ns_config_get(maps, "masterfile-format", &obj); + if (result == ISC_R_SUCCESS) { + char *masterformatstr = cfg_obj_asstring(obj); + + if (strcasecmp(masterformatstr, "text") == 0) + masterformat = dns_masterformat_text; + else if (strcasecmp(masterformatstr, "raw") == 0) + masterformat = dns_masterformat_raw; + else + INSIST(0); + } + RETERR(dns_zone_setfile2(zone, filename, masterformat)); obj = NULL; result = cfg_map_get(zoptions, "journal", &obj); diff --git a/bin/tests/system/conf.sh.in b/bin/tests/system/conf.sh.in index d6bd70962a..2adce547ae 100644 --- a/bin/tests/system/conf.sh.in +++ b/bin/tests/system/conf.sh.in @@ -15,7 +15,7 @@ # OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR # PERFORMANCE OF THIS SOFTWARE. -# $Id: conf.sh.in,v 1.28 2004/11/23 05:23:35 marka Exp $ +# $Id: conf.sh.in,v 1.29 2005/06/20 01:03:49 marka Exp $ # # Common configuration data for system tests, to be sourced into @@ -43,7 +43,7 @@ CHECKZONE=$TOP/bin/check/named-checkzone # load on the machine to make it unusable to other users. # v6synth SUBDIRS="cacheclean checknames dnssec forward glue ixfr limits lwresd \ - masterfile notify nsupdate resolver sortlist stub tkey \ + masterfile masterformat notify nsupdate resolver sortlist stub tkey \ unknown upforwd views xfer xferquota zonechecks" # PERL will be an empty string if no perl interpreter was found. diff --git a/bin/tests/system/masterformat/clean.sh b/bin/tests/system/masterformat/clean.sh new file mode 100755 index 0000000000..7aa458a42a --- /dev/null +++ b/bin/tests/system/masterformat/clean.sh @@ -0,0 +1,22 @@ +#!/bin/sh +# +# Copyright (C) 2005 Internet Systems Consortium, Inc. ("ISC") +# +# Permission to use, copy, modify, and distribute this software for any +# purpose with or without fee is hereby granted, provided that the above +# copyright notice and this permission notice appear in all copies. +# +# THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH +# REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY +# AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, +# INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM +# LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE +# OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR +# PERFORMANCE OF THIS SOFTWARE. + +# $Id: clean.sh,v 1.2 2005/06/20 01:03:49 marka Exp $ + +rm -f named-compilezone +rm -f ns1/example.db.raw +rm -f ns2/example.db +rm -f dig.out.* diff --git a/bin/tests/system/masterformat/ns1/compile.sh b/bin/tests/system/masterformat/ns1/compile.sh new file mode 100755 index 0000000000..3960178f96 --- /dev/null +++ b/bin/tests/system/masterformat/ns1/compile.sh @@ -0,0 +1,17 @@ +# Copyright (C) 2005 Internet Systems Consortium, Inc. ("ISC") +# +# Permission to use, copy, modify, and distribute this software for any +# purpose with or without fee is hereby granted, provided that the above +# copyright notice and this permission notice appear in all copies. +# +# THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH +# REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY +# AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, +# INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM +# LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE +# OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR +# PERFORMANCE OF THIS SOFTWARE. + +# $Id: compile.sh,v 1.2 2005/06/20 01:03:50 marka Exp $ + +../named-compilezone -F raw -o example.db.raw example example.db diff --git a/bin/tests/system/masterformat/ns1/example.db b/bin/tests/system/masterformat/ns1/example.db new file mode 100644 index 0000000000..57ee13ecd4 --- /dev/null +++ b/bin/tests/system/masterformat/ns1/example.db @@ -0,0 +1,38 @@ +$TTL 1D + +@ IN SOA ns hostmaster ( + 1 + 3600 + 1800 + 1814400 + 3 + ) + NS ns +ns A 10.53.0.1 +mx MX 10 mail +a A 10.53.0.1 + A 10.53.0.2 +aaaa AAAA 2001:db8::53 +cname CNAME cname-target +dname DNAME dname-target +txt TXT "this is text" + +;; +;; we are not testing DNSSEC behavior, so we don't care about the semantics +;; of the following records. +dnskey 300 DNSKEY 256 3 1 ( + AQPTpWyReB/e9Ii6mVGnakS8hX2zkh/iUYAg + +Ge4noWROpTWOIBvm76zeJPWs4Zfqa1IsswD + Ix5Mqeg0zwclz59uecKsKyx5w9IhtZ8plc4R + b9VIE5x7KNHAYTvTO5d4S8M= + ) +ds 300 DS 30795 1 1 ( + 310D27F4D82C1FC2400704EA9939FE6E1CEA + A3B9 ) +nsec 600 NSEC nsecnext NS DS RRSIG NSEC +rrsig 300 RRSIG SOA 1 0 300 20050714214747 ( + 20050614214747 30795 . + yi/RRPAQmn6rnjDQaCqVValBa+ICF00ZldKf + ZSDaoew5mMUh83DlrrPPNeAxrzMSNzDGlJ6P + fdyIFgzPn/CvthF4kjBUAiJTp4r2zhlaUJQ+ + QFo+drYXYgVJo6aA36fj ) diff --git a/bin/tests/system/masterformat/ns1/named.conf b/bin/tests/system/masterformat/ns1/named.conf new file mode 100644 index 0000000000..f8eec4b2cf --- /dev/null +++ b/bin/tests/system/masterformat/ns1/named.conf @@ -0,0 +1,36 @@ +/* + * Copyright (C) 2005 Internet Systems Consortium, Inc. ("ISC") + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH + * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY + * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, + * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM + * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE + * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* $Id: named.conf,v 1.2 2005/06/20 01:03:51 marka Exp $ */ + +// NS1 + +controls { /* empty */ }; + +options { + pid-file "named.pid"; + listen-on port 5300 { 10.53.0.1; }; + listen-on-v6 { none; }; + recursion no; + notify no; + dnssec-enable yes; +}; + +zone "example" { + type master; + masterfile-format raw; + file "example.db.raw"; +}; diff --git a/bin/tests/system/masterformat/ns2/named.conf b/bin/tests/system/masterformat/ns2/named.conf new file mode 100644 index 0000000000..759d348183 --- /dev/null +++ b/bin/tests/system/masterformat/ns2/named.conf @@ -0,0 +1,35 @@ +/* + * Copyright (C) 2005 Internet Systems Consortium, Inc. ("ISC") + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH + * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY + * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, + * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM + * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE + * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* $Id: named.conf,v 1.2 2005/06/20 01:03:51 marka Exp $ */ + +// NS2 + +controls { /* empty */ }; + +options { + pid-file "named.pid"; + listen-on port 5300 { 10.53.0.2; }; + listen-on-v6 { none; }; + recursion no; + notify no; + dnssec-enable yes; +}; + +zone "example" { + type master; + file "example.db"; +}; diff --git a/bin/tests/system/masterformat/setup.sh b/bin/tests/system/masterformat/setup.sh new file mode 100755 index 0000000000..77fe774642 --- /dev/null +++ b/bin/tests/system/masterformat/setup.sh @@ -0,0 +1,19 @@ +# Copyright (C) 2005 Internet Systems Consortium, Inc. ("ISC") +# +# Permission to use, copy, modify, and distribute this software for any +# purpose with or without fee is hereby granted, provided that the above +# copyright notice and this permission notice appear in all copies. +# +# THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH +# REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY +# AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, +# INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM +# LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE +# OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR +# PERFORMANCE OF THIS SOFTWARE. + +# $Id: setup.sh,v 1.2 2005/06/20 01:03:50 marka Exp $ + +ln -s $CHECKZONE named-compilezone +cp ns1/example.db ns2/ +cd ns1 && sh compile.sh diff --git a/bin/tests/system/masterformat/tests.sh b/bin/tests/system/masterformat/tests.sh new file mode 100755 index 0000000000..2b8d1dc0ea --- /dev/null +++ b/bin/tests/system/masterformat/tests.sh @@ -0,0 +1,80 @@ +#!/bin/sh +# +# Copyright (C) 2005 Internet Systems Consortium, Inc. ("ISC") +# +# Permission to use, copy, modify, and distribute this software for any +# purpose with or without fee is hereby granted, provided that the above +# copyright notice and this permission notice appear in all copies. +# +# THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH +# REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY +# AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, +# INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM +# LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE +# OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR +# PERFORMANCE OF THIS SOFTWARE. + +# $Id: tests.sh,v 1.2 2005/06/20 01:03:50 marka Exp $ + +SYSTEMTESTTOP=.. +. $SYSTEMTESTTOP/conf.sh + +DIGOPTS="+tcp +noauth +noadd +nosea +nostat +noquest +nocomm +nocmd" + +status=0 + +echo "I:checking that master file in the raw format worked" + +for server in 1 2 +do + for name in ns mx a aaaa cname dname txt rrsig nsec dnskey ds + do + $DIG $DIGOPTS $name.example. $name @10.53.0.$server -p 5300 + echo + done > dig.out.$server +done + +diff dig.out.1 dig.out.2 || status=1 + +echo "I:exit status: $status" +exit $status +#!/bin/sh +# +# Copyright (C) 2005 Internet Systems Consortium, Inc. ("ISC") +# +# Permission to use, copy, modify, and distribute this software for any +# purpose with or without fee is hereby granted, provided that the above +# copyright notice and this permission notice appear in all copies. +# +# THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH +# REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY +# AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, +# INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM +# LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE +# OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR +# PERFORMANCE OF THIS SOFTWARE. + +# $Id: tests.sh,v 1.2 2005/06/20 01:03:50 marka Exp $ + +SYSTEMTESTTOP=.. +. $SYSTEMTESTTOP/conf.sh + +DIGOPTS="+tcp +noauth +noadd +nosea +nostat +noquest +nocomm +nocmd" + +status=0 + +echo "I:checking that master file in the raw format worked" + +for server in 1 2 +do + for name in ns mx a aaaa cname dname txt rrsig nsec dnskey ds + do + $DIG $DIGOPTS $name.example. $name @10.53.0.$server -p 5300 + echo + done > dig.out.$server +done + +diff dig.out.1 dig.out.2 || status=1 + +echo "I:exit status: $status" +exit $status diff --git a/configure b/configure index 3fe6163d9f..8d144337e7 100755 --- a/configure +++ b/configure @@ -14,7 +14,7 @@ # OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR # PERFORMANCE OF THIS SOFTWARE. # -# $Id: configure,v 1.366 2005/06/16 21:59:33 jinmei Exp $ +# $Id: configure,v 1.367 2005/06/20 01:05:33 marka Exp $ # # Portions Copyright (C) 1996-2001 Nominum, Inc. # @@ -29,7 +29,7 @@ # WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN # ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT # OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. -# From configure.in Revision: 1.379 . +# From configure.in Revision: 1.380 . # Guess values for system-dependent variables and create Makefiles. # Generated by GNU Autoconf 2.59. # @@ -495,7 +495,7 @@ ac_includes_default="\ # include #endif" -ac_subst_vars='SHELL PATH_SEPARATOR PACKAGE_NAME PACKAGE_TARNAME PACKAGE_VERSION PACKAGE_STRING PACKAGE_BUGREPORT exec_prefix prefix program_transform_name bindir sbindir libexecdir datadir sysconfdir sharedstatedir localstatedir libdir includedir oldincludedir infodir mandir build_alias host_alias target_alias DEFS ECHO_C ECHO_N ECHO_T LIBS subdirs build build_cpu build_vendor build_os host host_cpu host_vendor host_os SET_MAKE RANLIB ac_ct_RANLIB INSTALL_PROGRAM INSTALL_SCRIPT INSTALL_DATA STD_CINCLUDES STD_CDEFINES STD_CWARNINGS CCOPT AR ARFLAGS LN ETAGS PERL CC CFLAGS LDFLAGS CPPFLAGS ac_ct_CC EXEEXT OBJEXT CPP EGREP ISC_SOCKADDR_LEN_T ISC_PLATFORM_HAVELONGLONG ISC_PLATFORM_HAVELIFCONF ISC_PLATFORM_NEEDSYSSELECTH LWRES_PLATFORM_NEEDSYSSELECTH USE_OPENSSL DST_OPENSSL_INC USE_GSSAPI DST_GSSAPI_INC DNS_CRYPTO_LIBS ALWAYS_DEFINES ISC_PLATFORM_USETHREADS ISC_THREAD_DIR MKDEPCC MKDEPCFLAGS MKDEPPROG IRIX_DNSSEC_WARNINGS_HACK purify_path PURIFY LN_S ECHO ac_ct_AR STRIP ac_ct_STRIP CXX CXXFLAGS ac_ct_CXX CXXCPP F77 FFLAGS ac_ct_F77 LIBTOOL O A SA LIBTOOL_MKDEP_SED LIBTOOL_MODE_COMPILE LIBTOOL_MODE_INSTALL LIBTOOL_MODE_LINK LIBTOOL_ALLOW_UNDEFINED LIBTOOL_IN_MAIN LIBBIND ISC_PLATFORM_HAVEIPV6 LWRES_PLATFORM_HAVEIPV6 ISC_PLATFORM_NEEDNETINETIN6H LWRES_PLATFORM_NEEDNETINETIN6H ISC_PLATFORM_NEEDNETINET6IN6H LWRES_PLATFORM_NEEDNETINET6IN6H ISC_PLATFORM_HAVEINADDR6 LWRES_PLATFORM_HAVEINADDR6 ISC_PLATFORM_NEEDIN6ADDRANY LWRES_PLATFORM_NEEDIN6ADDRANY ISC_PLATFORM_NEEDIN6ADDRLOOPBACK LWRES_PLATFORM_NEEDIN6ADDRLOOPBACK ISC_PLATFORM_HAVEIN6PKTINFO ISC_PLATFORM_FIXIN6ISADDR ISC_IPV6_H ISC_IPV6_O ISC_ISCIPV6_O ISC_IPV6_C LWRES_HAVE_SIN6_SCOPE_ID ISC_PLATFORM_HAVESCOPEID ISC_PLATFORM_HAVEIF_LADDRREQ ISC_PLATFORM_HAVEIF_LADDRCONF ISC_PLATFORM_NEEDNTOP ISC_PLATFORM_NEEDPTON ISC_PLATFORM_NEEDATON ISC_PLATFORM_HAVESALEN LWRES_PLATFORM_HAVESALEN ISC_PLATFORM_MSGHDRFLAVOR ISC_PLATFORM_NEEDPORTT ISC_LWRES_NEEDADDRINFO ISC_LWRES_NEEDRRSETINFO ISC_LWRES_SETHOSTENTINT ISC_LWRES_ENDHOSTENTINT ISC_LWRES_GETNETBYADDRINADDR ISC_LWRES_SETNETENTINT ISC_LWRES_ENDNETENTINT ISC_LWRES_GETHOSTBYADDRVOID ISC_LWRES_NEEDHERRNO ISC_LWRES_GETIPNODEPROTO ISC_LWRES_GETADDRINFOPROTO ISC_LWRES_GETNAMEINFOPROTO ISC_PLATFORM_NEEDSTRSEP ISC_PLATFORM_NEEDMEMMOVE ISC_PLATFORM_NEEDSTRTOUL LWRES_PLATFORM_NEEDSTRTOUL GENRANDOMLIB ISC_PLATFORM_NEEDSTRLCPY ISC_PLATFORM_NEEDSTRLCAT ISC_PLATFORM_NEEDSPRINTF LWRES_PLATFORM_NEEDSPRINTF ISC_PLATFORM_NEEDVSNPRINTF LWRES_PLATFORM_NEEDVSNPRINTF ISC_EXTRA_OBJS ISC_EXTRA_SRCS ISC_PLATFORM_QUADFORMAT LWRES_PLATFORM_QUADFORMAT ISC_PLATFORM_HAVESYSUNH ISC_PLATFORM_RLIMITTYPE ISC_PLATFORM_USEDECLSPEC LWRES_PLATFORM_USEDECLSPEC ISC_PLATFORM_BRACEPTHREADONCEINIT ISC_PLATFORM_HAVEIFNAMETOINDEX ISC_PLATFORM_HAVEXADD ISC_PLATFORM_HAVECMPXCHG ISC_PLATFORM_HAVEATOMICSTORE ISC_PLATFORM_USEGCCASM ISC_PLATFORM_USEOSFASM ISC_PLATFORM_USESTDASM ISC_ARCH_DIR LATEX PDFLATEX XSLTPROC XMLLINT XSLT_DOCBOOK_STYLE_HTML XSLT_DOCBOOK_STYLE_XHTML XSLT_DOCBOOK_STYLE_MAN XSLT_DOCBOOK_CHUNK_HTML XSLT_DOCBOOK_CHUNK_XHTML XSLT_DB2LATEX_STYLE XSLT_DB2LATEX_ADMONITIONS BIND9_TOP_BUILDDIR BIND9_ISC_BUILDINCLUDE BIND9_ISCCC_BUILDINCLUDE BIND9_ISCCFG_BUILDINCLUDE BIND9_DNS_BUILDINCLUDE BIND9_LWRES_BUILDINCLUDE BIND9_BIND9_BUILDINCLUDE BIND9_VERSION LIBOBJS LTLIBOBJS' +ac_subst_vars='SHELL PATH_SEPARATOR PACKAGE_NAME PACKAGE_TARNAME PACKAGE_VERSION PACKAGE_STRING PACKAGE_BUGREPORT exec_prefix prefix program_transform_name bindir sbindir libexecdir datadir sysconfdir sharedstatedir localstatedir libdir includedir oldincludedir infodir mandir build_alias host_alias target_alias DEFS ECHO_C ECHO_N ECHO_T LIBS subdirs build build_cpu build_vendor build_os host host_cpu host_vendor host_os SET_MAKE RANLIB ac_ct_RANLIB INSTALL_PROGRAM INSTALL_SCRIPT INSTALL_DATA LN_S STD_CINCLUDES STD_CDEFINES STD_CWARNINGS CCOPT AR ARFLAGS LN ETAGS PERL CC CFLAGS LDFLAGS CPPFLAGS ac_ct_CC EXEEXT OBJEXT CPP EGREP ISC_SOCKADDR_LEN_T ISC_PLATFORM_HAVELONGLONG ISC_PLATFORM_HAVELIFCONF ISC_PLATFORM_NEEDSYSSELECTH LWRES_PLATFORM_NEEDSYSSELECTH USE_OPENSSL DST_OPENSSL_INC USE_GSSAPI DST_GSSAPI_INC DNS_CRYPTO_LIBS ALWAYS_DEFINES ISC_PLATFORM_USETHREADS ISC_THREAD_DIR MKDEPCC MKDEPCFLAGS MKDEPPROG IRIX_DNSSEC_WARNINGS_HACK purify_path PURIFY ECHO ac_ct_AR STRIP ac_ct_STRIP CXX CXXFLAGS ac_ct_CXX CXXCPP F77 FFLAGS ac_ct_F77 LIBTOOL O A SA LIBTOOL_MKDEP_SED LIBTOOL_MODE_COMPILE LIBTOOL_MODE_INSTALL LIBTOOL_MODE_LINK LIBTOOL_ALLOW_UNDEFINED LIBTOOL_IN_MAIN LIBBIND ISC_PLATFORM_HAVEIPV6 LWRES_PLATFORM_HAVEIPV6 ISC_PLATFORM_NEEDNETINETIN6H LWRES_PLATFORM_NEEDNETINETIN6H ISC_PLATFORM_NEEDNETINET6IN6H LWRES_PLATFORM_NEEDNETINET6IN6H ISC_PLATFORM_HAVEINADDR6 LWRES_PLATFORM_HAVEINADDR6 ISC_PLATFORM_NEEDIN6ADDRANY LWRES_PLATFORM_NEEDIN6ADDRANY ISC_PLATFORM_NEEDIN6ADDRLOOPBACK LWRES_PLATFORM_NEEDIN6ADDRLOOPBACK ISC_PLATFORM_HAVEIN6PKTINFO ISC_PLATFORM_FIXIN6ISADDR ISC_IPV6_H ISC_IPV6_O ISC_ISCIPV6_O ISC_IPV6_C LWRES_HAVE_SIN6_SCOPE_ID ISC_PLATFORM_HAVESCOPEID ISC_PLATFORM_HAVEIF_LADDRREQ ISC_PLATFORM_HAVEIF_LADDRCONF ISC_PLATFORM_NEEDNTOP ISC_PLATFORM_NEEDPTON ISC_PLATFORM_NEEDATON ISC_PLATFORM_HAVESALEN LWRES_PLATFORM_HAVESALEN ISC_PLATFORM_MSGHDRFLAVOR ISC_PLATFORM_NEEDPORTT ISC_LWRES_NEEDADDRINFO ISC_LWRES_NEEDRRSETINFO ISC_LWRES_SETHOSTENTINT ISC_LWRES_ENDHOSTENTINT ISC_LWRES_GETNETBYADDRINADDR ISC_LWRES_SETNETENTINT ISC_LWRES_ENDNETENTINT ISC_LWRES_GETHOSTBYADDRVOID ISC_LWRES_NEEDHERRNO ISC_LWRES_GETIPNODEPROTO ISC_LWRES_GETADDRINFOPROTO ISC_LWRES_GETNAMEINFOPROTO ISC_PLATFORM_NEEDSTRSEP ISC_PLATFORM_NEEDMEMMOVE ISC_PLATFORM_NEEDSTRTOUL LWRES_PLATFORM_NEEDSTRTOUL GENRANDOMLIB ISC_PLATFORM_NEEDSTRLCPY ISC_PLATFORM_NEEDSTRLCAT ISC_PLATFORM_NEEDSPRINTF LWRES_PLATFORM_NEEDSPRINTF ISC_PLATFORM_NEEDVSNPRINTF LWRES_PLATFORM_NEEDVSNPRINTF ISC_EXTRA_OBJS ISC_EXTRA_SRCS ISC_PLATFORM_QUADFORMAT LWRES_PLATFORM_QUADFORMAT ISC_PLATFORM_HAVESYSUNH ISC_PLATFORM_RLIMITTYPE ISC_PLATFORM_USEDECLSPEC LWRES_PLATFORM_USEDECLSPEC ISC_PLATFORM_BRACEPTHREADONCEINIT ISC_PLATFORM_HAVEIFNAMETOINDEX ISC_PLATFORM_HAVEXADD ISC_PLATFORM_HAVECMPXCHG ISC_PLATFORM_HAVEATOMICSTORE ISC_PLATFORM_USEGCCASM ISC_PLATFORM_USEOSFASM ISC_PLATFORM_USESTDASM ISC_ARCH_DIR LATEX PDFLATEX XSLTPROC XMLLINT XSLT_DOCBOOK_STYLE_HTML XSLT_DOCBOOK_STYLE_XHTML XSLT_DOCBOOK_STYLE_MAN XSLT_DOCBOOK_CHUNK_HTML XSLT_DOCBOOK_CHUNK_XHTML XSLT_DB2LATEX_STYLE XSLT_DB2LATEX_ADMONITIONS BIND9_TOP_BUILDDIR BIND9_ISC_BUILDINCLUDE BIND9_ISCCC_BUILDINCLUDE BIND9_ISCCFG_BUILDINCLUDE BIND9_DNS_BUILDINCLUDE BIND9_LWRES_BUILDINCLUDE BIND9_BIND9_BUILDINCLUDE BIND9_VERSION LIBOBJS LTLIBOBJS' ac_subst_files='BIND9_MAKE_INCLUDES BIND9_MAKE_RULES LIBISC_API LIBISCCC_API LIBISCCFG_API LIBDNS_API LIBBIND9_API LIBLWRES_API' # Initialize some variables set by options. @@ -1812,6 +1812,17 @@ test -z "$INSTALL_SCRIPT" && INSTALL_SCRIPT='${INSTALL}' test -z "$INSTALL_DATA" && INSTALL_DATA='${INSTALL} -m 644' +echo "$as_me:$LINENO: checking whether ln -s works" >&5 +echo $ECHO_N "checking whether ln -s works... $ECHO_C" >&6 +LN_S=$as_ln_s +if test "$LN_S" = "ln -s"; then + echo "$as_me:$LINENO: result: yes" >&5 +echo "${ECHO_T}yes" >&6 +else + echo "$as_me:$LINENO: result: no, using $LN_S" >&5 +echo "${ECHO_T}no, using $LN_S" >&6 +fi + @@ -7839,17 +7850,6 @@ echo "$as_me:$LINENO: result: $lt_cv_path_NM" >&5 echo "${ECHO_T}$lt_cv_path_NM" >&6 NM="$lt_cv_path_NM" -echo "$as_me:$LINENO: checking whether ln -s works" >&5 -echo $ECHO_N "checking whether ln -s works... $ECHO_C" >&6 -LN_S=$as_ln_s -if test "$LN_S" = "ln -s"; then - echo "$as_me:$LINENO: result: yes" >&5 -echo "${ECHO_T}yes" >&6 -else - echo "$as_me:$LINENO: result: no, using $LN_S" >&5 -echo "${ECHO_T}no, using $LN_S" >&6 -fi - echo "$as_me:$LINENO: checking how to recognise dependent libraries" >&5 echo $ECHO_N "checking how to recognise dependent libraries... $ECHO_C" >&6 if test "${lt_cv_deplibs_check_method+set}" = set; then @@ -28814,6 +28814,7 @@ s,@ac_ct_RANLIB@,$ac_ct_RANLIB,;t t s,@INSTALL_PROGRAM@,$INSTALL_PROGRAM,;t t s,@INSTALL_SCRIPT@,$INSTALL_SCRIPT,;t t s,@INSTALL_DATA@,$INSTALL_DATA,;t t +s,@LN_S@,$LN_S,;t t s,@STD_CINCLUDES@,$STD_CINCLUDES,;t t s,@STD_CDEFINES@,$STD_CDEFINES,;t t s,@STD_CWARNINGS@,$STD_CWARNINGS,;t t @@ -28851,7 +28852,6 @@ s,@MKDEPPROG@,$MKDEPPROG,;t t s,@IRIX_DNSSEC_WARNINGS_HACK@,$IRIX_DNSSEC_WARNINGS_HACK,;t t s,@purify_path@,$purify_path,;t t s,@PURIFY@,$PURIFY,;t t -s,@LN_S@,$LN_S,;t t s,@ECHO@,$ECHO,;t t s,@ac_ct_AR@,$ac_ct_AR,;t t s,@STRIP@,$STRIP,;t t diff --git a/configure.in b/configure.in index 16428beed9..c8d0d25a9c 100644 --- a/configure.in +++ b/configure.in @@ -18,7 +18,7 @@ AC_DIVERT_PUSH(1)dnl esyscmd([sed "s/^/# /" COPYRIGHT])dnl AC_DIVERT_POP()dnl -AC_REVISION($Revision: 1.379 $) +AC_REVISION($Revision: 1.380 $) AC_INIT(lib/dns/name.c) AC_PREREQ(2.13) @@ -31,6 +31,7 @@ AC_CANONICAL_HOST AC_PROG_MAKE_SET AC_PROG_RANLIB AC_PROG_INSTALL +AC_PROG_LN_S AC_SUBST(STD_CINCLUDES) AC_SUBST(STD_CDEFINES) diff --git a/doc/arm/Bv9ARM-book.xml b/doc/arm/Bv9ARM-book.xml index 69983476cc..6685a4b4da 100644 --- a/doc/arm/Bv9ARM-book.xml +++ b/doc/arm/Bv9ARM-book.xml @@ -18,7 +18,7 @@ - PERFORMANCE OF THIS SOFTWARE. --> - + BIND 9 Administrator Reference Manual @@ -1053,6 +1053,15 @@ zone "eng.example.com" { + + named-compilezone + + + Similar to named-checkzone, but + it always dumps the zone content to a specified file + (typically in a different format). + + rndc @@ -4386,6 +4395,7 @@ category notify { null; }; use-additional-cache yes_or_no ; acache-cleaning-interval number; max-acache-size size_spec ; + masterfile-format (text|raw) ; }; @@ -6855,7 +6865,37 @@ query-source-v6 address * port *; - + + + masterfile-format + + masterfile-format specifies + the file format of zone files (see + ). + The default value is text, which is the + standard textual representation. Files in other formats + than text are typically expected + to be generated by the named-compilezone. + Note that when a zone file in a different format than + text is loaded, named + may omit some of the checks which would be performed for a + file in the text format. In particular, + check-names checks do not apply + for the raw format. This means + a zone file in the raw format + must be generated with the same check level as that + specified in the named configuration + file. This statement sets the + masterfile-format for all zones, + but can be overridden on a per-zone / per-view basis + by including a masterfile-format + statement within the zone or + view block in the configuration + file. + + + + @@ -7552,6 +7592,7 @@ view "external" { dialup dialup_option ; delegation-only yes_or_no ; file string ; + masterfile-format (text|raw) ; journal string ; forward (only|first) ; forwarders { ip_addr port ip_port ; ip_addr port ip_port ; ... }; @@ -8262,11 +8303,21 @@ view "external" { multi-master - See the description of - multi-master in . + See the description of multi-master in + . + + + masterfile-format + + + See the description of masterfile-format + in . + + + @@ -9835,6 +9886,48 @@ $GENERATE 1-127 $ CNAME $.0 BIND 8 does not support the optional TTL and CLASS fields. + + + Additional File Formats + + In addition to the standard textual format, BIND 9 + supports the ability to read or dump to zone files in + other formats. The raw format is + currently available as an additional format. It is a + binary format representing BIND 9's internal data + structure directly, thereby remarkably improving the + loading time. + + + For a primary server, a zone file in the + raw format is expected to be + generated from a textual zone file by the + named-compilezone command. For a + secondary server or for a dynamic zone, it is automatically + generated (if this format is specified by the + masterfile-format option) when + named dumps the zone contents after + zone transfer or when applying prior updates. + + + If a zone file in a binary format needs manual modification, + it first must be converted to a textual form by the + named-compilezone command. All + necessary modification should go to the text file, which + should then be converted to the binary form by the + named-compilezone command again. + + + Although the raw format uses the + network byte order and avoids architecture-dependent + data alignment so that it is as much portable as + possible, it is primarily expected to be used inside + the same single system. In order to export a zone + file in the raw format or make a + portable backup of the file, it is recommended to + convert the file to the standard textual representation. + + diff --git a/lib/bind9/check.c b/lib/bind9/check.c index 60372c20f8..37a6f6133b 100644 --- a/lib/bind9/check.c +++ b/lib/bind9/check.c @@ -15,7 +15,7 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: check.c,v 1.59 2005/05/27 00:49:19 marka Exp $ */ +/* $Id: check.c,v 1.60 2005/06/20 01:03:52 marka Exp $ */ /*! \file */ @@ -801,6 +801,7 @@ check_zoneconf(cfg_obj_t *zconfig, cfg_obj_t *voptions, cfg_obj_t *config, { "check-wildcard", MASTERZONE }, { "check-mx", MASTERZONE }, { "integrity-check", MASTERZONE }, + { "masterfile-format", MASTERZONE | SLAVEZONE | STUBZONE | HINTZONE }, }; static optionstable dialups[] = { diff --git a/lib/dns/db.c b/lib/dns/db.c index 51a5c4d552..a9c16e4b9d 100644 --- a/lib/dns/db.c +++ b/lib/dns/db.c @@ -15,7 +15,7 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: db.c,v 1.77 2005/04/29 00:22:44 marka Exp $ */ +/* $Id: db.c,v 1.78 2005/06/20 01:03:52 marka Exp $ */ /*! \file */ @@ -339,13 +339,22 @@ dns_db_load(dns_db_t *db, const char *filename) { isc_result_t dns_db_dump(dns_db_t *db, dns_dbversion_t *version, const char *filename) { + return ((db->methods->dump)(db, version, filename, + dns_masterformat_text)); +} + +isc_result_t +dns_db_dump2(dns_db_t *db, dns_dbversion_t *version, const char *filename, + dns_masterformat_t masterformat) { /* - * Dump 'db' into master file 'filename'. + * Dump 'db' into master file 'filename' in the 'masterformat' format. + * XXXJT: is it okay to modify the interface to the existing "dump" + * method? */ REQUIRE(DNS_DB_VALID(db)); - return ((db->methods->dump)(db, version, filename)); + return ((db->methods->dump)(db, version, filename, masterformat)); } /*** diff --git a/lib/dns/include/dns/db.h b/lib/dns/include/dns/db.h index 2da7d83c89..685ddd2a87 100644 --- a/lib/dns/include/dns/db.h +++ b/lib/dns/include/dns/db.h @@ -15,7 +15,7 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: db.h,v 1.80 2005/04/29 00:22:55 marka Exp $ */ +/* $Id: db.h,v 1.81 2005/06/20 01:03:54 marka Exp $ */ #ifndef DNS_DB_H #define DNS_DB_H 1 @@ -75,7 +75,8 @@ typedef struct dns_dbmethods { dns_dbload_t **dbloadp); isc_result_t (*endload)(dns_db_t *db, dns_dbload_t **dbloadp); isc_result_t (*dump)(dns_db_t *db, dns_dbversion_t *version, - const char *filename); + const char *filename, + dns_masterformat_t masterformat); void (*currentversion)(dns_db_t *db, dns_dbversion_t **versionp); isc_result_t (*newversion)(dns_db_t *db, @@ -473,6 +474,10 @@ dns_db_load(dns_db_t *db, const char *filename); isc_result_t dns_db_dump(dns_db_t *db, dns_dbversion_t *version, const char *filename); + +isc_result_t +dns_db_dump2(dns_db_t *db, dns_dbversion_t *version, const char *filename, + dns_masterformat_t masterformat); /*%< * Dump version 'version' of 'db' to master file 'filename'. * diff --git a/lib/dns/include/dns/master.h b/lib/dns/include/dns/master.h index 7a9661f2b2..d5c15d871d 100644 --- a/lib/dns/include/dns/master.h +++ b/lib/dns/include/dns/master.h @@ -15,7 +15,7 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: master.h,v 1.43 2005/05/19 04:59:04 marka Exp $ */ +/* $Id: master.h,v 1.44 2005/06/20 01:03:54 marka Exp $ */ #ifndef DNS_MASTER_H #define DNS_MASTER_H 1 @@ -57,6 +57,38 @@ ISC_LANG_BEGINDECLS +/* + * Structures that implement the "raw" format for master dump. + * These are provided for a reference purpose only; in the actual + * encoding, we directly read/write each field so that the encoded data + * is always "packed", regardless of the hardware architecture. + */ +#define DNS_RAWFORMAT_VERSION 0 + +/* Common header */ +typedef struct { + isc_uint32_t format; /* must be + * dns_masterformat_raw */ + isc_uint32_t version; /* compatibility for future + * extensions */ + isc_uint32_t dumptime; /* timestamp on creation + * (currently unused) + */ +} dns_masterrawheader_t; + +/* The structure for each RRset */ +typedef struct { + isc_uint32_t totallen; /* length of the data for this + * RRset, including the + * "header" part */ + dns_rdataclass_t rdclass; /* 16-bit class */ + dns_rdatatype_t type; /* 16-bit type */ + dns_rdatatype_t covers; /* same as type */ + dns_ttl_t ttl; /* 32-bit TTL */ + isc_uint32_t nrdata; /* number of RRs in this set */ + /* followed by encoded owner name, and then rdata */ +} dns_masterrawrdataset_t; + /*** *** Function ***/ @@ -70,6 +102,16 @@ dns_master_loadfile(const char *master_file, dns_rdatacallbacks_t *callbacks, isc_mem_t *mctx); +isc_result_t +dns_master_loadfile2(const char *master_file, + dns_name_t *top, + dns_name_t *origin, + dns_rdataclass_t zclass, + unsigned int options, + dns_rdatacallbacks_t *callbacks, + isc_mem_t *mctx, + dns_masterformat_t format); + isc_result_t dns_master_loadstream(FILE *stream, dns_name_t *top, @@ -108,6 +150,18 @@ dns_master_loadfileinc(const char *master_file, dns_loaddonefunc_t done, void *done_arg, dns_loadctx_t **ctxp, isc_mem_t *mctx); +isc_result_t +dns_master_loadfileinc2(const char *master_file, + dns_name_t *top, + dns_name_t *origin, + dns_rdataclass_t zclass, + unsigned int options, + dns_rdatacallbacks_t *callbacks, + isc_task_t *task, + dns_loaddonefunc_t done, void *done_arg, + dns_loadctx_t **ctxp, isc_mem_t *mctx, + dns_masterformat_t format); + isc_result_t dns_master_loadstreaminc(FILE *stream, dns_name_t *top, diff --git a/lib/dns/include/dns/masterdump.h b/lib/dns/include/dns/masterdump.h index 0742efd0ac..a7f36f8a55 100644 --- a/lib/dns/include/dns/masterdump.h +++ b/lib/dns/include/dns/masterdump.h @@ -15,7 +15,7 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: masterdump.h,v 1.33 2005/04/29 00:22:59 marka Exp $ */ +/* $Id: masterdump.h,v 1.34 2005/06/20 01:03:54 marka Exp $ */ #ifndef DNS_MASTERDUMP_H #define DNS_MASTERDUMP_H 1 @@ -211,10 +211,19 @@ isc_result_t dns_master_dumptostream(isc_mem_t *mctx, dns_db_t *db, dns_dbversion_t *version, const dns_master_style_t *style, FILE *f); + +isc_result_t +dns_master_dumptostream2(isc_mem_t *mctx, dns_db_t *db, + dns_dbversion_t *version, + const dns_master_style_t *style, + dns_masterformat_t format, FILE *f); /*%< - * Dump the database 'db' to the steam 'f' in RFC1035 master - * file format, in the style defined by 'style' - * (e.g., &dns_default_master_style_default) + * Dump the database 'db' to the steam 'f' in the specified format by + * 'format'. If the format is dns_masterformat_text (the RFC1035 format), + * 'style' specifies the file style (e.g., &dns_master_style_default). + * + * dns_master_dumptostream() is an old form of dns_master_dumptostream2(), + * which always specifies the dns_masterformat_text format. * * Temporary dynamic memory may be allocated from 'mctx'. * @@ -239,14 +248,30 @@ dns_master_dumpinc(isc_mem_t *mctx, dns_db_t *db, dns_dbversion_t *version, isc_task_t *task, dns_dumpdonefunc_t done, void *done_arg, dns_dumpctx_t **dctxp); +isc_result_t +dns_master_dumpinc2(isc_mem_t *mctx, dns_db_t *db, dns_dbversion_t *version, + const dns_master_style_t *style, const char *filename, + isc_task_t *task, dns_dumpdonefunc_t done, void *done_arg, dns_dumpctx_t **dctxp, dns_masterformat_t format); + isc_result_t dns_master_dump(isc_mem_t *mctx, dns_db_t *db, dns_dbversion_t *version, const dns_master_style_t *style, const char *filename); + +isc_result_t +dns_master_dump2(isc_mem_t *mctx, dns_db_t *db, + dns_dbversion_t *version, + const dns_master_style_t *style, const char *filename, + dns_masterformat_t format); + /*%< - * Dump the database 'db' to the file 'filename' in RFC1035 master - * file format, in the style defined by 'style' - * (e.g., &dns_default_master_style_default) + * Dump the database 'db' to the file 'filename' in the specified format by + * 'format'. If the format is dns_masterformat_text (the RFC1035 format), + * 'style' specifies the file style (e.g., &dns_master_style_default). + * + * dns_master_dumpinc() and dns_master_dump() are old forms of _dumpinc2() + * and _dump2(), respectively, which always specify the dns_masterformat_text + * format. * * Temporary dynamic memory may be allocated from 'mctx'. * diff --git a/lib/dns/include/dns/types.h b/lib/dns/include/dns/types.h index d3aec3bad3..cf77d16a1d 100644 --- a/lib/dns/include/dns/types.h +++ b/lib/dns/include/dns/types.h @@ -15,7 +15,7 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: types.h,v 1.115 2005/05/19 04:59:04 marka Exp $ */ +/* $Id: types.h,v 1.116 2005/06/20 01:03:54 marka Exp $ */ #ifndef DNS_TYPES_H #define DNS_TYPES_H 1 @@ -152,6 +152,12 @@ typedef enum { dns_dialuptype_passive = 5 } dns_dialuptype_t; +typedef enum { + dns_masterformat_none = 0, + dns_masterformat_text = 1, + dns_masterformat_raw = 2 +} dns_masterformat_t; + /* * These are generated by gen.c. */ diff --git a/lib/dns/include/dns/zone.h b/lib/dns/include/dns/zone.h index cf70fba749..7daa709d4f 100644 --- a/lib/dns/include/dns/zone.h +++ b/lib/dns/include/dns/zone.h @@ -15,7 +15,7 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: zone.h,v 1.134 2005/05/19 04:59:05 marka Exp $ */ +/* $Id: zone.h,v 1.135 2005/06/20 01:03:55 marka Exp $ */ #ifndef DNS_ZONE_H #define DNS_ZONE_H 1 @@ -32,6 +32,7 @@ #include #include +#include #include typedef enum { @@ -193,14 +194,23 @@ dns_zone_getorigin(dns_zone_t *zone); isc_result_t dns_zone_setfile(dns_zone_t *zone, const char *file); + +isc_result_t +dns_zone_setfile2(dns_zone_t *zone, const char *file, + dns_masterformat_t format); /*%< - * Sets the name of the master file from which the zone - * loads its database to 'file'. For zones that have - * no associated master file, 'file' will be NULL. + * Sets the name of the master file in the format of 'format' from which + * the zone loads its database to 'file'. + * + * For zones that have no associated master file, 'file' will be NULL. * * For zones with persistent databases, the file name * setting is ignored. * + * dns_zone_setfile() is a backward-compatible form of + * dns_zone_setfile2(), which always specifies the + * dns_masterformat_text (RFC1035) format. + * * Require: *\li 'zone' to be a valid zone. * @@ -390,8 +400,21 @@ dns_zone_dump(dns_zone_t *zone); isc_result_t dns_zone_dumptostream(dns_zone_t *zone, FILE *fd); + +isc_result_t +dns_zone_dumptostream2(dns_zone_t *zone, FILE *fd, dns_masterformat_t format, + const dns_master_style_t *style); /*%< - * Write the zone to stream 'fd'. + * Write the zone to stream 'fd' in the specified 'format'. + * If the 'format' is dns_masterformat_text (RFC1035), 'style' also + * specifies the file style (e.g., &dns_master_style_default). + * + * dns_zone_dumptostream() is a backward-compatible form of + * dns_zone_dumptostream2(), which always uses the dns_masterformat_text + * format and the dns_master_style_default style. + * + * Note that dns_zone_dumptostream2() is the most flexible form. It + * can also provide the functionality of dns_zone_fulldumptostream(). * * Require: *\li 'zone' to be a valid zone. diff --git a/lib/dns/master.c b/lib/dns/master.c index a697dbe4e6..24203e22cb 100644 --- a/lib/dns/master.c +++ b/lib/dns/master.c @@ -15,7 +15,7 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: master.c,v 1.154 2005/06/04 00:18:54 marka Exp $ */ +/* $Id: master.c,v 1.155 2005/06/20 01:03:53 marka Exp $ */ /*! \file */ @@ -27,6 +27,7 @@ #include #include #include +#include #include #include #include @@ -97,12 +98,21 @@ typedef struct dns_incctx dns_incctx_t; struct dns_loadctx { unsigned int magic; isc_mem_t *mctx; - isc_lex_t *lex; - isc_boolean_t keep_lex; + dns_masterformat_t format; + dns_rdatacallbacks_t *callbacks; isc_task_t *task; dns_loaddonefunc_t done; void *done_arg; + + /* Common methods */ + isc_result_t (*openfile)(dns_loadctx_t *lctx, + const char *filename); + isc_result_t (*load)(dns_loadctx_t *lctx); + + /* Members specific to the text format: */ + isc_lex_t *lex; + isc_boolean_t keep_lex; unsigned int options; isc_boolean_t ttl_known; isc_boolean_t default_ttl_known; @@ -115,6 +125,11 @@ struct dns_loadctx { dns_rdataclass_t zclass; dns_fixedname_t fixed_top; dns_name_t *top; /*%< top of zone */ + + /* Members specific to the raw format: */ + FILE *f; + isc_boolean_t first; + /* Which fixed buffers we are using? */ unsigned int loop_cnt; /*% records per quantum, * 0 => all. */ @@ -146,6 +161,18 @@ struct dns_incctx { #define DNS_AS_STR(t) ((t).value.as_textregion.base) +static isc_result_t +openfile_text(dns_loadctx_t *lctx, const char *master_file); + +static isc_result_t +openfile_raw(dns_loadctx_t *lctx, const char *master_file); + +static isc_result_t +load_text(dns_loadctx_t *lctx); + +static isc_result_t +load_raw(dns_loadctx_t *lctx); + static isc_result_t pushfile(const char *master_file, dns_name_t *origin, dns_loadctx_t *lctx); @@ -408,6 +435,7 @@ incctx_destroy(isc_mem_t *mctx, dns_incctx_t *ictx) { static void loadctx_destroy(dns_loadctx_t *lctx) { isc_mem_t *mctx; + isc_result_t result; REQUIRE(DNS_LCTX_VALID(lctx)); @@ -415,6 +443,15 @@ loadctx_destroy(dns_loadctx_t *lctx) { if (lctx->inc != NULL) incctx_destroy(lctx->mctx, lctx->inc); + if (lctx->f != NULL) { + result = isc_stdio_close(lctx->f); + if (result != ISC_R_SUCCESS) { + UNEXPECTED_ERROR(__FILE__, __LINE__, + "isc_stdio_close() failed: %s", + isc_result_totext(result)); + } + } + /* isc_lex_destroy() will close all open streams */ if (lctx->lex != NULL && !lctx->keep_lex) isc_lex_destroy(&lctx->lex); @@ -464,7 +501,8 @@ incctx_create(isc_mem_t *mctx, dns_name_t *origin, dns_incctx_t **ictxp) { } static isc_result_t -loadctx_create(isc_mem_t *mctx, unsigned int options, dns_name_t *top, +loadctx_create(dns_masterformat_t format, isc_mem_t *mctx, + unsigned int options, dns_name_t *top, dns_rdataclass_t zclass, dns_name_t *origin, dns_rdatacallbacks_t *callbacks, isc_task_t *task, dns_loaddonefunc_t done, void *done_arg, isc_lex_t *lex, @@ -503,6 +541,20 @@ loadctx_create(isc_mem_t *mctx, unsigned int options, dns_name_t *top, if (result != ISC_R_SUCCESS) goto cleanup_ctx; + lctx->format = format; + switch (format) { + default: + INSIST(0); + case dns_masterformat_text: + lctx->openfile = openfile_text; + lctx->load = load_text; + break; + case dns_masterformat_raw: + lctx->openfile = openfile_raw; + lctx->load = load_raw; + break; + } + if (lex != NULL) { lctx->lex = lex; lctx->keep_lex = ISC_TRUE; @@ -537,6 +589,9 @@ loadctx_create(isc_mem_t *mctx, unsigned int options, dns_name_t *top, dns_name_toregion(top, &r); dns_name_fromregion(lctx->top, &r); + lctx->f = NULL; + lctx->first = ISC_TRUE; + lctx->loop_cnt = (done != NULL) ? 100 : 0; lctx->callbacks = callbacks; lctx->task = NULL; @@ -642,6 +697,25 @@ genname(char *name, int it, char *buffer, size_t length) { return (ISC_R_SUCCESS); } +static isc_result_t +openfile_text(dns_loadctx_t *lctx, const char *master_file) { + return (isc_lex_openfile(lctx->lex, master_file)); +} + +static isc_result_t +openfile_raw(dns_loadctx_t *lctx, const char *master_file) { + isc_result_t result; + + result = isc_stdio_open(master_file, "r", &lctx->f); + if (result != ISC_R_SUCCESS && result != ISC_R_FILENOTFOUND) { + UNEXPECTED_ERROR(__FILE__, __LINE__, + "isc_stdio_open() failed: %s", + isc_result_totext(result)); + } + + return (result); +} + static isc_result_t generate(dns_loadctx_t *lctx, char *range, char *lhs, char *gtype, char *rhs, const char *source, unsigned int line) @@ -884,7 +958,7 @@ check_wildcard(dns_incctx_t *ictx, const char *source, unsigned long line, } static isc_result_t -load(dns_loadctx_t *lctx) { +load_text(dns_loadctx_t *lctx) { dns_rdataclass_t rdclass; dns_rdatatype_t type, covers; isc_uint32_t ttl_offset = 0; @@ -1914,7 +1988,7 @@ pushfile(const char *master_file, dns_name_t *origin, dns_loadctx_t *lctx) { new->drop = ictx->drop; } - result = isc_lex_openfile(lctx->lex, master_file); + result = (lctx->openfile)(lctx, master_file); if (result != ISC_R_SUCCESS) goto cleanup; new->parent = ictx; @@ -1927,25 +2001,349 @@ pushfile(const char *master_file, dns_name_t *origin, dns_loadctx_t *lctx) { return (result); } +static inline isc_result_t +read_and_check(isc_boolean_t do_read, isc_buffer_t *buffer, + size_t len, FILE *f) +{ + isc_result_t result; + + if (do_read) { + INSIST(isc_buffer_availablelength(buffer) >= len); + result = isc_stdio_read(isc_buffer_used(buffer), 1, len, + f, NULL); + if (result != ISC_R_SUCCESS) + return (result); + isc_buffer_add(buffer, len); + } else if (isc_buffer_remaininglength(buffer) < len) + return (ISC_R_RANGE); + + return (ISC_R_SUCCESS); +} + +isc_result_t +load_raw(dns_loadctx_t *lctx) { + isc_result_t result = ISC_R_SUCCESS; + isc_boolean_t done = ISC_FALSE; + unsigned int loop_cnt = 0; + dns_rdatacallbacks_t *callbacks; + unsigned char namebuf[DNS_NAME_MAXWIRE]; + isc_region_t r; + dns_name_t name; + rdatalist_head_t head, dummy; + dns_rdatalist_t rdatalist; + isc_mem_t *mctx = lctx->mctx; + dns_rdata_t *rdata = NULL; + unsigned int rdata_size = 0; + int target_size = TSIZ; + isc_buffer_t target; + unsigned char *target_mem = NULL; + + REQUIRE(DNS_LCTX_VALID(lctx)); + callbacks = lctx->callbacks; + + if (lctx->first) { + dns_masterrawheader_t header; + isc_uint32_t format, version, dumptime; + size_t hdrlen = sizeof(format) + sizeof(version) + + sizeof(dumptime); + + INSIST(hdrlen <= sizeof(header)); + isc_buffer_init(&target, &header, sizeof(header)); + + result = isc_stdio_read(&header, 1, hdrlen, lctx->f, NULL); + if (result != ISC_R_SUCCESS) { + UNEXPECTED_ERROR(__FILE__, __LINE__, + "isc_stdio_read failed: %s", + isc_result_totext(result)); + return (result); + } + isc_buffer_add(&target, hdrlen); + format = isc_buffer_getuint32(&target); + if (format != dns_masterformat_raw) { + (*callbacks->error)(callbacks, + "dns_master_load: " + "file format mismatch"); + return (ISC_R_NOTIMPLEMENTED); + } + + version = isc_buffer_getuint32(&target); + if (version > DNS_RAWFORMAT_VERSION) { + (*callbacks->error)(callbacks, + "dns_master_load: " + "unsupported file format version"); + return (ISC_R_NOTIMPLEMENTED); + } + + /* Empty read: currently, we do not use dumptime */ + dumptime = isc_buffer_getuint32(&target); + + lctx->first = ISC_FALSE; + } + + ISC_LIST_INIT(head); + ISC_LIST_INIT(dummy); + dns_rdatalist_init(&rdatalist); + + /* + * Allocate target_size of buffer space. This is greater than twice + * the maximum individual RR data size. + */ + target_mem = isc_mem_get(mctx, target_size); + if (target_mem == NULL) { + result = ISC_R_NOMEMORY; + goto cleanup; + } + isc_buffer_init(&target, target_mem, target_size); + + /* + * In the following loop, we regard any error fatal regardless of + * whether "MANYERRORS" is set in the context option. This is because + * normal errors should already have been checked at creation time. + * Besides, it is very unlikely that we can recover from an error + * in this format, and so trying to continue parsing erroneous data + * does not really make sense. + */ + for (loop_cnt = 0; + (lctx->loop_cnt == 0 || loop_cnt < lctx->loop_cnt); + loop_cnt++) { + dns_masterrawrdataset_t rawrrset; + unsigned int i, rdcount, consumed_name; + isc_uint16_t namelen; + isc_uint32_t totallen; + size_t minlen, readlen; + isc_boolean_t sequential_read = ISC_FALSE; + + /* Read the data length */ + isc_buffer_clear(&target); + INSIST(isc_buffer_availablelength(&target) >= + sizeof(totallen)); + result = isc_stdio_read(target.base, 1, sizeof(totallen), + lctx->f, NULL); + if (result == ISC_R_EOF) { + result = ISC_R_SUCCESS; + done = ISC_TRUE; + break; + } + if (result != ISC_R_SUCCESS) + goto cleanup; + isc_buffer_add(&target, sizeof(totallen)); + totallen = isc_buffer_getuint32(&target); + /* + * Validation: the input data must at least contain the common + * header. + */ + minlen = sizeof(totallen) + sizeof(isc_uint16_t) + + sizeof(isc_uint16_t) + sizeof(isc_uint16_t) + + sizeof(isc_uint32_t) + sizeof(isc_uint32_t); + if (totallen < minlen) { + result = ISC_R_RANGE; + goto cleanup; + } + totallen -= sizeof(totallen); + + isc_buffer_clear(&target); + if (totallen > isc_buffer_availablelength(&target)) { + /* + * The default buffer size should typically be large + * enough to store the entire RRset. We could try to + * allocate enough space if this is not the case, but + * it might cause a hazardous result when "totallen" + * is forged. Thus, we'd rather take an inefficient + * but robust approach in this atypical case: read + * data step by step, and commit partial data when + * necessary. Note that the buffer must be large + * enough to store the "header part", owner name, and + * at least one rdata (however large it is). + */ + sequential_read = ISC_TRUE; + readlen = minlen - sizeof(totallen); + } else { + /* + * Typical case. We can read the whole RRset at once + * with the default buffer. + */ + readlen = totallen; + } + result = isc_stdio_read(target.base, 1, readlen, + lctx->f, NULL); + if (result != ISC_R_SUCCESS) + goto cleanup; + isc_buffer_add(&target, readlen); + + /* Construct RRset headers */ + rdatalist.rdclass = isc_buffer_getuint16(&target); + rdatalist.type = isc_buffer_getuint16(&target); + rdatalist.covers = isc_buffer_getuint16(&target); + rdatalist.ttl = isc_buffer_getuint32(&target); + rdcount = isc_buffer_getuint32(&target); + INSIST(isc_buffer_consumedlength(&target) <= readlen); + + /* Owner name: length followed by name */ + result = read_and_check(sequential_read, &target, + sizeof(namelen), lctx->f); + if (result != ISC_R_SUCCESS) + goto cleanup; + namelen = isc_buffer_getuint16(&target); + if (namelen > sizeof(namebuf)) { + result = ISC_R_RANGE; + goto cleanup; + } + + result = read_and_check(sequential_read, &target, namelen, + lctx->f); + if (result != ISC_R_SUCCESS) + goto cleanup; + isc_buffer_setactive(&target, (unsigned int)namelen); + isc_buffer_activeregion(&target, &r); + dns_name_init(&name, NULL); + dns_name_fromregion(&name, &r); + isc_buffer_forward(&target, (unsigned int)namelen); + consumed_name = isc_buffer_consumedlength(&target); + + /* Rdata contents. */ + if (rdcount > rdata_size) { + dns_rdata_t *new_rdata = NULL; + + new_rdata = grow_rdata(rdata_size + RDSZ, rdata, + rdata_size, &head, + &dummy, mctx); + if (new_rdata == NULL) { + result = ISC_R_NOMEMORY; + goto cleanup; + } + rdata_size += RDSZ; + rdata = new_rdata; + } + + continue_read: + for (i = 0; i < rdcount; i++) { + isc_uint16_t rdlen; + + dns_rdata_init(&rdata[i]); + + if (sequential_read && + isc_buffer_availablelength(&target) < MINTSIZ) { + unsigned int j; + + INSIST(i > 0); /* detect an infinite loop */ + + /* Partial Commit. */ + ISC_LIST_APPEND(head, &rdatalist, link); + result = commit(callbacks, lctx, &head, &name, + NULL, 0); + for (j = 0; j < i; j++) { + ISC_LIST_UNLINK(rdatalist.rdata, + &rdata[j], link); + dns_rdata_reset(&rdata[j]); + } + if (result != ISC_R_SUCCESS) + goto cleanup; + + /* Rewind the buffer and continue */ + isc_buffer_clear(&target); + isc_buffer_add(&target, consumed_name); + isc_buffer_forward(&target, consumed_name); + + rdcount -= i; + i = 0; + + goto continue_read; + } + + /* rdata length */ + result = read_and_check(sequential_read, &target, + sizeof(rdlen), lctx->f); + if (result != ISC_R_SUCCESS) + goto cleanup; + rdlen = isc_buffer_getuint16(&target); + + /* rdata */ + result = read_and_check(sequential_read, &target, + rdlen, lctx->f); + if (result != ISC_R_SUCCESS) + goto cleanup; + isc_buffer_setactive(&target, (unsigned int)rdlen); + isc_buffer_activeregion(&target, &r); + isc_buffer_forward(&target, (unsigned int)rdlen); + dns_rdata_fromregion(&rdata[i], rawrrset.rdclass, + rdatalist.type, &r); + + ISC_LIST_APPEND(rdatalist.rdata, &rdata[i], link); + } + + /* + * Sanity check. Still having remaining space is not + * necessarily critical, but it very likely indicates broken + * or malformed data. + */ + if (isc_buffer_remaininglength(&target) != 0) { + result = ISC_R_RANGE; + goto cleanup; + } + + ISC_LIST_APPEND(head, &rdatalist, link); + + /* Commit this RRset. rdatalist will be unlinked. */ + result = commit(callbacks, lctx, &head, &name, NULL, 0); + + for (i = 0; i < rdcount; i++) { + ISC_LIST_UNLINK(rdatalist.rdata, &rdata[i], link); + dns_rdata_reset(&rdata[i]); + } + + if (result != ISC_R_SUCCESS) + goto cleanup; + } + + if (!done) { + INSIST(lctx->done != NULL && lctx->task != NULL); + result = DNS_R_CONTINUE; + } else if (result == ISC_R_SUCCESS && lctx->result != ISC_R_SUCCESS) + result = lctx->result; + + cleanup: + if (rdata != NULL) + isc_mem_put(mctx, rdata, rdata_size * sizeof(*rdata)); + if (target_mem != NULL) + isc_mem_put(mctx, target_mem, target_size); + if (result != ISC_R_SUCCESS && result != DNS_R_CONTINUE) { + (*callbacks->error)(callbacks, "dns_master_load: %s", + dns_result_totext(result)); + } + + return (result); +} + isc_result_t dns_master_loadfile(const char *master_file, dns_name_t *top, dns_name_t *origin, dns_rdataclass_t zclass, unsigned int options, dns_rdatacallbacks_t *callbacks, isc_mem_t *mctx) +{ + return (dns_master_loadfile2(master_file, top, origin, zclass, options, + callbacks, mctx, dns_masterformat_text)); +} + +isc_result_t +dns_master_loadfile2(const char *master_file, dns_name_t *top, + dns_name_t *origin, + dns_rdataclass_t zclass, unsigned int options, + dns_rdatacallbacks_t *callbacks, isc_mem_t *mctx, + dns_masterformat_t format) { dns_loadctx_t *lctx = NULL; isc_result_t result; - result = loadctx_create(mctx, options, top, zclass, origin, + result = loadctx_create(format, mctx, options, top, zclass, origin, callbacks, NULL, NULL, NULL, NULL, &lctx); if (result != ISC_R_SUCCESS) return (result); - result = isc_lex_openfile(lctx->lex, master_file); + result = (lctx->openfile)(lctx, master_file); if (result != ISC_R_SUCCESS) goto cleanup; - result = load(lctx); + result = (lctx->load)(lctx); INSIST(result != DNS_R_CONTINUE); cleanup: @@ -1960,19 +2358,33 @@ dns_master_loadfileinc(const char *master_file, dns_name_t *top, unsigned int options, dns_rdatacallbacks_t *callbacks, isc_task_t *task, dns_loaddonefunc_t done, void *done_arg, dns_loadctx_t **lctxp, isc_mem_t *mctx) +{ + return (dns_master_loadfileinc2(master_file, top, origin, zclass, + options, callbacks, task, done, + done_arg, lctxp, mctx, + dns_masterformat_text)); +} + +isc_result_t +dns_master_loadfileinc2(const char *master_file, dns_name_t *top, + dns_name_t *origin, dns_rdataclass_t zclass, + unsigned int options, dns_rdatacallbacks_t *callbacks, + isc_task_t *task, dns_loaddonefunc_t done, + void *done_arg, dns_loadctx_t **lctxp, isc_mem_t *mctx, + dns_masterformat_t format) { dns_loadctx_t *lctx = NULL; isc_result_t result; - + REQUIRE(task != NULL); REQUIRE(done != NULL); - result = loadctx_create(mctx, options, top, zclass, origin, + result = loadctx_create(format, mctx, options, top, zclass, origin, callbacks, task, done, done_arg, NULL, &lctx); if (result != ISC_R_SUCCESS) return (result); - result = isc_lex_openfile(lctx->lex, master_file); + result = (lctx->openfile)(lctx, master_file); if (result != ISC_R_SUCCESS) goto cleanup; @@ -1998,8 +2410,9 @@ dns_master_loadstream(FILE *stream, dns_name_t *top, dns_name_t *origin, REQUIRE(stream != NULL); - result = loadctx_create(mctx, options, top, zclass, origin, - callbacks, NULL, NULL, NULL, NULL, &lctx); + result = loadctx_create(dns_masterformat_text, mctx, options, top, + zclass, origin, callbacks, NULL, NULL, NULL, + NULL, &lctx); if (result != ISC_R_SUCCESS) goto cleanup; @@ -2007,7 +2420,7 @@ dns_master_loadstream(FILE *stream, dns_name_t *top, dns_name_t *origin, if (result != ISC_R_SUCCESS) goto cleanup; - result = load(lctx); + result = (lctx->load)(lctx); INSIST(result != DNS_R_CONTINUE); cleanup: @@ -2030,8 +2443,9 @@ dns_master_loadstreaminc(FILE *stream, dns_name_t *top, dns_name_t *origin, REQUIRE(task != NULL); REQUIRE(done != NULL); - result = loadctx_create(mctx, options, top, zclass, origin, - callbacks, task, done, done_arg, NULL, &lctx); + result = loadctx_create(dns_masterformat_text, mctx, options, top, + zclass, origin, callbacks, task, done, + done_arg, NULL, &lctx); if (result != ISC_R_SUCCESS) goto cleanup; @@ -2062,8 +2476,9 @@ dns_master_loadbuffer(isc_buffer_t *buffer, dns_name_t *top, REQUIRE(buffer != NULL); - result = loadctx_create(mctx, options, top, zclass, origin, - callbacks, NULL, NULL, NULL, NULL, &lctx); + result = loadctx_create(dns_masterformat_text, mctx, options, top, + zclass, origin, callbacks, NULL, NULL, NULL, + NULL, &lctx); if (result != ISC_R_SUCCESS) return (result); @@ -2071,7 +2486,7 @@ dns_master_loadbuffer(isc_buffer_t *buffer, dns_name_t *top, if (result != ISC_R_SUCCESS) goto cleanup; - result = load(lctx); + result = (lctx->load)(lctx); INSIST(result != DNS_R_CONTINUE); cleanup: @@ -2095,8 +2510,9 @@ dns_master_loadbufferinc(isc_buffer_t *buffer, dns_name_t *top, REQUIRE(task != NULL); REQUIRE(done != NULL); - result = loadctx_create(mctx, options, top, zclass, origin, - callbacks, task, done, done_arg, NULL, &lctx); + result = loadctx_create(dns_masterformat_text, mctx, options, top, + zclass, origin, callbacks, task, done, + done_arg, NULL, &lctx); if (result != ISC_R_SUCCESS) return (result); @@ -2127,12 +2543,13 @@ dns_master_loadlexer(isc_lex_t *lex, dns_name_t *top, REQUIRE(lex != NULL); - result = loadctx_create(mctx, options, top, zclass, origin, - callbacks, NULL, NULL, NULL, lex, &lctx); + result = loadctx_create(dns_masterformat_text, mctx, options, top, + zclass, origin, callbacks, NULL, NULL, NULL, + lex, &lctx); if (result != ISC_R_SUCCESS) return (result); - result = load(lctx); + result = (lctx->load)(lctx); INSIST(result != DNS_R_CONTINUE); dns_loadctx_detach(&lctx); @@ -2154,8 +2571,9 @@ dns_master_loadlexerinc(isc_lex_t *lex, dns_name_t *top, REQUIRE(task != NULL); REQUIRE(done != NULL); - result = loadctx_create(mctx, options, top, zclass, origin, - callbacks, task, done, done_arg, lex, &lctx); + result = loadctx_create(dns_masterformat_text, mctx, options, top, + zclass, origin, callbacks, task, done, + done_arg, lex, &lctx); if (result != ISC_R_SUCCESS) return (result); @@ -2316,9 +2734,15 @@ commit(dns_rdatacallbacks_t *callbacks, dns_loadctx_t *lctx, } else if (result != ISC_R_SUCCESS) { dns_name_format(owner, namebuf, sizeof(namebuf)); - (*error)(callbacks, "%s: %s:%lu: %s: %s", - "dns_master_load", source, line, - namebuf, dns_result_totext(result)); + if (source != NULL) { + (*error)(callbacks, "%s: %s:%lu: %s: %s", + "dns_master_load", source, line, + namebuf, dns_result_totext(result)); + } else { + (*error)(callbacks, "%s: %s: %s", + "dns_master_load", namebuf, + dns_result_totext(result)); + } } if (MANYERRS(lctx, result)) SETRESULT(lctx, result); @@ -2377,7 +2801,7 @@ load_quantum(isc_task_t *task, isc_event_t *event) { if (lctx->canceled) result = ISC_R_CANCELED; else - result = load(lctx); + result = (lctx->load)(lctx); if (result == DNS_R_CONTINUE) { event->ev_arg = lctx; isc_task_send(task, &event); diff --git a/lib/dns/masterdump.c b/lib/dns/masterdump.c index 0800f29c19..72327d9558 100644 --- a/lib/dns/masterdump.c +++ b/lib/dns/masterdump.c @@ -15,7 +15,7 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: masterdump.c,v 1.77 2005/04/29 00:22:48 marka Exp $ */ +/* $Id: masterdump.c,v 1.78 2005/06/20 01:03:53 marka Exp $ */ /*! \file */ @@ -38,6 +38,7 @@ #include #include #include +#include #include #include #include @@ -173,6 +174,11 @@ struct dns_dumpctx { /* dns_master_dumpinc() */ char *file; char *tmpfile; + dns_masterformat_t format; + isc_result_t (*dumpsets)(isc_mem_t *mctx, dns_name_t *name, + dns_rdatasetiter_t *rdsiter, + dns_totext_ctx_t *ctx, + isc_buffer_t *buffer, FILE *f); }; #define NXDOMAIN(x) (((x)->attributes & DNS_RDATASETATTR_NXDOMAIN) != 0) @@ -776,9 +782,9 @@ static const char *trustnames[] = { }; static isc_result_t -dump_rdatasets(isc_mem_t *mctx, dns_name_t *name, dns_rdatasetiter_t *rdsiter, - dns_totext_ctx_t *ctx, - isc_buffer_t *buffer, FILE *f) +dump_rdatasets_text(isc_mem_t *mctx, dns_name_t *name, + dns_rdatasetiter_t *rdsiter, dns_totext_ctx_t *ctx, + isc_buffer_t *buffer, FILE *f) { isc_result_t itresult, dumpresult; isc_region_t r; @@ -850,6 +856,145 @@ dump_rdatasets(isc_mem_t *mctx, dns_name_t *name, dns_rdatasetiter_t *rdsiter, return (itresult); } +/* + * Dump given RRsets in the "raw" format. + */ +static isc_result_t +dump_rdataset_raw(isc_mem_t *mctx, dns_name_t *name, dns_rdataset_t *rdataset, + isc_buffer_t *buffer, FILE *f) +{ + isc_result_t result; + isc_uint32_t totallen; + isc_uint16_t dlen; + isc_region_t r, r_hdr; + + REQUIRE(buffer->length > 0); + REQUIRE(DNS_RDATASET_VALID(rdataset)); + + restart: + totallen = 0; + result = dns_rdataset_first(rdataset); + REQUIRE(result == ISC_R_SUCCESS); + + isc_buffer_clear(buffer); + + /* + * Common header and owner name (length followed by name) + * These fields should be in a moderate length, so we assume we + * can store all of them in the initial buffer. + */ + isc_buffer_availableregion(buffer, &r_hdr); + INSIST(r_hdr.length >= sizeof(dns_masterrawrdataset_t)); + isc_buffer_putuint32(buffer, totallen); /* XXX: leave space */ + isc_buffer_putuint16(buffer, rdataset->rdclass); /* 16-bit class */ + isc_buffer_putuint16(buffer, rdataset->type); /* 16-bit type */ + isc_buffer_putuint16(buffer, rdataset->covers); /* same as type */ + isc_buffer_putuint32(buffer, rdataset->ttl); /* 32-bit TTL */ + isc_buffer_putuint32(buffer, dns_rdataset_count(rdataset)); + totallen = isc_buffer_usedlength(buffer); + INSIST(totallen <= sizeof(dns_masterrawrdataset_t)); + + dns_name_toregion(name, &r); + INSIST(isc_buffer_availablelength(buffer) >= + (sizeof(dlen) + r.length)); + dlen = (isc_uint16_t)r.length; + isc_buffer_putuint16(buffer, dlen); + isc_buffer_copyregion(buffer, &r); + totallen += sizeof(dlen) + r.length; + + do { + dns_rdata_t rdata = DNS_RDATA_INIT; + isc_region_t r; + + dns_rdataset_current(rdataset, &rdata); + dns_rdata_toregion(&rdata, &r); + INSIST(r.length <= DNS_NAME_MAXWIRE); + dlen = (isc_uint16_t)r.length; + + /* + * Copy the rdata into the buffer. If the buffer is too small, + * grow it. This should be rare, so we'll simply restart the + * entire procedure (or should we copy the old data and + * continue?). + */ + if (isc_buffer_availablelength(buffer) < dlen + r.length) { + int newlength; + void *newmem; + + newlength = buffer->length * 2; + newmem = isc_mem_get(mctx, newlength); + if (newmem == NULL) + return (ISC_R_NOMEMORY); + isc_mem_put(mctx, buffer->base, buffer->length); + isc_buffer_init(buffer, newmem, newlength); + goto restart; + } + isc_buffer_putuint16(buffer, dlen); + isc_buffer_copyregion(buffer, &r); + totallen += sizeof(dlen) + r.length; + + result = dns_rdataset_next(rdataset); + } while (result == ISC_R_SUCCESS); + + if (result != ISC_R_NOMORE) + return (result); + + /* + * Fill in the total length field. + * XXX: this is a bit tricky. Since we have already "used" the space + * for the total length in the buffer, we first remember the entire + * buffer length in the region, "rewind", and then write the value. + */ + isc_buffer_usedregion(buffer, &r); + isc_buffer_clear(buffer); + isc_buffer_putuint32(buffer, totallen); + INSIST(isc_buffer_usedlength(buffer) < totallen); + + /* + * Write the buffer contents to the raw master file. + */ + result = isc_stdio_write(r.base, 1, (size_t)r.length, f, NULL); + + if (result != ISC_R_SUCCESS) { + UNEXPECTED_ERROR(__FILE__, __LINE__, + "raw master file write failed: %s", + isc_result_totext(result)); + return (result); + } + + return (result); +} + +static isc_result_t +dump_rdatasets_raw(isc_mem_t *mctx, dns_name_t *name, + dns_rdatasetiter_t *rdsiter, dns_totext_ctx_t *ctx, + isc_buffer_t *buffer, FILE *f) +{ + isc_result_t result; + dns_rdataset_t rdataset; + + for (result = dns_rdatasetiter_first(rdsiter); + result == ISC_R_SUCCESS; + result = dns_rdatasetiter_next(rdsiter)) { + + dns_rdataset_init(&rdataset); + dns_rdatasetiter_current(rdsiter, &rdataset); + + if (rdataset.type == 0 && + (ctx->style.flags & DNS_STYLEFLAG_NCACHE) == 0) { + /* Omit negative cache entries */ + } else { + result = dump_rdataset_raw(mctx, name, &rdataset, + buffer, f); + } + dns_rdataset_disassociate(&rdataset); + } + + if (result == ISC_R_NOMORE) + result = ISC_R_SUCCESS; + + return (result); +} /* * Initial size of text conversion buffer. The buffer is used @@ -858,7 +1003,7 @@ dump_rdatasets(isc_mem_t *mctx, dns_name_t *name, dns_rdatasetiter_t *rdsiter, * * When converting rdatasets, it is dynamically resized, but * when converting origins, timestamps, etc it is not. Therefore, - * the initial size must large enough to hold the longest possible + * the initial size must large enough to hold the longest possible * text representation of any domain name (for $ORIGIN). */ static const int initial_buffer_length = 1200; @@ -1023,7 +1168,8 @@ task_send(dns_dumpctx_t *dctx) { static isc_result_t dumpctx_create(isc_mem_t *mctx, dns_db_t *db, dns_dbversion_t *version, - const dns_master_style_t *style, FILE *f, dns_dumpctx_t **dctxp) + const dns_master_style_t *style, FILE *f, dns_dumpctx_t **dctxp, + dns_masterformat_t format) { dns_dumpctx_t *dctx; isc_result_t result; @@ -1046,6 +1192,19 @@ dumpctx_create(isc_mem_t *mctx, dns_db_t *db, dns_dbversion_t *version, dctx->canceled = ISC_FALSE; dctx->file = NULL; dctx->tmpfile = NULL; + dctx->format = format; + + switch (format) { + case dns_masterformat_text: + dctx->dumpsets = dump_rdatasets_text; + break; + case dns_masterformat_raw: + dctx->dumpsets = dump_rdatasets_raw; + break; + default: + INSIST(0); + break; + } result = totext_ctx_init(style, &dctx->tctx); if (result != ISC_R_SUCCESS) { @@ -1059,8 +1218,11 @@ dumpctx_create(isc_mem_t *mctx, dns_db_t *db, dns_dbversion_t *version, dctx->do_date = dns_db_iscache(dctx->db); - relative = ((dctx->tctx.style.flags & DNS_STYLEFLAG_REL_OWNER) != 0) ? - ISC_TRUE : ISC_FALSE; + if (dctx->format == dns_masterformat_text && + (dctx->tctx.style.flags & DNS_STYLEFLAG_REL_OWNER) != 0) { + relative = ISC_TRUE; + } else + relative = ISC_FALSE; result = dns_db_createiterator(dctx->db, relative, &dctx->dbiter); if (result != ISC_R_SUCCESS) goto cleanup; @@ -1097,6 +1259,8 @@ dumptostreaminc(dns_dumpctx_t *dctx) { dns_name_t *name; dns_fixedname_t fixname; unsigned int nodes; + dns_masterrawheader_t rawheader; + isc_uint32_t now32; bufmem = isc_mem_get(dctx->mctx, initial_buffer_length); if (bufmem == NULL) @@ -1108,20 +1272,61 @@ dumptostreaminc(dns_dumpctx_t *dctx) { name = dns_fixedname_name(&fixname); if (dctx->first) { - /* - * If the database has cache semantics, output an RFC2540 - * $DATE directive so that the TTLs can be adjusted when - * it is reloaded. For zones it is not really needed, and - * it would make the file incompatible with pre-RFC2540 - * software, so we omit it in the zone case. - */ - if (dctx->do_date) { - result = dns_time32_totext(dctx->now, &buffer); - RUNTIME_CHECK(result == ISC_R_SUCCESS); - isc_buffer_usedregion(&buffer, &r); - fprintf(dctx->f, "$DATE %.*s\n", - (int) r.length, (char *) r.base); + switch (dctx->format) { + case dns_masterformat_text: + /* + * If the database has cache semantics, output an + * RFC2540 $DATE directive so that the TTLs can be + * adjusted when it is reloaded. For zones it is not + * really needed, and it would make the file + * incompatible with pre-RFC2540 software, so we omit + * it in the zone case. + */ + if (dctx->do_date) { + result = dns_time32_totext(dctx->now, &buffer); + RUNTIME_CHECK(result == ISC_R_SUCCESS); + isc_buffer_usedregion(&buffer, &r); + fprintf(dctx->f, "$DATE %.*s\n", + (int) r.length, (char *) r.base); + } + break; + case dns_masterformat_raw: + r.base = (unsigned char *)&rawheader; + r.length = sizeof(rawheader); + isc_buffer_region(&buffer, &r); + isc_buffer_putuint32(&buffer, dns_masterformat_raw); + isc_buffer_putuint32(&buffer, DNS_RAWFORMAT_VERSION); + if (sizeof(now32) != sizeof(dctx->now)) { + /* + * We assume isc_stdtime_t is a 32-bit integer, + * which should be the case on most cases. + * If it turns out to be uncommon, we'll need + * to bump the version number and revise the + * header format. + */ + isc_log_write(dns_lctx, + ISC_LOGCATEGORY_GENERAL, + DNS_LOGMODULE_MASTERDUMP, + ISC_LOG_INFO, + "dumping master file in raw " + "format: stdtime is not 32bits"); + now32 = 0; + } else + now32 = dctx->now; + isc_buffer_putuint32(&buffer, now32); + INSIST(isc_buffer_usedlength(&buffer) <= + sizeof(rawheader)); + result = isc_stdio_write(buffer.base, 1, + isc_buffer_usedlength(&buffer), + dctx->f, NULL); + if (result != ISC_R_SUCCESS) + return (result); + isc_buffer_clear(&buffer); + break; + default: + INSIST(0); } + result = dns_dbiterator_first(dctx->dbiter); dctx->first = ISC_FALSE; } else @@ -1150,8 +1355,8 @@ dumptostreaminc(dns_dumpctx_t *dctx) { dns_db_detachnode(dctx->db, &node); goto fail; } - result = dump_rdatasets(dctx->mctx, name, rdsiter, &dctx->tctx, - &buffer, dctx->f); + result = (dctx->dumpsets)(dctx->mctx, name, rdsiter, + &dctx->tctx, &buffer, dctx->f); dns_rdatasetiter_destroy(&rdsiter); if (result != ISC_R_SUCCESS) { dns_db_detachnode(dctx->db, &node); @@ -1186,7 +1391,8 @@ dns_master_dumptostreaminc(isc_mem_t *mctx, dns_db_t *db, REQUIRE(f != NULL); REQUIRE(done != NULL); - result = dumpctx_create(mctx, db, version, style, f, &dctx); + result = dumpctx_create(mctx, db, version, style, f, &dctx, + dns_masterformat_text); if (result != ISC_R_SUCCESS) return (result); isc_task_attach(task, &dctx->task); @@ -1213,11 +1419,21 @@ dns_master_dumptostream(isc_mem_t *mctx, dns_db_t *db, dns_dbversion_t *version, const dns_master_style_t *style, FILE *f) +{ + return (dns_master_dumptostream2(mctx, db, version, style, + dns_masterformat_text, f)); +} + +isc_result_t +dns_master_dumptostream2(isc_mem_t *mctx, dns_db_t *db, + dns_dbversion_t *version, + const dns_master_style_t *style, + dns_masterformat_t format, FILE *f) { dns_dumpctx_t *dctx = NULL; isc_result_t result; - result = dumpctx_create(mctx, db, version, style, f, &dctx); + result = dumpctx_create(mctx, db, version, style, f, &dctx, format); if (result != ISC_R_SUCCESS) return (result); @@ -1265,6 +1481,17 @@ dns_master_dumpinc(isc_mem_t *mctx, dns_db_t *db, dns_dbversion_t *version, const dns_master_style_t *style, const char *filename, isc_task_t *task, dns_dumpdonefunc_t done, void *done_arg, dns_dumpctx_t **dctxp) +{ + return (dns_master_dumpinc2(mctx, db, version, style, filename, task, + done, done_arg, dctxp, + dns_masterformat_text)); +} + +isc_result_t +dns_master_dumpinc2(isc_mem_t *mctx, dns_db_t *db, dns_dbversion_t *version, + const dns_master_style_t *style, const char *filename, + isc_task_t *task, dns_dumpdonefunc_t done, void *done_arg, + dns_dumpctx_t **dctxp, dns_masterformat_t format) { FILE *f = NULL; isc_result_t result; @@ -1280,7 +1507,7 @@ dns_master_dumpinc(isc_mem_t *mctx, dns_db_t *db, dns_dbversion_t *version, if (result != ISC_R_SUCCESS) goto cleanup; - result = dumpctx_create(mctx, db, version, style, f, &dctx); + result = dumpctx_create(mctx, db, version, style, f, &dctx, format); if (result != ISC_R_SUCCESS) { (void)isc_stdio_close(f); (void)isc_file_remove(tempname); @@ -1315,6 +1542,15 @@ dns_master_dumpinc(isc_mem_t *mctx, dns_db_t *db, dns_dbversion_t *version, isc_result_t dns_master_dump(isc_mem_t *mctx, dns_db_t *db, dns_dbversion_t *version, const dns_master_style_t *style, const char *filename) +{ + return (dns_master_dump2(mctx, db, version, style, filename, + dns_masterformat_text)); +} + +isc_result_t +dns_master_dump2(isc_mem_t *mctx, dns_db_t *db, dns_dbversion_t *version, + const dns_master_style_t *style, const char *filename, + dns_masterformat_t format) { FILE *f = NULL; isc_result_t result; @@ -1325,7 +1561,7 @@ dns_master_dump(isc_mem_t *mctx, dns_db_t *db, dns_dbversion_t *version, if (result != ISC_R_SUCCESS) return (result); - result = dumpctx_create(mctx, db, version, style, f, &dctx); + result = dumpctx_create(mctx, db, version, style, f, &dctx, format); if (result != ISC_R_SUCCESS) goto cleanup; @@ -1342,6 +1578,7 @@ dns_master_dump(isc_mem_t *mctx, dns_db_t *db, dns_dbversion_t *version, /* * Dump a database node into a master file. + * XXX: this function assumes the text format. */ isc_result_t dns_master_dumpnodetostream(isc_mem_t *mctx, dns_db_t *db, @@ -1375,7 +1612,7 @@ dns_master_dumpnodetostream(isc_mem_t *mctx, dns_db_t *db, result = dns_db_allrdatasets(db, node, version, now, &rdsiter); if (result != ISC_R_SUCCESS) goto failure; - result = dump_rdatasets(mctx, name, rdsiter, &ctx, &buffer, f); + result = dump_rdatasets_text(mctx, name, rdsiter, &ctx, &buffer, f); if (result != ISC_R_SUCCESS) goto failure; dns_rdatasetiter_destroy(&rdsiter); @@ -1454,4 +1691,3 @@ dns_master_styledestroy(dns_master_style_t **stylep, isc_mem_t *mctx) { *stylep = NULL; isc_mem_put(mctx, style, sizeof(*style)); } - diff --git a/lib/dns/rbtdb.c b/lib/dns/rbtdb.c index e3c3c579f4..a324435341 100644 --- a/lib/dns/rbtdb.c +++ b/lib/dns/rbtdb.c @@ -15,7 +15,7 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: rbtdb.c,v 1.208 2005/06/17 01:00:08 marka Exp $ */ +/* $Id: rbtdb.c,v 1.209 2005/06/20 01:03:53 marka Exp $ */ /*! \file */ @@ -5191,16 +5191,17 @@ endload(dns_db_t *db, dns_dbload_t **dbloadp) { } static isc_result_t -dump(dns_db_t *db, dns_dbversion_t *version, const char *filename) { +dump(dns_db_t *db, dns_dbversion_t *version, const char *filename, + dns_masterformat_t masterformat) { dns_rbtdb_t *rbtdb; rbtdb = (dns_rbtdb_t *)db; REQUIRE(VALID_RBTDB(rbtdb)); - return (dns_master_dump(rbtdb->common.mctx, db, version, - &dns_master_style_default, - filename)); + return (dns_master_dump2(rbtdb->common.mctx, db, version, + &dns_master_style_default, + filename, masterformat)); } static void diff --git a/lib/dns/sdb.c b/lib/dns/sdb.c index e912426704..fd9d1b8b01 100644 --- a/lib/dns/sdb.c +++ b/lib/dns/sdb.c @@ -15,7 +15,7 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: sdb.c,v 1.49 2005/04/29 00:22:51 marka Exp $ */ +/* $Id: sdb.c,v 1.50 2005/06/20 01:03:53 marka Exp $ */ /*! \file */ @@ -601,10 +601,12 @@ endload(dns_db_t *db, dns_dbload_t **dbloadp) { } static isc_result_t -dump(dns_db_t *db, dns_dbversion_t *version, const char *filename) { +dump(dns_db_t *db, dns_dbversion_t *version, const char *filename, + dns_masterformat_t masterformat) { UNUSED(db); UNUSED(version); UNUSED(filename); + UNUSED(masterformat); return (ISC_R_NOTIMPLEMENTED); } diff --git a/lib/dns/zone.c b/lib/dns/zone.c index ece6eb5807..10fd2d5292 100644 --- a/lib/dns/zone.c +++ b/lib/dns/zone.c @@ -15,7 +15,7 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: zone.c,v 1.439 2005/06/10 07:51:54 marka Exp $ */ +/* $Id: zone.c,v 1.440 2005/06/20 01:03:53 marka Exp $ */ /*! \file */ @@ -164,6 +164,7 @@ struct dns_zone { unsigned int irefs; dns_name_t origin; char *masterfile; + dns_masterformat_t masterformat; char *journal; isc_int32_t journalsize; dns_rdataclass_t rdclass; @@ -559,6 +560,7 @@ dns_zone_create(dns_zone_t **zonep, isc_mem_t *mctx) { zone->irefs = 0; dns_name_init(&zone->origin, NULL); zone->masterfile = NULL; + zone->masterformat = dns_masterformat_none; zone->keydirectory = NULL; zone->journalsize = -1; zone->journal = NULL; @@ -936,14 +938,22 @@ dns_zone_setstring(dns_zone_t *zone, char **field, const char *value) { isc_result_t dns_zone_setfile(dns_zone_t *zone, const char *file) { + return (dns_zone_setfile2(zone, file, dns_masterformat_text)); +} + +isc_result_t +dns_zone_setfile2(dns_zone_t *zone, const char *file, + dns_masterformat_t format) { isc_result_t result = ISC_R_SUCCESS; REQUIRE(DNS_ZONE_VALID(zone)); LOCK_ZONE(zone); result = dns_zone_setstring(zone, &zone->masterfile, file); - if (result == ISC_R_SUCCESS) + if (result == ISC_R_SUCCESS) { + zone->masterformat = format; result = default_journal(zone); + } UNLOCK_ZONE(zone); return (result); @@ -1101,8 +1111,8 @@ zone_load(dns_zone_t *zone, unsigned int flags) { if (!DNS_ZONE_FLAG(zone, DNS_ZONEFLG_HASINCLUDE) && isc_time_compare(&filetime, &zone->loadtime) < 0) { dns_zone_log(zone, ISC_LOG_DEBUG(1), - "skipping load: master file older " - "than last load"); + "skipping load: master file " + "older than last load"); result = DNS_R_UPTODATE; goto cleanup; } @@ -1117,9 +1127,10 @@ zone_load(dns_zone_t *zone, unsigned int flags) { strcmp(zone->db_argv[0], "rbt64") == 0)) { if (zone->masterfile == NULL || !isc_file_exists(zone->masterfile)) { - if (zone->masterfile != NULL) + if (zone->masterfile != NULL) { dns_zone_log(zone, ISC_LOG_DEBUG(1), "no master file"); + } zone->refreshtime = now; if (zone->task != NULL) zone_settimer(zone, &now); @@ -1216,14 +1227,15 @@ zone_gotreadhandle(isc_task_t *task, isc_event_t *event) { options |= DNS_MASTER_CHECKMXFAIL; if (DNS_ZONE_OPTION(load->zone, DNS_ZONEOPT_CHECKWILDCARD)) options |= DNS_MASTER_CHECKWILDCARD; - result = dns_master_loadfileinc(load->zone->masterfile, - dns_db_origin(load->db), - dns_db_origin(load->db), - load->zone->rdclass, - options, - &load->callbacks, task, - zone_loaddone, load, - &load->zone->lctx, load->zone->mctx); + result = dns_master_loadfileinc2(load->zone->masterfile, + dns_db_origin(load->db), + dns_db_origin(load->db), + load->zone->rdclass, + options, + &load->callbacks, task, + zone_loaddone, load, + &load->zone->lctx, load->zone->mctx, + load->zone->masterformat); if (result != ISC_R_SUCCESS && result != DNS_R_CONTINUE && result != DNS_R_SEENINCLUDE) goto fail; @@ -1253,10 +1265,10 @@ zone_gotwritehandle(isc_task_t *task, isc_event_t *event) { LOCK_ZONE(zone); ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read); dns_db_currentversion(zone->db, &version); - result = dns_master_dumpinc(zone->mctx, zone->db, version, - &dns_master_style_default, - zone->masterfile, zone->task, - dump_done, zone, &zone->dctx); + result = dns_master_dumpinc2(zone->mctx, zone->db, version, + &dns_master_style_default, + zone->masterfile, zone->task, dump_done, + zone, &zone->dctx, zone->masterformat); dns_db_closeversion(zone->db, &version, ISC_FALSE); ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read); UNLOCK_ZONE(zone); @@ -1333,9 +1345,10 @@ zone_startload(dns_db_t *db, dns_zone_t *zone, isc_time_t loadtime) { &callbacks.add_private); if (result != ISC_R_SUCCESS) return (result); - result = dns_master_loadfile(zone->masterfile, &zone->origin, - &zone->origin, zone->rdclass, - options, &callbacks, zone->mctx); + result = dns_master_loadfile2(zone->masterfile, &zone->origin, + &zone->origin, zone->rdclass, + options, &callbacks, zone->mctx, + zone->masterformat); tresult = dns_db_endload(db, &callbacks.add_private); if (result == ISC_R_SUCCESS) result = tresult; @@ -3013,6 +3026,7 @@ zone_dump(dns_zone_t *zone, isc_boolean_t compact) { isc_boolean_t again; dns_db_t *db = NULL; char *masterfile = NULL; + dns_masterformat_t masterformat = dns_masterformat_none; /* * 'compact' MUST only be set if we are task locked. @@ -3027,8 +3041,10 @@ zone_dump(dns_zone_t *zone, isc_boolean_t compact) { dns_db_attach(zone->db, &db); ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read); LOCK_ZONE(zone); - if (zone->masterfile != NULL) + if (zone->masterfile != NULL) { masterfile = isc_mem_strdup(zone->mctx, zone->masterfile); + masterformat = zone->masterformat; + } UNLOCK_ZONE(zone); if (db == NULL) { result = DNS_R_NOTLOADED; @@ -3053,9 +3069,9 @@ zone_dump(dns_zone_t *zone, isc_boolean_t compact) { UNLOCK_ZONE(zone); } else { dns_db_currentversion(db, &version); - result = dns_master_dump(zone->mctx, db, version, - &dns_master_style_default, - masterfile); + result = dns_master_dump2(zone->mctx, db, version, + &dns_master_style_default, + masterfile, masterformat); dns_db_closeversion(db, &version, ISC_FALSE); } fail: @@ -3093,7 +3109,9 @@ zone_dump(dns_zone_t *zone, isc_boolean_t compact) { } static isc_result_t -dumptostream(dns_zone_t *zone, FILE *fd, const dns_master_style_t *style) { +dumptostream(dns_zone_t *zone, FILE *fd, const dns_master_style_t *style, + dns_masterformat_t format) +{ isc_result_t result; dns_dbversion_t *version = NULL; dns_db_t *db = NULL; @@ -3108,20 +3126,29 @@ dumptostream(dns_zone_t *zone, FILE *fd, const dns_master_style_t *style) { return (DNS_R_NOTLOADED); dns_db_currentversion(db, &version); - result = dns_master_dumptostream(zone->mctx, db, version, style, fd); + result = dns_master_dumptostream2(zone->mctx, db, version, style, + format, fd); dns_db_closeversion(db, &version, ISC_FALSE); dns_db_detach(&db); return (result); } +isc_result_t +dns_zone_dumptostream2(dns_zone_t *zone, FILE *fd, dns_masterformat_t format, + const dns_master_style_t *style) { + return dumptostream(zone, fd, style, format); +} + isc_result_t dns_zone_dumptostream(dns_zone_t *zone, FILE *fd) { - return dumptostream(zone, fd, &dns_master_style_default); + return dumptostream(zone, fd, &dns_master_style_default, + dns_masterformat_text); } isc_result_t dns_zone_fulldumptostream(dns_zone_t *zone, FILE *fd) { - return dumptostream(zone, fd, &dns_master_style_full); + return dumptostream(zone, fd, &dns_master_style_full, + dns_masterformat_text); } void @@ -6043,7 +6070,8 @@ zone_replacedb(dns_zone_t *zone, dns_db_t *db, isc_boolean_t dump) { isc_log_write(dns_lctx, DNS_LOGCATEGORY_GENERAL, DNS_LOGMODULE_ZONE, ISC_LOG_DEBUG(3), "dumping new zone version"); - result = dns_db_dump(db, ver, zone->masterfile); + result = dns_db_dump2(db, ver, zone->masterfile, + zone->masterformat); if (result != ISC_R_SUCCESS) goto fail; diff --git a/lib/isccfg/namedconf.c b/lib/isccfg/namedconf.c index ea4f04cfd8..4f8b78bc66 100644 --- a/lib/isccfg/namedconf.c +++ b/lib/isccfg/namedconf.c @@ -15,7 +15,7 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: namedconf.c,v 1.51 2005/06/07 00:27:34 marka Exp $ */ +/* $Id: namedconf.c,v 1.52 2005/06/20 01:03:55 marka Exp $ */ /*! \file */ @@ -664,6 +664,12 @@ static cfg_type_t cfg_type_mustbesecure = { &cfg_rep_tuple, mustbesecure_fields }; +static const char *masterformat_enums[] = { "text", "raw", NULL }; +static cfg_type_t cfg_type_masterformat = { + "masterformat", cfg_parse_enum, cfg_print_ustring, cfg_doc_enum, + &cfg_rep_string, &masterformat_enums +}; + /* * dnssec-lookaside */ @@ -764,6 +770,7 @@ zone_clauses[] = { { "allow-update", &cfg_type_bracketed_aml, 0 }, { "allow-update-forwarding", &cfg_type_bracketed_aml, 0 }, { "allow-notify", &cfg_type_bracketed_aml, 0 }, + { "masterfile-format", &cfg_type_masterformat, 0 }, { "notify", &cfg_type_notifytype, 0 }, { "notify-source", &cfg_type_sockaddr4wild, 0 }, { "notify-source-v6", &cfg_type_sockaddr6wild, 0 }, diff --git a/make/rules.in b/make/rules.in index 61c8d9ef3a..78ec625c92 100644 --- a/make/rules.in +++ b/make/rules.in @@ -13,7 +13,7 @@ # OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR # PERFORMANCE OF THIS SOFTWARE. -# $Id: rules.in,v 1.51 2005/05/11 05:55:41 sra Exp $ +# $Id: rules.in,v 1.52 2005/06/20 01:03:55 marka Exp $ ### ### Common Makefile rules for BIND 9. @@ -176,6 +176,7 @@ RANLIB = @RANLIB@ INSTALL = @INSTALL@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ +LINK_PROGRAM = @LN_S@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_DATA = @INSTALL_DATA@