+3241. [func] Extended the header of raw-format master files to
+ include the serial number of the zone from which
+ they were generated, if different (as in the case
+ of inline-signing zones). This is to be used in
+ inline-signing zones, to track changes between the
+ unsigned and signed versions of the zone, which may
+ have different serial numbers.
+
+ (Note: raw zonefiles generated by this version of
+ BIND are no longer compatble with prior versions.
+ To generate a backward-compatible raw zonefile
+ using dnssec-signzone or named-compilezone, specify
+ output format "raw=0" instead of simply "raw".)
+ [RT #26587]
+
3241. [bug] Address race conditions in the resolver code.
[RT #26889]
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: check-tool.c,v 1.41 2010/09/07 23:46:59 tbox Exp $ */
+/* $Id: check-tool.c,v 1.42 2011/12/08 16:07:19 each Exp $ */
/*! \file */
/*% dump the zone */
isc_result_t
dump_zone(const char *zonename, dns_zone_t *zone, const char *filename,
- dns_masterformat_t fileformat, const dns_master_style_t *style)
+ dns_masterformat_t fileformat, const dns_master_style_t *style,
+ const isc_uint32_t rawversion)
{
isc_result_t result;
FILE *output = stdout;
}
}
- result = dns_zone_dumptostream2(zone, output, fileformat, style);
+ result = dns_zone_dumptostream3(zone, output, fileformat, style,
+ rawversion);
if (output != stdout)
(void)isc_stdio_close(output);
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: check-tool.h,v 1.16 2010/09/07 23:46:59 tbox Exp $ */
+/* $Id: check-tool.h,v 1.17 2011/12/08 16:07:19 each Exp $ */
#ifndef CHECK_TOOL_H
#define CHECK_TOOL_H
isc_result_t
dump_zone(const char *zonename, dns_zone_t *zone, const char *filename,
- dns_masterformat_t fileformat, const dns_master_style_t *style);
+ dns_masterformat_t fileformat, const dns_master_style_t *style,
+ const isc_uint32_t rawversion);
#ifdef _WIN32
void InitSockets(void);
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: named-checkzone.c,v 1.61 2010/09/07 23:46:59 tbox Exp $ */
+/* $Id: named-checkzone.c,v 1.62 2011/12/08 16:07:19 each Exp $ */
/*! \file */
const char *outputformatstr = NULL;
dns_masterformat_t inputformat = dns_masterformat_text;
dns_masterformat_t outputformat = dns_masterformat_text;
+ isc_uint32_t rawversion = 1;
FILE *errout = stdout;
outputstyle = &dns_master_style_full;
inputformat = dns_masterformat_text;
else if (strcasecmp(inputformatstr, "raw") == 0)
inputformat = dns_masterformat_raw;
- else {
+ else if (strncasecmp(inputformatstr, "raw=", 4) == 0) {
+ inputformat = dns_masterformat_raw;
+ fprintf(stderr,
+ "WARNING: input format raw, version ignored\n");
+ } else {
fprintf(stderr, "unknown file format: %s\n",
inputformatstr);
exit(1);
}
if (outputformatstr != NULL) {
- if (strcasecmp(outputformatstr, "text") == 0)
+ if (strcasecmp(outputformatstr, "text") == 0) {
outputformat = dns_masterformat_text;
- else if (strcasecmp(outputformatstr, "raw") == 0)
+ } else if (strcasecmp(outputformatstr, "raw") == 0) {
+ outputformat = dns_masterformat_raw;
+ } else if (strncasecmp(outputformatstr, "raw=", 4) == 0) {
+ char *end;
+
outputformat = dns_masterformat_raw;
- else {
+ rawversion = strtol(outputformatstr + 4, &end, 10);
+ if (end == outputformatstr + 4 || *end != '\0' ||
+ rawversion > 1U) {
+ fprintf(stderr,
+ "unknown raw format version\n");
+ exit(1);
+ }
+ } else {
fprintf(stderr, "unknown file format: %s\n",
outputformatstr);
exit(1);
fflush(errout);
}
result = dump_zone(origin, zone, output_filename,
- outputformat, outputstyle);
+ outputformat, outputstyle, rawversion);
if (!quiet && progmode == progmode_compile)
fprintf(errout, "done\n");
}
- PERFORMANCE OF THIS SOFTWARE.
-->
-<!-- $Id: named-checkzone.docbook,v 1.40 2010/01/16 23:48:15 tbox Exp $ -->
+<!-- $Id: named-checkzone.docbook,v 1.41 2011/12/08 16:07:20 each Exp $ -->
<refentry id="man.named-checkzone">
<refentryinfo>
<date>June 13, 2000</date>
<listitem>
<para>
Specify the format of the output file specified.
- Possible formats are <command>"text"</command> (default)
- and <command>"raw"</command>.
For <command>named-checkzone</command>,
this does not cause any effects unless it dumps the zone
contents.
</para>
+ <para>
+ Possible formats are <command>"text"</command> (default)
+ and <command>"raw"</command> or <command>"raw=N"</comand>,
+ which store the zone in a binary format for rapid loading
+ by <command>named</command>. <command>"raw=N"</command>
+ specifies the format version of the raw zone file: if N
+ is 0, the raw file can be read by any version of
+ <command>named</command>; if N is 1, the file can be read
+ by release 9.9.0 or higher. The default is 1.
+ </para>
</listitem>
</varlistentry>
* IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: dnssec-signzone.c,v 1.282 2011/11/07 23:46:50 tbox Exp $ */
+/* $Id: dnssec-signzone.c,v 1.283 2011/12/08 16:07:20 each Exp $ */
/*! \file */
static const dns_master_style_t *masterstyle;
static dns_masterformat_t inputformat = dns_masterformat_text;
static dns_masterformat_t outputformat = dns_masterformat_text;
+static unsigned int rawversion = 1;
static unsigned int nsigned = 0, nretained = 0, ndropped = 0;
static unsigned int nverified = 0, nverifyfailed = 0;
static const char *directory = NULL, *dsdir = NULL;
inputformat = dns_masterformat_text;
else if (strcasecmp(inputformatstr, "raw") == 0)
inputformat = dns_masterformat_raw;
- else
- fatal("unknown file format: %s\n", inputformatstr);
+ else if (strncasecmp(inputformatstr, "raw=", 4) == 0) {
+ inputformat = dns_masterformat_raw;
+ fprintf(stderr,
+ "WARNING: input format version ignored\n");
+ } else
+ fatal("unknown file format: %s", inputformatstr);
+
}
if (outputformatstr != NULL) {
- if (strcasecmp(outputformatstr, "text") == 0)
+ if (strcasecmp(outputformatstr, "text") == 0) {
outputformat = dns_masterformat_text;
- else if (strcasecmp(outputformatstr, "raw") == 0)
- outputformat = dns_masterformat_raw;
- else if (strcasecmp(outputformatstr, "full") == 0) {
+ } else if (strcasecmp(outputformatstr, "full") == 0) {
outputformat = dns_masterformat_text;
masterstyle = &dns_master_style_full;
+ } else if (strcasecmp(outputformatstr, "raw") == 0) {
+ outputformat = dns_masterformat_raw;
+ } else if (strncasecmp(outputformatstr, "raw=", 4) == 0) {
+ outputformat = dns_masterformat_raw;
+ char *end;
+
+ outputformat = dns_masterformat_raw;
+ rawversion = strtol(outputformatstr + 4, &end, 10);
+ if (end == outputformatstr + 4 || *end != '\0' ||
+ rawversion > 1U) {
+ fprintf(stderr,
+ "unknown raw format version\n");
+ exit(1);
+ }
} else
fatal("unknown file format: %s\n", outputformatstr);
}
TIME_NOW(&sign_finish);
verifyzone();
- if (outputformat != dns_masterformat_text) {
- result = dns_master_dumptostream2(mctx, gdb, gversion,
+ if (outputformat == dns_masterformat_raw) {
+ dns_masterrawheader_t header;
+ dns_master_initrawheader(&header);
+ if (rawversion == 0U)
+ header.flags = DNS_MASTERRAW_COMPAT;
+ result = dns_master_dumptostream3(mctx, gdb, gversion,
masterstyle, outputformat,
- fp);
- check_result(result, "dns_master_dumptostream2");
+ &header, fp);
+ check_result(result, "dns_master_dumptostream3");
}
DESTROYLOCK(&namelock);
- PERFORMANCE OF THIS SOFTWARE.
-->
-<!-- $Id: dnssec-signzone.docbook,v 1.50 2011/11/07 23:16:31 each Exp $ -->
+<!-- $Id: dnssec-signzone.docbook,v 1.51 2011/12/08 16:07:20 each Exp $ -->
<refentry id="man.dnssec-signzone">
<refentryinfo>
<date>June 05, 2009</date>
<para>
The format of the output file containing the signed zone.
Possible formats are <command>"text"</command> (default)
- <command>"raw"</command>, and <command>"full"</command>,
- which is text output in a format suitable for processing
- by external scripts.
+ <command>"full"</command>, which is text output in a
+ format suitable for processing by external scripts,
+ and <command>"raw"</command> or <command>"raw=N"</command>,
+ which store the zone in a binary format for rapid loading
+ by <command>named</command>. <command>"raw=N"</command>
+ specifies the format version of the raw zone file: if N
+ is 0, the raw file can be read by any version of
+ <command>named</command>; if N is 1, the file can be
+ read by release 9.9.0 or higher. The default is 1.
</para>
</listitem>
</varlistentry>
# OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
# PERFORMANCE OF THIS SOFTWARE.
-# $Id: clean.sh,v 1.45 2011/10/30 23:11:24 each Exp $
+# $Id: clean.sh,v 1.46 2011/12/08 16:07:20 each Exp $
rm -f */K* */keyset-* */dsset-* */dlvset-* */signedkey-* */*.signed
rm -f */trusted.conf */managed.conf */tmp* */*.jnl */*.bk
rm -f */named.secroots
rm -f ns1/managed.key.id
rm -f signer/example.db
-rm -f signer/signer.out.1 signer/signer.out.2
+rm -f signer/signer.out.*
rm -f ns2/algroll.db
rm -f ns3/kskonly.example.db
rm -f ns4/named.conf
# OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
# PERFORMANCE OF THIS SOFTWARE.
-# $Id: tests.sh,v 1.105 2011/11/29 00:49:26 marka Exp $
+# $Id: tests.sh,v 1.106 2011/12/08 16:07:20 each Exp $
SYSTEMTESTTOP=..
. $SYSTEMTESTTOP/conf.sh
return $ret
}
+# check that a zone file is raw format, version 0
+israw0 () {
+ cat $1 | perl -e '$input = <STDIN>;
+ ($style, $version) = unpack("NN", $input);
+ exit 1 if ($style != 2 || $version != 0);'
+ return $?
+}
+
+# check that a zone file is raw format, version 1
+israw1 () {
+ cat $1 | perl -e '$input = <STDIN>;
+ ($style, $version) = unpack("NN", $input);
+ exit 1 if ($style != 2 || $version != 1);'
+ return $?
+}
+
# Check the example. domain
echo "I:checking that zone transfer worked ($n)"
ret=0
(
cd signer
-$SIGNER -O full -f - -Sxt -o example example.db > signer.out.3 2>&1
-$SIGNER -O text -f - -Sxt -o example example.db > signer.out.4 2>&1
+$SIGNER -O full -f - -Sxt -o example example.db > signer.out.3 2> /dev/null
+$SIGNER -O text -f - -Sxt -o example example.db > signer.out.4 2> /dev/null
+$SIGNER -O raw -f signer.out.5 -Sxt -o example example.db > /dev/null 2>&1
+$SIGNER -O raw=0 -f signer.out.6 -Sxt -o example example.db > /dev/null 2>&1
+$SIGNER -O raw -f - -Sxt -o example example.db > signer.out.7 2> /dev/null
) || ret=1
awk '/IN *SOA/ {if (NF != 11) exit(1)}' signer/signer.out.3 || ret=1
awk '/IN *SOA/ {if (NF != 7) exit(1)}' signer/signer.out.4 || ret=1
+israw1 signer/signer.out.5 || ret=1
+israw0 signer/signer.out.6 || ret=1
+israw1 signer/signer.out.7 || ret=1
if [ $ret != 0 ]; then echo "I:failed"; fi
status=`expr $status + $ret`
# OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
# PERFORMANCE OF THIS SOFTWARE.
-# $Id: clean.sh,v 1.8 2011/10/30 22:55:12 each Exp $
+# $Id: clean.sh,v 1.9 2011/12/08 16:07:20 each Exp $
rm -f named-compilezone
-rm -f ns1/example.db.raw
+rm -f ns1/example.db.raw*
+rm -f ns1/example.db.compat
rm -f ns2/example.db
rm -f dig.out.*
rm -f */named.memstats
# OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
# PERFORMANCE OF THIS SOFTWARE.
-# $Id: compile.sh,v 1.6 2007/06/19 23:47:04 tbox Exp $
+# $Id: compile.sh,v 1.7 2011/12/08 16:07:20 each Exp $
-../named-compilezone -D -F raw -o example.db.raw example example.db
+../named-compilezone -D -F raw -o example.db.raw example \
+ example.db > /dev/null 2>&1
+../named-compilezone -D -F raw=1 -o example.db.raw1 example-explicit \
+ example.db > /dev/null 2>&1
+../named-compilezone -D -F raw=0 -o example.db.compat example-compat \
+ example.db > /dev/null 2>&1
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: named.conf,v 1.6 2011/10/26 23:46:15 tbox Exp $ */
+/* $Id: named.conf,v 1.7 2011/12/08 16:07:20 each Exp $ */
// NS1
file "example.db.raw";
};
+zone "compat-example" {
+ type master;
+ masterfile-format raw;
+ file "example.db.compat";
+};
+
zone "transfer1" {
type master;
file "example.db";
# OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
# PERFORMANCE OF THIS SOFTWARE.
-# $Id: setup.sh,v 1.8 2011/10/26 23:46:14 tbox Exp $
+# $Id: setup.sh,v 1.9 2011/12/08 16:07:20 each Exp $
+rm -f named-compilezone
ln -s $CHECKZONE named-compilezone
rm -f ns1/example.db.raw
cp ns1/example.db ns2/
# OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
# PERFORMANCE OF THIS SOFTWARE.
-# $Id: tests.sh,v 1.7 2011/12/02 04:14:33 marka Exp $
+# $Id: tests.sh,v 1.8 2011/12/08 16:07:20 each Exp $
SYSTEMTESTTOP=..
. $SYSTEMTESTTOP/conf.sh
israw () {
- cat $1 | perl -e '$input = <STDIN>;
- ($style, $version) = unpack("NN", $input);
- exit 1 if ($style != 2 || $version != 0);'
+ perl -e '$input = <STDIN>;
+ ($style, $version) = unpack("NN", $input);
+ exit 1 if ($style != 2 || $version > 1);' < $1
return $?
}
+rawversion () {
+ perl -e '$input = <STDIN>;
+ if (length($input) < 2) { print "not raw\n"; exit 0; };
+ ($style, $version) = unpack("NN", $input);
+ print ($style == 2 ? "$version\n" : "not raw\n");' < $1
+}
+
DIGOPTS="+tcp +noauth +noadd +nosea +nostat +noquest +nocomm +nocmd"
status=0
-echo "I:checking that master file in the raw format worked"
+echo "I:checking that master files in raw format loaded"
ret=0
-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
+for zone in example example-explicit example-compat; do
+ for server in 1 2; do
+ for name in ns mx a aaaa cname dname txt rrsig nsec dnskey ds; do
+ $DIG $DIGOPTS $name.$zone. $name @10.53.0.$server -p 5300
echo
- done > dig.out.$server
+ done > dig.out.$zone.$server
+ done
+ $PERL ../digcomp.pl dig.out.$zone.1 dig.out.$zone.2 || ret=1
done
-$PERL ../digcomp.pl dig.out.1 dig.out.2 || ret=1
+[ $ret -eq 0 ] || echo "I:failed"
+status=`expr $status + $ret`
+
+echo "I:checking raw format versions"
+ret=0
+israw ns1/example.db.raw || ret=1
+israw ns1/example.db.raw1 || ret=1
+israw ns1/example.db.compat || ret=1
+[ "`rawversion ns1/example.db.raw`" = 1 ] || ret=1
+[ "`rawversion ns1/example.db.raw1`" = 1 ] || ret=1
+[ "`rawversion ns1/example.db.compat`" = 0 ] || ret=1
[ $ret -eq 0 ] || echo "I:failed"
status=`expr $status + $ret`
do
ret=0
israw ns2/formerly-text.db > /dev/null 2>&1 || ret=1
+ [ "`rawversion ns2/formerly-text.db`" = 1 ] || ret=1
[ $ret -eq 0 ] && break
sleep 1
done
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: callbacks.c,v 1.17 2007/06/19 23:47:16 tbox Exp $ */
+/* $Id: callbacks.c,v 1.18 2011/12/08 16:07:20 each Exp $ */
/*! \file */
REQUIRE(callbacks != NULL);
callbacks->add = NULL;
+ callbacks->rawdata = NULL;
+ callbacks->zone = NULL;
callbacks->add_private = NULL;
callbacks->error_private = NULL;
callbacks->warn_private = NULL;
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: callbacks.h,v 1.24 2007/06/19 23:47:16 tbox Exp $ */
+/* $Id: callbacks.h,v 1.25 2011/12/08 16:07:21 each Exp $ */
#ifndef DNS_CALLBACKS_H
#define DNS_CALLBACKS_H 1
* dns_load_master calls this when it has rdatasets to commit.
*/
dns_addrdatasetfunc_t add;
+
+ /*%
+ * dns_master_load*() call this when loading a raw zonefile,
+ * to pass back information obtained from the file header
+ */
+ dns_rawdatafunc_t rawdata;
+ dns_zone_t *zone;
+
/*%
* dns_load_master / dns_rdata_fromtext call this to issue a error.
*/
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: master.h,v 1.53 2009/07/01 23:47:36 tbox Exp $ */
+/* $Id: master.h,v 1.54 2011/12/08 16:07:21 each Exp $ */
#ifndef DNS_MASTER_H
#define DNS_MASTER_H 1
* 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
+#define DNS_RAWFORMAT_VERSION 1
+
+/*
+ * Flags to indicate the status of the data in the raw file header
+ */
+#define DNS_MASTERRAW_COMPAT 0x01
+#define DNS_MASTERRAW_SOURCESERIALSET 0x02
+#define DNS_MASTERRAW_LASTXFRINSET 0x04
/* Common header */
-typedef struct {
+struct dns_masterrawheader {
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;
+ * (currently unused) */
+ isc_uint32_t flags; /* Flags */
+ isc_uint32_t sourceserial; /* Source serial number (used
+ * by inline-signing zones) */
+ isc_uint32_t lastxfrin; /* timestamp of last transfer
+ * (used by slave zones) */
+};
/* The structure for each RRset */
typedef struct {
*\li 'ctx' to be valid
*/
+void
+dns_master_initrawheader(dns_masterrawheader_t *header);
+/*%<
+ * Initializes the header for a raw master file, setting all
+ * values to zero.
+ */
ISC_LANG_ENDDECLS
#endif /* DNS_MASTER_H */
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: masterdump.h,v 1.45 2011/05/26 07:56:39 marka Exp $ */
+/* $Id: masterdump.h,v 1.46 2011/12/08 16:07:21 each Exp $ */
#ifndef DNS_MASTERDUMP_H
#define DNS_MASTERDUMP_H 1
dns_dbversion_t *version,
const dns_master_style_t *style,
dns_masterformat_t format, FILE *f);
+
+isc_result_t
+dns_master_dumptostream3(isc_mem_t *mctx, dns_db_t *db,
+ dns_dbversion_t *version,
+ const dns_master_style_t *style,
+ dns_masterformat_t format,
+ dns_masterrawheader_t *header, FILE *f);
/*%<
* 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.
+ * dns_master_dumptostream() is an old form of dns_master_dumptostream3(),
+ * which always specifies the dns_masterformat_text format.
+ * dns_master_dumptostream2() is an old form which always specifies
+ * a NULL header.
+ *
+ * If 'format' is dns_masterformat_raw, then 'header' can contain
+ * information to be written to the file header.
*
* Temporary dynamic memory may be allocated from 'mctx'.
*
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_dumpinc3(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, dns_masterrawheader_t *header);
+
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,
dns_masterformat_t format);
+isc_result_t
+dns_master_dump3(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, dns_masterrawheader_t *header);
+
/*%<
* 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.
+ * dns_master_dumpinc() and dns_master_dump() are old forms of _dumpinc3()
+ * and _dump3(), respectively, which always specify the dns_masterformat_text
+ * format. dns_master_dumpinc2() and dns_master_dump2() are old forms which
+ * always specify a NULL header.
+ *
+ * If 'format' is dns_masterformat_raw, then 'header' can contain
+ * information to be written to the file header.
*
* Temporary dynamic memory may be allocated from 'mctx'.
*
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: types.h,v 1.145 2011/07/01 23:47:44 tbox Exp $ */
+/* $Id: types.h,v 1.146 2011/12/08 16:07:21 each Exp $ */
#ifndef DNS_TYPES_H
#define DNS_TYPES_H 1
typedef isc_uint16_t dns_keytag_t;
typedef struct dns_loadctx dns_loadctx_t;
typedef struct dns_loadmgr dns_loadmgr_t;
+typedef struct dns_masterrawheader dns_masterrawheader_t;
typedef struct dns_message dns_message_t;
typedef isc_uint16_t dns_messageid_t;
typedef isc_region_t dns_label_t;
typedef void
(*dns_loaddonefunc_t)(void *, isc_result_t);
+typedef void
+(*dns_rawdatafunc_t)(dns_zone_t *, dns_masterrawheader_t *);
+
typedef isc_result_t
(*dns_addrdatasetfunc_t)(void *, dns_name_t *, dns_rdataset_t *);
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: zone.h,v 1.197 2011/11/04 05:51:01 each Exp $ */
+/* $Id: zone.h,v 1.198 2011/12/08 16:07:21 each Exp $ */
#ifndef DNS_ZONE_H
#define DNS_ZONE_H 1
isc_result_t
dns_zone_dumptostream2(dns_zone_t *zone, FILE *fd, dns_masterformat_t format,
const dns_master_style_t *style);
+isc_result_t
+dns_zone_dumptostream3(dns_zone_t *zone, FILE *fd, dns_masterformat_t format,
+ const dns_master_style_t *style,
+ const isc_uint32_t rawversion);
/*%<
* Write the zone to stream 'fd' in the specified 'format'.
* If the 'format' is dns_masterformat_text (RFC1035), 'style' also
* 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
+ * dns_zone_dumptostream2() is a backward-compatible form of
+ * dns_zone_dumptostream3(), which always uses the current
+ * default raw file format version.
+ *
+ * Note that dns_zone_dumptostream3() is the most flexible form. It
* can also provide the functionality of dns_zone_fulldumptostream().
*
* Require:
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: master.c,v 1.180 2011/03/12 04:59:48 tbox Exp $ */
+/* $Id: master.c,v 1.181 2011/12/08 16:07:20 each Exp $ */
/*! \file */
/* Members specific to the raw format: */
FILE *f;
isc_boolean_t first;
+ dns_masterrawheader_t header;
/* Which fixed buffers we are using? */
unsigned int loop_cnt; /*% records per quantum,
lctx->f = NULL;
lctx->first = ISC_TRUE;
+ dns_master_initrawheader(&lctx->header);
lctx->loop_cnt = (done != NULL) ? 100 : 0;
lctx->callbacks = callbacks;
int target_size = TSIZ;
isc_buffer_t target;
unsigned char *target_mem = NULL;
+ dns_masterrawheader_t header;
REQUIRE(DNS_LCTX_VALID(lctx));
callbacks = lctx->callbacks;
+ dns_master_initrawheader(&header);
+
if (lctx->first) {
- dns_masterrawheader_t header;
- isc_uint32_t format, version, dumptime;
- size_t hdrlen = sizeof(format) + sizeof(version) +
- sizeof(dumptime);
+ unsigned char data[sizeof(header)];
+ size_t commonlen =
+ sizeof(header.format) + sizeof(header.version);
+ size_t remainder;
- INSIST(hdrlen <= sizeof(header));
- isc_buffer_init(&target, &header, sizeof(header));
+ INSIST(commonlen <= sizeof(header));
+ isc_buffer_init(&target, data, sizeof(data));
- result = isc_stdio_read(&header, 1, hdrlen, lctx->f, NULL);
+ result = isc_stdio_read(data, 1, commonlen, 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) {
+ isc_buffer_add(&target, commonlen);
+ header.format = isc_buffer_getuint32(&target);
+ if (header.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) {
+ header.version = isc_buffer_getuint32(&target);
+ switch (header.version) {
+ case 0:
+ remainder = sizeof(header.dumptime);
+ break;
+ case DNS_RAWFORMAT_VERSION:
+ remainder = sizeof(header) - commonlen;
+ break;
+ default:
(*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);
- POST(dumptime);
+ result = isc_stdio_read(data + commonlen, 1, remainder,
+ 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, remainder);
+ header.dumptime = isc_buffer_getuint32(&target);
+ if (header.version == DNS_RAWFORMAT_VERSION) {
+ header.flags = isc_buffer_getuint32(&target);
+ header.sourceserial = isc_buffer_getuint32(&target);
+ header.lastxfrin = isc_buffer_getuint32(&target);
+ }
lctx->first = ISC_FALSE;
+ lctx->header = header;
}
ISC_LIST_INIT(head);
} else if (result == ISC_R_SUCCESS && lctx->result != ISC_R_SUCCESS)
result = lctx->result;
+ if (result == ISC_R_SUCCESS && callbacks->rawdata != NULL)
+ (*callbacks->rawdata)(callbacks->zone, &header);
+
cleanup:
if (rdata != NULL)
isc_mem_put(mctx, rdata, rdata_size * sizeof(*rdata));
lctx->canceled = ISC_TRUE;
UNLOCK(&lctx->lock);
}
+
+void
+dns_master_initrawheader(dns_masterrawheader_t *header) {
+ memset(header, 0, sizeof(dns_masterrawheader_t));
+}
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: masterdump.c,v 1.110 2011/11/07 23:16:31 each Exp $ */
+/* $Id: masterdump.c,v 1.111 2011/12/08 16:07:21 each Exp $ */
/*! \file */
char *file;
char *tmpfile;
dns_masterformat_t format;
+ dns_masterrawheader_t header;
isc_result_t (*dumpsets)(isc_mem_t *mctx, dns_name_t *name,
dns_rdatasetiter_t *rdsiter,
dns_totext_ctx_t *ctx,
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,
- dns_masterformat_t format)
+ dns_masterformat_t format, dns_masterrawheader_t *header)
{
dns_dumpctx_t *dctx;
isc_result_t result;
dctx->file = NULL;
dctx->tmpfile = NULL;
dctx->format = format;
+ if (header == NULL)
+ dns_master_initrawheader(&dctx->header);
+ else
+ dctx->header = *header;
switch (format) {
case dns_masterformat_text:
dns_fixedname_t fixname;
unsigned int nodes;
dns_masterrawheader_t rawheader;
- isc_uint32_t now32;
+ isc_uint32_t rawversion, now32;
isc_time_t start;
bufmem = isc_mem_get(dctx->mctx, initial_buffer_length);
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 !defined(STDTIME_ON_32BITS) || (STDTIME_ON_32BITS + 0) != 1
/*
* We assume isc_stdtime_t is a 32-bit integer,
#else
now32 = dctx->now;
#endif
+ rawversion = 1;
+ if ((dctx->header.flags & DNS_MASTERRAW_COMPAT) != 0)
+ rawversion = 0;
+ isc_buffer_putuint32(&buffer, dns_masterformat_raw);
+ isc_buffer_putuint32(&buffer, rawversion);
isc_buffer_putuint32(&buffer, now32);
+
+ if (rawversion == 1) {
+ isc_buffer_putuint32(&buffer,
+ dctx->header.flags);
+ isc_buffer_putuint32(&buffer,
+ dctx->header.sourceserial);
+ isc_buffer_putuint32(&buffer,
+ dctx->header.lastxfrin);
+ }
+
INSIST(isc_buffer_usedlength(&buffer) <=
sizeof(rawheader));
result = isc_stdio_write(buffer.base, 1,
REQUIRE(done != NULL);
result = dumpctx_create(mctx, db, version, style, f, &dctx,
- dns_masterformat_text);
+ dns_masterformat_text, NULL);
if (result != ISC_R_SUCCESS)
return (result);
isc_task_attach(task, &dctx->task);
const dns_master_style_t *style,
FILE *f)
{
- return (dns_master_dumptostream2(mctx, db, version, style,
- dns_masterformat_text, f));
+ return (dns_master_dumptostream3(mctx, db, version, style,
+ dns_masterformat_text, NULL, f));
}
isc_result_t
dns_dbversion_t *version,
const dns_master_style_t *style,
dns_masterformat_t format, FILE *f)
+{
+ return (dns_master_dumptostream3(mctx, db, version, style,
+ format, NULL, f));
+}
+
+isc_result_t
+dns_master_dumptostream3(isc_mem_t *mctx, dns_db_t *db,
+ dns_dbversion_t *version,
+ const dns_master_style_t *style,
+ dns_masterformat_t format,
+ dns_masterrawheader_t *header, FILE *f)
{
dns_dumpctx_t *dctx = NULL;
isc_result_t result;
- result = dumpctx_create(mctx, db, version, style, f, &dctx, format);
+ result = dumpctx_create(mctx, db, version, style, f, &dctx,
+ format, header);
if (result != ISC_R_SUCCESS)
return (result);
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,
+ return (dns_master_dumpinc3(mctx, db, version, style, filename, task,
done, done_arg, dctxp,
- dns_masterformat_text));
+ dns_masterformat_text, NULL));
}
isc_result_t
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)
+{
+ return (dns_master_dumpinc3(mctx, db, version, style, filename, task,
+ done, done_arg, dctxp, format, NULL));
+}
+
+isc_result_t
+dns_master_dumpinc3(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,
+ dns_masterrawheader_t *header)
{
FILE *f = NULL;
isc_result_t result;
if (result != ISC_R_SUCCESS)
goto cleanup;
- result = dumpctx_create(mctx, db, version, style, f, &dctx, format);
+ result = dumpctx_create(mctx, db, version, style, f, &dctx,
+ format, header);
if (result != ISC_R_SUCCESS) {
(void)isc_stdio_close(f);
(void)isc_file_remove(tempname);
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));
+ return (dns_master_dump3(mctx, db, version, style, filename,
+ dns_masterformat_text, NULL));
}
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)
+{
+ return (dns_master_dump3(mctx, db, version, style, filename,
+ format, NULL));
+}
+
+isc_result_t
+dns_master_dump3(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, dns_masterrawheader_t *header)
{
FILE *f = NULL;
isc_result_t result;
if (result != ISC_R_SUCCESS)
return (result);
- result = dumpctx_create(mctx, db, version, style, f, &dctx, format);
+ result = dumpctx_create(mctx, db, version, style, f, &dctx,
+ format, header);
if (result != ISC_R_SUCCESS)
goto cleanup;
# OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
# PERFORMANCE OF THIS SOFTWARE.
-# $Id: Makefile.in,v 1.11 2011/12/04 23:48:12 marka Exp $
+# $Id: Makefile.in,v 1.12 2011/12/08 16:07:21 each Exp $
srcdir = @srcdir@
VPATH = @srcdir@
@BIND9_MAKE_RULES@
master_test@EXEEXT@: master_test.@O@ dnstest.@O@ ${ISCDEPLIBS} ${DNSDEPLIBS}
+ ${PERL} mkraw.pl < testdata/master/master12.data.in \
+ > testdata/master/master12.data
+ ${PERL} mkraw.pl < testdata/master/master13.data.in \
+ > testdata/master/master13.data
+ ${PERL} mkraw.pl < testdata/master/master14.data.in \
+ > testdata/master/master14.data
${LIBTOOL_MODE_LINK} ${PURIFY} ${CC} ${CFLAGS} ${LDFLAGS} -o $@ \
master_test.@O@ dnstest.@O@ ${DNSLIBS} \
${ISCLIBS} ${LIBS}
clean distclean::
rm -f ${TARGETS}
rm -f atf.out
+ rm -f testdata/master/master12.data testdata/master/master13.data \
+ testdata/master/master14.data
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: master_test.c,v 1.6 2011/09/07 19:11:14 each Exp $ */
+/* $Id: master_test.c,v 1.7 2011/12/08 16:07:22 each Exp $ */
/*! \file */
#include <dns/cache.h>
#include <dns/callbacks.h>
+#include <dns/db.h>
#include <dns/master.h>
#include <dns/masterdump.h>
#include <dns/name.h>
#define BIGBUFLEN (64 * 1024)
#define TEST_ORIGIN "test"
+static dns_masterrawheader_t header;
+static isc_boolean_t headerset;
+
static isc_result_t
add_callback(void *arg, dns_name_t *owner, dns_rdataset_t *dataset);
+static void
+rawdata_callback(dns_zone_t *zone, dns_masterrawheader_t *header);
+
static isc_result_t
add_callback(void *arg, dns_name_t *owner, dns_rdataset_t *dataset) {
char buf[BIGBUFLEN];
return(result);
}
+static void
+rawdata_callback(dns_zone_t *zone, dns_masterrawheader_t *h) {
+ UNUSED(zone);
+ header = *h;
+ headerset = ISC_TRUE;
+}
+
static int
-test_master(const char *testfile) {
+test_master(const char *testfile, dns_masterformat_t format) {
isc_result_t result;
int len;
char origin[sizeof(TEST_ORIGIN)];
isc_buffer_setactive(&source, len);
isc_buffer_init(&target, name_buf, BUFLEN);
dns_name_init(&dns_origin, NULL);
+ dns_master_initrawheader(&header);
result = dns_name_fromtext(&dns_origin, &source, dns_rootname,
0, &target);
dns_rdatacallbacks_init_stdio(&callbacks);
callbacks.add = add_callback;
-
- result = dns_master_loadfile(testfile, &dns_origin, &dns_origin,
- dns_rdataclass_in, ISC_TRUE,
- &callbacks, mctx);
+ callbacks.rawdata = rawdata_callback;
+ callbacks.zone = NULL;
+ headerset = ISC_FALSE;
+ result = dns_master_loadfile2(testfile, &dns_origin, &dns_origin,
+ dns_rdataclass_in, ISC_TRUE,
+ &callbacks, mctx, format);
return (result);
}
*/
/* Successful load test */
-ATF_TC(master_load);
-ATF_TC_HEAD(master_load, tc) {
+ATF_TC(load);
+ATF_TC_HEAD(load, tc) {
atf_tc_set_md_var(tc, "descr", "dns_master_loadfile() loads a "
"valid master file and returns success");
}
-ATF_TC_BODY(master_load, tc) {
+ATF_TC_BODY(load, tc) {
isc_result_t result;
UNUSED(tc);
result = dns_test_begin(NULL, ISC_FALSE);
ATF_REQUIRE_EQ(result, ISC_R_SUCCESS);
- result = test_master("testdata/master/master1.data");
+ result = test_master("testdata/master/master1.data",
+ dns_masterformat_text);
ATF_REQUIRE_EQ(result, ISC_R_SUCCESS);
dns_test_end();
/* Unepxected end of file test */
-ATF_TC(master_unexpected);
-ATF_TC_HEAD(master_unexpected, tc) {
+ATF_TC(unexpected);
+ATF_TC_HEAD(unexpected, tc) {
atf_tc_set_md_var(tc, "descr", "dns_master_loadfile() returns "
"DNS_R_UNEXPECTED when file ends "
"too soon");
}
-ATF_TC_BODY(master_unexpected, tc) {
+ATF_TC_BODY(unexpected, tc) {
isc_result_t result;
UNUSED(tc);
result = dns_test_begin(NULL, ISC_FALSE);
ATF_REQUIRE_EQ(result, ISC_R_SUCCESS);
- result = test_master("testdata/master/master2.data");
+ result = test_master("testdata/master/master2.data",
+ dns_masterformat_text);
ATF_REQUIRE_EQ(result, ISC_R_UNEXPECTEDEND);
dns_test_end();
/* No owner test */
-ATF_TC(master_noowner);
-ATF_TC_HEAD(master_noowner, tc) {
+ATF_TC(noowner);
+ATF_TC_HEAD(noowner, tc) {
atf_tc_set_md_var(tc, "descr", "dns_master_loadfile() accepts broken "
"zones with no TTL for first record "
"if it is an SOA");
}
-ATF_TC_BODY(master_noowner, tc) {
+ATF_TC_BODY(noowner, tc) {
isc_result_t result;
UNUSED(tc);
result = dns_test_begin(NULL, ISC_FALSE);
ATF_REQUIRE_EQ(result, ISC_R_SUCCESS);
- result = test_master("testdata/master/master3.data");
+ result = test_master("testdata/master/master3.data",
+ dns_masterformat_text);
ATF_REQUIRE_EQ(result, DNS_R_NOOWNER);
dns_test_end();
/* No TTL test */
-ATF_TC(master_nottl);
-ATF_TC_HEAD(master_nottl, tc) {
+ATF_TC(nottl);
+ATF_TC_HEAD(nottl, tc) {
atf_tc_set_md_var(tc, "descr", "dns_master_loadfile() returns "
"DNS_R_NOOWNER when no owner name "
"is specified");
}
-ATF_TC_BODY(master_nottl, tc) {
+ATF_TC_BODY(nottl, tc) {
isc_result_t result;
UNUSED(tc);
result = dns_test_begin(NULL, ISC_FALSE);
ATF_REQUIRE_EQ(result, ISC_R_SUCCESS);
- result = test_master("testdata/master/master4.data");
+ result = test_master("testdata/master/master4.data",
+ dns_masterformat_text);
ATF_REQUIRE_EQ(result, ISC_R_SUCCESS);
dns_test_end();
/* Bad class test */
-ATF_TC(master_badclass);
-ATF_TC_HEAD(master_badclass, tc) {
+ATF_TC(badclass);
+ATF_TC_HEAD(badclass, tc) {
atf_tc_set_md_var(tc, "descr", "dns_master_loadfile() returns "
"DNS_R_BADCLASS when record class "
"doesn't match zone class");
}
-ATF_TC_BODY(master_badclass, tc) {
+ATF_TC_BODY(badclass, tc) {
isc_result_t result;
UNUSED(tc);
result = dns_test_begin(NULL, ISC_FALSE);
ATF_REQUIRE_EQ(result, ISC_R_SUCCESS);
- result = test_master("testdata/master/master5.data");
+ result = test_master("testdata/master/master5.data",
+ dns_masterformat_text);
ATF_REQUIRE_EQ(result, DNS_R_BADCLASS);
dns_test_end();
}
/* DNSKEY test */
-ATF_TC(master_dnskey);
-ATF_TC_HEAD(master_dnskey, tc) {
+ATF_TC(dnskey);
+ATF_TC_HEAD(dnskey, tc) {
atf_tc_set_md_var(tc, "descr", "dns_master_loadfile() understands "
"DNSKEY with key material");
}
-ATF_TC_BODY(master_dnskey, tc) {
+ATF_TC_BODY(dnskey, tc) {
isc_result_t result;
UNUSED(tc);
result = dns_test_begin(NULL, ISC_FALSE);
ATF_REQUIRE_EQ(result, ISC_R_SUCCESS);
- result = test_master("testdata/master/master6.data");
+ result = test_master("testdata/master/master6.data",
+ dns_masterformat_text);
ATF_REQUIRE_EQ(result, ISC_R_SUCCESS);
dns_test_end();
/* DNSKEY with no key material test */
-ATF_TC(master_dnsnokey);
-ATF_TC_HEAD(master_dnsnokey, tc) {
+ATF_TC(dnsnokey);
+ATF_TC_HEAD(dnsnokey, tc) {
atf_tc_set_md_var(tc, "descr", "dns_master_loadfile() understands "
"DNSKEY with no key material");
}
-ATF_TC_BODY(master_dnsnokey, tc) {
+ATF_TC_BODY(dnsnokey, tc) {
isc_result_t result;
UNUSED(tc);
result = dns_test_begin(NULL, ISC_FALSE);
ATF_REQUIRE_EQ(result, ISC_R_SUCCESS);
- result = test_master("testdata/master/master7.data");
+ result = test_master("testdata/master/master7.data",
+ dns_masterformat_text);
ATF_REQUIRE_EQ(result, ISC_R_SUCCESS);
dns_test_end();
}
/* Include test */
-ATF_TC(master_include);
-ATF_TC_HEAD(master_include, tc) {
+ATF_TC(include);
+ATF_TC_HEAD(include, tc) {
atf_tc_set_md_var(tc, "descr", "dns_master_loadfile() understands "
"$INCLUDE");
}
-ATF_TC_BODY(master_include, tc) {
+ATF_TC_BODY(include, tc) {
isc_result_t result;
UNUSED(tc);
result = dns_test_begin(NULL, ISC_FALSE);
ATF_REQUIRE_EQ(result, ISC_R_SUCCESS);
- result = test_master("testdata/master/master8.data");
+ result = test_master("testdata/master/master8.data",
+ dns_masterformat_text);
ATF_REQUIRE_EQ(result, DNS_R_SEENINCLUDE);
dns_test_end();
}
/* Include failure test */
-ATF_TC(master_includefail);
-ATF_TC_HEAD(master_includefail, tc) {
+ATF_TC(includefail);
+ATF_TC_HEAD(includefail, tc) {
atf_tc_set_md_var(tc, "descr", "dns_master_loadfile() understands "
"$INCLUDE failures");
}
-ATF_TC_BODY(master_includefail, tc) {
+ATF_TC_BODY(includefail, tc) {
isc_result_t result;
UNUSED(tc);
result = dns_test_begin(NULL, ISC_FALSE);
ATF_REQUIRE_EQ(result, ISC_R_SUCCESS);
- result = test_master("testdata/master/master9.data");
+ result = test_master("testdata/master/master9.data",
+ dns_masterformat_text);
ATF_REQUIRE_EQ(result, DNS_R_BADCLASS);
dns_test_end();
/* Non-empty blank lines test */
-ATF_TC(master_blanklines);
-ATF_TC_HEAD(master_blanklines, tc) {
+ATF_TC(blanklines);
+ATF_TC_HEAD(blanklines, tc) {
atf_tc_set_md_var(tc, "descr", "dns_master_loadfile() handles "
"non-empty blank lines");
}
-ATF_TC_BODY(master_blanklines, tc) {
+ATF_TC_BODY(blanklines, tc) {
isc_result_t result;
UNUSED(tc);
result = dns_test_begin(NULL, ISC_FALSE);
ATF_REQUIRE_EQ(result, ISC_R_SUCCESS);
- result = test_master("testdata/master/master10.data");
+ result = test_master("testdata/master/master10.data",
+ dns_masterformat_text);
ATF_REQUIRE_EQ(result, ISC_R_SUCCESS);
dns_test_end();
}
/* SOA leading zeroes test */
-ATF_TC(master_leadingzero);
-ATF_TC_HEAD(master_leadingzero, tc) {
+ATF_TC(leadingzero);
+ATF_TC_HEAD(leadingzero, tc) {
atf_tc_set_md_var(tc, "descr", "dns_master_loadfile() allows "
"leading zeroes in SOA");
}
-ATF_TC_BODY(master_leadingzero, tc) {
+ATF_TC_BODY(leadingzero, tc) {
isc_result_t result;
UNUSED(tc);
result = dns_test_begin(NULL, ISC_FALSE);
ATF_REQUIRE_EQ(result, ISC_R_SUCCESS);
- result = test_master("testdata/master/master11.data");
+ result = test_master("testdata/master/master11.data",
+ dns_masterformat_text);
ATF_REQUIRE_EQ(result, ISC_R_SUCCESS);
dns_test_end();
}
-ATF_TC(master_totext);
-ATF_TC_HEAD(master_totext, tc) {
+ATF_TC(totext);
+ATF_TC_HEAD(totext, tc) {
atf_tc_set_md_var(tc, "descr", "masterfile totext tests");
}
-ATF_TC_BODY(master_totext, tc) {
+ATF_TC_BODY(totext, tc) {
isc_result_t result;
dns_rdataset_t rdataset;
dns_rdatalist_t rdatalist;
dns_test_end();
}
+/* Raw load */
+ATF_TC(loadraw);
+ATF_TC_HEAD(loadraw, tc) {
+ atf_tc_set_md_var(tc, "descr", "dns_master_loadfile() loads a "
+ "valid raw file and returns success");
+}
+ATF_TC_BODY(loadraw, tc) {
+ isc_result_t result;
+
+ UNUSED(tc);
+
+ result = dns_test_begin(NULL, ISC_FALSE);
+ ATF_REQUIRE_EQ(result, ISC_R_SUCCESS);
+
+ /* Raw format version 0 */
+ result = test_master("testdata/master/master12.data",
+ dns_masterformat_raw);
+ ATF_CHECK_STREQ(isc_result_totext(result), "success");
+ ATF_CHECK(headerset);
+ ATF_CHECK_EQ(header.flags, 0);
+
+ /* Raw format version 1, no source serial */
+ result = test_master("testdata/master/master13.data",
+ dns_masterformat_raw);
+ ATF_CHECK_STREQ(isc_result_totext(result), "success");
+ ATF_CHECK(headerset);
+ ATF_CHECK_EQ(header.flags, 0);
+
+ /* Raw format version 1, source serial == 2011120101 */
+ result = test_master("testdata/master/master14.data",
+ dns_masterformat_raw);
+ ATF_CHECK_STREQ(isc_result_totext(result), "success");
+ ATF_CHECK(headerset);
+ ATF_CHECK((header.flags & DNS_MASTERRAW_SOURCESERIALSET) != 0);
+ ATF_CHECK_EQ(header.sourceserial, 2011120101);
+
+ dns_test_end();
+}
+
+/* Raw dump*/
+ATF_TC(dumpraw);
+ATF_TC_HEAD(dumpraw, tc) {
+ atf_tc_set_md_var(tc, "descr", "dns_master_dump*() functions "
+ "dump valid raw files");
+}
+ATF_TC_BODY(dumpraw, tc) {
+ isc_result_t result;
+ dns_db_t *db = NULL;
+ dns_dbversion_t *version = NULL;
+ char origin[sizeof(TEST_ORIGIN)];
+ dns_name_t dns_origin;
+ isc_buffer_t source, target;
+ unsigned char name_buf[BUFLEN];
+ int len;
+
+ UNUSED(tc);
+
+ strcpy(origin, TEST_ORIGIN);
+ len = strlen(origin);
+ isc_buffer_init(&source, origin, len);
+ isc_buffer_add(&source, len);
+ isc_buffer_setactive(&source, len);
+ isc_buffer_init(&target, name_buf, BUFLEN);
+ dns_name_init(&dns_origin, NULL);
+ result = dns_name_fromtext(&dns_origin, &source, dns_rootname,
+ 0, &target);
+ ATF_REQUIRE_EQ(result, ISC_R_SUCCESS);
+
+ result = dns_test_begin(NULL, ISC_FALSE);
+ ATF_REQUIRE_EQ(result, ISC_R_SUCCESS);
+
+ result = dns_db_create(mctx, "rbt", &dns_origin, dns_dbtype_zone,
+ dns_rdataclass_in, 0, NULL, &db);
+ ATF_REQUIRE_EQ(result, ISC_R_SUCCESS);
+
+ result = dns_db_load(db, "testdata/master/master1.data");
+ ATF_REQUIRE_EQ(result, ISC_R_SUCCESS);
+
+ dns_db_currentversion(db, &version);
+
+ result = dns_master_dump2(mctx, db, version,
+ &dns_master_style_default, "test.dump",
+ dns_masterformat_raw);
+ ATF_REQUIRE_EQ(result, ISC_R_SUCCESS);
+
+ result = test_master("test.dump", dns_masterformat_raw);
+ ATF_CHECK_STREQ(isc_result_totext(result), "success");
+ ATF_CHECK(headerset);
+ ATF_CHECK_EQ(header.flags, 0);
+
+ dns_master_initrawheader(&header);
+ header.sourceserial = 12345;
+ header.flags |= DNS_MASTERRAW_SOURCESERIALSET;
+
+ unlink("test.dump");
+ result = dns_master_dump3(mctx, db, version,
+ &dns_master_style_default, "test.dump",
+ dns_masterformat_raw, &header);
+ ATF_REQUIRE_EQ(result, ISC_R_SUCCESS);
+
+ result = test_master("test.dump", dns_masterformat_raw);
+ ATF_CHECK_STREQ(isc_result_totext(result), "success");
+ ATF_CHECK(headerset);
+ ATF_CHECK((header.flags & DNS_MASTERRAW_SOURCESERIALSET) != 0);
+ ATF_CHECK_EQ(header.sourceserial, 12345);
+
+ unlink("test.dump");
+ dns_db_closeversion(db, &version, ISC_FALSE);
+ dns_db_detach(&db);
+ dns_test_end();
+}
+
/*
* Main
*/
ATF_TP_ADD_TCS(tp) {
- ATF_TP_ADD_TC(tp, master_load);
- ATF_TP_ADD_TC(tp, master_unexpected);
- ATF_TP_ADD_TC(tp, master_noowner);
- ATF_TP_ADD_TC(tp, master_nottl);
- ATF_TP_ADD_TC(tp, master_badclass);
- ATF_TP_ADD_TC(tp, master_dnskey);
- ATF_TP_ADD_TC(tp, master_dnsnokey);
- ATF_TP_ADD_TC(tp, master_include);
- ATF_TP_ADD_TC(tp, master_includefail);
- ATF_TP_ADD_TC(tp, master_blanklines);
- ATF_TP_ADD_TC(tp, master_leadingzero);
- ATF_TP_ADD_TC(tp, master_totext);
+ ATF_TP_ADD_TC(tp, load);
+ ATF_TP_ADD_TC(tp, unexpected);
+ ATF_TP_ADD_TC(tp, noowner);
+ ATF_TP_ADD_TC(tp, nottl);
+ ATF_TP_ADD_TC(tp, badclass);
+ ATF_TP_ADD_TC(tp, dnskey);
+ ATF_TP_ADD_TC(tp, dnsnokey);
+ ATF_TP_ADD_TC(tp, include);
+ ATF_TP_ADD_TC(tp, includefail);
+ ATF_TP_ADD_TC(tp, blanklines);
+ ATF_TP_ADD_TC(tp, leadingzero);
+ ATF_TP_ADD_TC(tp, totext);
+ ATF_TP_ADD_TC(tp, loadraw);
+ ATF_TP_ADD_TC(tp, dumpraw);
return (atf_no_error());
}
--- /dev/null
+#!/usr/bin/perl -w
+#
+# Copyright (C) 2011 Internet Systems Consortium, Inc. ("ISC")
+#
+# Permission to use, copy, modify, and/or 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: mkraw.pl,v 1.2 2011/12/08 16:07:22 each Exp $
+
+# Convert a hexdump to binary format.
+#
+# To convert binary data to the input format for this command,
+# use the following:
+#
+# perl -e 'while (read(STDIN, my $byte, 1)) {
+# print unpack("H2", $byte);
+# }
+# print "\n";' < file > file.in
+
+use strict;
+chomp(my $line = <STDIN>);
+print pack("H*", $line);
1800 ;retry
604800 ;expiration
3600 ) ;minimum
-a in ns ns.vix.com.
-a in ns ns2vix.com.
-a in ns ns3vix.com.
+ in ns ns.vix.com.
+ in ns ns2.vix.com.
+ in ns ns3.vix.com.
b in a 1.2.3.4
--- /dev/null
+00000002000000004ed7306600000051000100060000000003e80000000100060474657374000035096c6f63616c686f7374000a706f73746d6173746572096c6f63616c686f73740076cb8ab100000e100000070800093a8000000e1000000046000100020000000003e8000000030006047465737400000c026e730376697803636f6d00000d036e73320376697803636f6d00000d036e73330376697803636f6d0000000022000100010000000003e80000000100080162047465737400000401020304
--- /dev/null
+00000002000000014ed7337f00000000000000000000000000000051000100060000000003e80000000100060474657374000035096c6f63616c686f7374000a706f73746d6173746572096c6f63616c686f73740076cb8ab100000e100000070800093a8000000e1000000046000100020000000003e8000000030006047465737400000c026e730376697803636f6d00000d036e73320376697803636f6d00000d036e73330376697803636f6d0000000022000100010000000003e80000000100080162047465737400000401020304
--- /dev/null
+00000002000000014ed7337f0000000277df41e50000000000000051000100060000000003e80000000100060474657374000035096c6f63616c686f7374000a706f73746d6173746572096c6f63616c686f73740076cb8ab100000e100000070800093a8000000e1000000046000100020000000003e8000000030006047465737400000c026e730376697803636f6d00000d036e73320376697803636f6d00000d036e73330376697803636f6d0000000022000100010000000003e80000000100080162047465737400000401020304
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: zone.c,v 1.650 2011/12/07 22:48:22 marka Exp $ */
+/* $Id: zone.c,v 1.651 2011/12/08 16:07:21 each Exp $ */
/*! \file */
dns_zone_t *raw;
dns_zone_t *secure;
+
+ isc_boolean_t rawserialset;
+ isc_uint32_t rawserial;
};
#define DNS_ZONE_FLAG(z,f) (ISC_TF(((z)->flags & (f)) != 0))
ISC_LIST_INIT(zone->forwards);
zone->raw = NULL;
zone->secure = NULL;
+ zone->rawserial = 0;
+ zone->rawserialset = ISC_FALSE;
zone->magic = ZONE_MAGIC;
result = dns_master_loadfileinc3(load->zone->masterfile,
dns_db_origin(load->db),
dns_db_origin(load->db),
- load->zone->rdclass,
- options,
+ load->zone->rdclass, options,
load->zone->sigresigninginterval,
&load->callbacks, task,
zone_loaddone, load,
zone_loaddone(load, result);
}
+static void
+get_raw_serial(dns_zone_t *raw, dns_masterrawheader_t *rawdata) {
+ isc_result_t result;
+
+ LOCK(&raw->lock);
+ if (raw->db != NULL) {
+ result = zone_get_from_db(raw, raw->db, NULL, NULL,
+ &rawdata->sourceserial,
+ NULL, NULL, NULL, NULL,
+ NULL);
+ if (result == ISC_R_SUCCESS)
+ rawdata->flags |= DNS_MASTERRAW_SOURCESERIALSET;
+ }
+ UNLOCK(&raw->lock);
+}
+
static void
zone_gotwritehandle(isc_task_t *task, isc_event_t *event) {
const char me[] = "zone_gotwritehandle";
dns_zone_t *zone = event->ev_arg;
isc_result_t result = ISC_R_SUCCESS;
dns_dbversion_t *version = NULL;
+ dns_masterrawheader_t rawdata;
REQUIRE(DNS_ZONE_VALID(zone));
INSIST(task == zone->task);
LOCK_ZONE(zone);
ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read);
dns_db_currentversion(zone->db, &version);
- result = dns_master_dumpinc2(zone->mctx, zone->db, version,
+ dns_master_initrawheader(&rawdata);
+ if (zone->raw != NULL)
+ get_raw_serial(zone->raw, &rawdata);
+ result = dns_master_dumpinc3(zone->mctx, zone->db, version,
&dns_master_style_default,
zone->masterfile, zone->task, dump_done,
- zone, &zone->dctx, zone->masterformat);
+ zone, &zone->dctx, zone->masterformat,
+ &rawdata);
dns_db_closeversion(zone->db, &version, ISC_FALSE);
ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
UNLOCK_ZONE(zone);
dump_done(zone, result);
}
+static void
+zone_setrawdata(dns_zone_t *zone, dns_masterrawheader_t *header) {
+ if (zone == NULL)
+ return;
+
+ /*
+ * Save the raw serial number for inline-signing zones.
+ * (XXX: Other information from the header will be used
+ * for other purposes in the future, but for now this is
+ * all we're interested in.)
+ */
+ if (zone->raw != NULL ||
+ ((header->flags & DNS_MASTERRAW_SOURCESERIALSET) == 0))
+ return;
+
+ LOCK_ZONE(zone);
+ zone->rawserial = header->sourceserial;
+ zone->rawserialset = ISC_TRUE;
+ UNLOCK_ZONE(zone);
+}
+
static isc_result_t
zone_startload(dns_db_t *db, dns_zone_t *zone, isc_time_t loadtime) {
dns_load_t *load;
zone_iattach(zone, &load->zone);
dns_db_attach(db, &load->db);
dns_rdatacallbacks_init(&load->callbacks);
+ load->callbacks.rawdata = zone_setrawdata;
+ zone_iattach(zone, &load->callbacks.zone);
result = dns_db_beginload(db, &load->callbacks.add,
&load->callbacks.add_private);
if (result != ISC_R_SUCCESS)
dns_rdatacallbacks_t callbacks;
dns_rdatacallbacks_init(&callbacks);
+ callbacks.rawdata = zone_setrawdata;
+ zone_iattach(zone, &callbacks.zone);
result = dns_db_beginload(db, &callbacks.add,
&callbacks.add_private);
- if (result != ISC_R_SUCCESS)
+ if (result != ISC_R_SUCCESS) {
+ zone_idetach(&callbacks.zone);
return (result);
- result = dns_master_loadfile3(zone->masterfile, &zone->origin,
- &zone->origin, zone->rdclass,
- options, zone->sigresigninginterval,
+ }
+ result = dns_master_loadfile3(zone->masterfile,
+ &zone->origin, &zone->origin,
+ zone->rdclass, options,
+ zone->sigresigninginterval,
&callbacks, zone->mctx,
zone->masterformat);
tresult = dns_db_endload(db, &callbacks.add_private);
if (result == ISC_R_SUCCESS)
result = tresult;
+ zone_idetach(&callbacks.zone);
}
return (result);
load->magic = 0;
dns_db_detach(&load->db);
zone_idetach(&load->zone);
+ zone_idetach(&load->callbacks.zone);
isc_mem_detach(&load->mctx);
isc_mem_put(zone->mctx, load, sizeof(*load));
return (result);
result = DNS_R_CONTINUE;
UNLOCK_ZONE(zone);
} else {
+ dns_masterrawheader_t rawdata;
dns_db_currentversion(db, &version);
- result = dns_master_dump2(zone->mctx, db, version,
+ dns_master_initrawheader(&rawdata);
+ if (zone->raw != NULL)
+ get_raw_serial(zone->raw, &rawdata);
+ result = dns_master_dump3(zone->mctx, db, version,
&dns_master_style_default,
- masterfile, masterformat);
+ masterfile, masterformat,
+ &rawdata);
dns_db_closeversion(db, &version, ISC_FALSE);
}
fail:
static isc_result_t
dumptostream(dns_zone_t *zone, FILE *fd, const dns_master_style_t *style,
- dns_masterformat_t format)
+ dns_masterformat_t format, const isc_uint32_t rawversion)
{
isc_result_t result;
dns_dbversion_t *version = NULL;
dns_db_t *db = NULL;
+ dns_masterrawheader_t rawdata;
REQUIRE(DNS_ZONE_VALID(zone));
return (DNS_R_NOTLOADED);
dns_db_currentversion(db, &version);
- result = dns_master_dumptostream2(zone->mctx, db, version, style,
- format, fd);
+ dns_master_initrawheader(&rawdata);
+ if (rawversion == 0)
+ rawdata.flags |= DNS_MASTERRAW_COMPAT;
+ if (zone->raw != NULL && rawversion > 0)
+ get_raw_serial(zone->raw, &rawdata);
+ result = dns_master_dumptostream3(zone->mctx, db, version, style,
+ format, &rawdata, fd);
dns_db_closeversion(db, &version, ISC_FALSE);
dns_db_detach(&db);
return (result);
}
+isc_result_t
+dns_zone_dumptostream3(dns_zone_t *zone, FILE *fd, dns_masterformat_t format,
+ const dns_master_style_t *style,
+ const isc_uint32_t rawversion)
+{
+ return (dumptostream(zone, fd, style, format, rawversion));
+}
+
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);
+ return (dumptostream(zone, fd, style, format, DNS_RAWFORMAT_VERSION));
}
isc_result_t
dns_zone_dumptostream(dns_zone_t *zone, FILE *fd) {
- return dumptostream(zone, fd, &dns_master_style_default,
- dns_masterformat_text);
+ return (dumptostream(zone, fd, &dns_master_style_default,
+ dns_masterformat_text, 0));
}
isc_result_t
dns_zone_fulldumptostream(dns_zone_t *zone, FILE *fd) {
- return dumptostream(zone, fd, &dns_master_style_full,
- dns_masterformat_text);
+ return (dumptostream(zone, fd, &dns_master_style_full,
+ dns_masterformat_text, 0));
}
void
LOCK_ZONE(zone);
DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NEEDNOTIFY);
+ zone->rawserial = start;
+ zone->rawserialset = ISC_TRUE;
zone_needdump(zone, DNS_DUMP_DELAY);
TIME_NOW(&timenow);
(void)zone_postload(load->zone, load->db, load->loadtime, result);
zonemgr_putio(&load->zone->readio);
DNS_ZONE_CLRFLAG(load->zone, DNS_ZONEFLG_LOADING);
+ zone_idetach(&load->callbacks.zone);
/*
* Leave the zone frozen if the reload fails.
*/