]> git.ipfire.org Git - thirdparty/bind9.git/commitdiff
3241. [func] Extended the header of raw-format master files to
authorEvan Hunt <each@isc.org>
Thu, 8 Dec 2011 16:07:22 +0000 (16:07 +0000)
committerEvan Hunt <each@isc.org>
Thu, 8 Dec 2011 16:07:22 +0000 (16:07 +0000)
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]

30 files changed:
CHANGES
bin/check/check-tool.c
bin/check/check-tool.h
bin/check/named-checkzone.c
bin/check/named-checkzone.docbook
bin/dnssec/dnssec-signzone.c
bin/dnssec/dnssec-signzone.docbook
bin/tests/system/dnssec/clean.sh
bin/tests/system/dnssec/tests.sh
bin/tests/system/masterformat/clean.sh
bin/tests/system/masterformat/ns1/compile.sh
bin/tests/system/masterformat/ns1/named.conf
bin/tests/system/masterformat/setup.sh
bin/tests/system/masterformat/tests.sh
lib/dns/callbacks.c
lib/dns/include/dns/callbacks.h
lib/dns/include/dns/master.h
lib/dns/include/dns/masterdump.h
lib/dns/include/dns/types.h
lib/dns/include/dns/zone.h
lib/dns/master.c
lib/dns/masterdump.c
lib/dns/tests/Makefile.in
lib/dns/tests/master_test.c
lib/dns/tests/mkraw.pl [new file with mode: 0644]
lib/dns/tests/testdata/master/master1.data
lib/dns/tests/testdata/master/master12.data.in [new file with mode: 0644]
lib/dns/tests/testdata/master/master13.data.in [new file with mode: 0644]
lib/dns/tests/testdata/master/master14.data.in [new file with mode: 0644]
lib/dns/zone.c

diff --git a/CHANGES b/CHANGES
index ef840b0f3e6524d2d7827e623e981716c7ce0f0e..76db5a99d682307899a14331439c5f2d3076d086 100644 (file)
--- a/CHANGES
+++ b/CHANGES
@@ -1,3 +1,18 @@
+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]
 
index 422d9b1cde98f59555340a7ed9c8ba2718934360..baf7dcab6055f9fb6cab567b61708d88d541ef53 100644 (file)
@@ -15,7 +15,7 @@
  * 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 */
 
@@ -635,7 +635,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,
-         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;
@@ -658,7 +659,8 @@ dump_zone(const char *zonename, dns_zone_t *zone, const char *filename,
                }
        }
 
-       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);
index e988597a740d0450524180d5fb2f552d509480b3..daeb2b91d2dfc0fc501f0a5f72d6fd6c94a33b3b 100644 (file)
@@ -15,7 +15,7 @@
  * 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
@@ -41,7 +41,8 @@ load_zone(isc_mem_t *mctx, const char *zonename, const char *filename,
 
 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);
index 4ba952473a9082b87d18e20a7f4c868fe458be9d..0d0d8453a9a222ce1cc377e7b2382f47ba752447 100644 (file)
@@ -15,7 +15,7 @@
  * 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 */
 
@@ -112,6 +112,7 @@ main(int argc, char **argv) {
        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;
@@ -397,7 +398,11 @@ main(int argc, char **argv) {
                        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);
@@ -405,11 +410,22 @@ main(int argc, char **argv) {
        }
 
        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);
@@ -467,7 +483,7 @@ main(int argc, char **argv) {
                        fflush(errout);
                }
                result = dump_zone(origin, zone, output_filename,
-                                  outputformat, outputstyle);
+                                  outputformat, outputstyle, rawversion);
                if (!quiet && progmode == progmode_compile)
                        fprintf(errout, "done\n");
        }
index 33dc15e47095c1f2ed87a58041c6429addf1c1bd..5e81fc08b3d3d3c725a86f233d9eec5365698427 100644 (file)
@@ -18,7 +18,7 @@
  - 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>
 
index a6df36b38c8bc532dc6851d299755082de86befb..6b1f353e737bcab1ec402aedd7a80a55a9bd9843 100644 (file)
@@ -29,7 +29,7 @@
  * 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 */
 
@@ -139,6 +139,7 @@ static char *tempfile = NULL;
 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;
@@ -3808,18 +3809,35 @@ main(int argc, char *argv[]) {
                        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);
        }
@@ -4054,11 +4072,15 @@ main(int argc, char *argv[]) {
        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);
index d571e95d21579cbebf8d1d659f1a622410a9b32d..2517d199bc3a120df3d4df2d24690a4726bac2ed 100644 (file)
@@ -18,7 +18,7 @@
  - 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>
index 35ad87e179d329b51e38452e3ba0d7bdfee75c4c..8bce9d805f8a8a272ae848a7c8ed36c07d938af7 100644 (file)
@@ -15,7 +15,7 @@
 # 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
@@ -47,7 +47,7 @@ rm -f ns3/secure.optout.example.db
 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
index ec656ee309a99b76bff980ad0cff431c8473e0c4..054e84d64f8eecc82ad84126ac3437a69da8c382 100644 (file)
@@ -15,7 +15,7 @@
 # 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
@@ -57,6 +57,22 @@ checkprivate () {
     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)"
@@ -1109,11 +1125,17 @@ echo "I:checking dnssec-signzone output format ($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`
 
index 9728b85d2f9671551bd8dab16b5f79204ad2bda0..be50b22189c99109c801cf6d862e93a54021c076 100755 (executable)
 # 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
index 551a01f0bd6399672d7adc2446e00c2d8775791b..f00c5c0ca5353e7710ba3f386703b85a232d9edc 100755 (executable)
 # 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
index 1243a3aec16eeb72b9d2fd3328171078eb57731c..b16c7000bacae2dd3a6eddb6324c10de320d3231 100644 (file)
@@ -14,7 +14,7 @@
  * 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
 
@@ -36,6 +36,12 @@ zone "example" {
        file "example.db.raw";
 };
 
+zone "compat-example" {
+       type master;
+       masterfile-format raw;
+       file "example.db.compat";
+};
+
 zone "transfer1" {
         type master;
         file "example.db";
index 31a6ef07944ce35d9388045f484ee753492a9270..ba014a20b1d25e315344e8c38470db940e373e25 100755 (executable)
@@ -12,8 +12,9 @@
 # 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/
index ae78110f15d4ed74556d6bf5e2f9869a8fc84a0a..74678ecc5b8e0c595d517620f0d36ee699395265 100755 (executable)
 # 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`
 
@@ -64,6 +82,7 @@ for i in 0 1 2 3 4 5 6 7 8 9
 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
index 928f37df7809ee1efaa53f33a666b60fcfdca27e..ee36142ee440664d43c66bf63a688b2171eab15f 100644 (file)
@@ -15,7 +15,7 @@
  * 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 */
 
@@ -88,6 +88,8 @@ dns_rdatacallbacks_initcommon(dns_rdatacallbacks_t *callbacks) {
        REQUIRE(callbacks != NULL);
 
        callbacks->add = NULL;
+       callbacks->rawdata = NULL;
+       callbacks->zone = NULL;
        callbacks->add_private = NULL;
        callbacks->error_private = NULL;
        callbacks->warn_private = NULL;
index 8a8385a99534866215754a2f68f6edc94e687fbf..bb3b357a1b195df86e33678cbac0b65d15a40b5a 100644 (file)
@@ -15,7 +15,7 @@
  * 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
@@ -41,6 +41,14 @@ struct dns_rdatacallbacks {
         * 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.
         */
index 41560ee4b2cd4b46aa4fdf9bdfba39eb1097630e..4ab41fc4662d00d37545043a693682fbd8c94c48 100644 (file)
@@ -15,7 +15,7 @@
  * 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
@@ -66,18 +66,29 @@ ISC_LANG_BEGINDECLS
  * 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 {
@@ -302,6 +313,12 @@ dns_loadctx_cancel(dns_loadctx_t *ctx);
  *\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 */
index 99e1caeece8c2346cac1ae3c5cf1363c399e524c..0ad553445cad33c04bb96bc2ae28385bf2644e21 100644 (file)
@@ -15,7 +15,7 @@
  * 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
@@ -220,13 +220,25 @@ 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);
+
+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'.
  *
@@ -256,6 +268,13 @@ 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_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,
@@ -267,14 +286,24 @@ dns_master_dump2(isc_mem_t *mctx, dns_db_t *db,
                 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'.
  *
index b37251d8459a2b266e9de56d8c19999f859b5be9..caa334757d54315e899a29d97323053920d96e98 100644 (file)
@@ -15,7 +15,7 @@
  * 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
@@ -85,6 +85,7 @@ typedef struct dns_keytable                   dns_keytable_t;
 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;
@@ -355,6 +356,9 @@ typedef void
 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 *);
 
index bcf93a0408531a941717f2562985424c2a1e59a0..9f8ed39e56759204abb55a85aa16391d68a526d9 100644 (file)
@@ -15,7 +15,7 @@
  * 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
@@ -510,6 +510,10 @@ 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);
+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
@@ -519,7 +523,11 @@ dns_zone_dumptostream2(dns_zone_t *zone, FILE *fd, dns_masterformat_t format,
  *    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:
index 7cebcccf7382e45dd0c930428bd475d69b69b237..a3e5b4eb4b404118e514c50f5fa7e940c5fba030 100644 (file)
@@ -15,7 +15,7 @@
  * 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 */
 
@@ -133,6 +133,7 @@ struct dns_loadctx {
        /* 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,
@@ -595,6 +596,7 @@ loadctx_create(dns_masterformat_t format, isc_mem_t *mctx,
 
        lctx->f = NULL;
        lctx->first = ISC_TRUE;
+       dns_master_initrawheader(&lctx->header);
 
        lctx->loop_cnt = (done != NULL) ? 100 : 0;
        lctx->callbacks = callbacks;
@@ -2086,48 +2088,72 @@ load_raw(dns_loadctx_t *lctx) {
        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);
@@ -2353,6 +2379,9 @@ load_raw(dns_loadctx_t *lctx) {
        } 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));
@@ -2935,3 +2964,8 @@ dns_loadctx_cancel(dns_loadctx_t *lctx) {
        lctx->canceled = ISC_TRUE;
        UNLOCK(&lctx->lock);
 }
+
+void
+dns_master_initrawheader(dns_masterrawheader_t *header) {
+       memset(header, 0, sizeof(dns_masterrawheader_t));
+}
index ff5438775410af0597b07f705c5dfc14a29a41bc..0d91ce37decebdad0757ff3f799f3db61f8868fd 100644 (file)
@@ -15,7 +15,7 @@
  * 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 */
 
@@ -188,6 +188,7 @@ struct dns_dumpctx {
        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,
@@ -1265,7 +1266,7 @@ 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,
-              dns_masterformat_t format)
+              dns_masterformat_t format, dns_masterrawheader_t *header)
 {
        dns_dumpctx_t *dctx;
        isc_result_t result;
@@ -1289,6 +1290,10 @@ dumpctx_create(isc_mem_t *mctx, dns_db_t *db, dns_dbversion_t *version,
        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:
@@ -1356,7 +1361,7 @@ dumptostreaminc(dns_dumpctx_t *dctx) {
        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);
@@ -1391,8 +1396,6 @@ dumptostreaminc(dns_dumpctx_t *dctx) {
                        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,
@@ -1411,7 +1414,22 @@ dumptostreaminc(dns_dumpctx_t *dctx) {
 #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,
@@ -1530,7 +1548,7 @@ dns_master_dumptostreaminc(isc_mem_t *mctx, dns_db_t *db,
        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);
@@ -1557,8 +1575,8 @@ dns_master_dumptostream(isc_mem_t *mctx, dns_db_t *db,
                        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
@@ -1566,11 +1584,23 @@ 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)
+{
+       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);
 
@@ -1621,9 +1651,9 @@ 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)
 {
-       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
@@ -1631,6 +1661,17 @@ 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)
+{
+       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;
@@ -1646,7 +1687,8 @@ dns_master_dumpinc2(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, 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);
@@ -1682,14 +1724,23 @@ 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));
+       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;
@@ -1700,7 +1751,8 @@ dns_master_dump2(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, format);
+       result = dumpctx_create(mctx, db, version, style, f, &dctx,
+                               format, header);
        if (result != ISC_R_SUCCESS)
                goto cleanup;
 
index a464a63c4e8fe7033d7284f609b7e4c8f9e492ea..cb2e865347c221ef25c34f737a4c25a5897490a4 100644 (file)
@@ -12,7 +12,7 @@
 # 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@
@@ -49,6 +49,12 @@ TARGETS =    master_test@EXEEXT@ dbiterator_test@EXEEXT@ time_test@EXEEXT@ \
 @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}
@@ -99,3 +105,5 @@ unit::
 clean distclean::
        rm -f ${TARGETS}
        rm -f atf.out
+       rm -f testdata/master/master12.data testdata/master/master13.data \
+               testdata/master/master14.data 
index 99c1daa1cbe03fcbdcebd3c86f51cc61b855e164..82d2efd481996fd0ab8b0b84284a8dcfbf0090a5 100644 (file)
@@ -14,7 +14,7 @@
  * 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 */
 
@@ -26,6 +26,7 @@
 
 #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];
@@ -60,8 +67,15 @@ add_callback(void *arg, dns_name_t *owner, dns_rdataset_t *dataset) {
        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)];
@@ -78,6 +92,7 @@ test_master(const char *testfile) {
        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);
@@ -86,10 +101,12 @@ test_master(const char *testfile) {
 
        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);
 }
 
@@ -98,12 +115,12 @@ test_master(const char *testfile) {
  */
 
 /* 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);
@@ -111,7 +128,8 @@ ATF_TC_BODY(master_load, 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();
@@ -119,13 +137,13 @@ ATF_TC_BODY(master_load, tc) {
 
 
 /* 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);
@@ -133,7 +151,8 @@ ATF_TC_BODY(master_unexpected, 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();
@@ -141,13 +160,13 @@ ATF_TC_BODY(master_unexpected, tc) {
 
 
 /* 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);
@@ -155,7 +174,8 @@ ATF_TC_BODY(master_noowner, 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();
@@ -163,14 +183,14 @@ ATF_TC_BODY(master_noowner, tc) {
 
 
 /* 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);
@@ -178,7 +198,8 @@ ATF_TC_BODY(master_nottl, 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();
@@ -186,13 +207,13 @@ ATF_TC_BODY(master_nottl, tc) {
 
 
 /* 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);
@@ -200,19 +221,20 @@ ATF_TC_BODY(master_badclass, 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);
@@ -220,7 +242,8 @@ ATF_TC_BODY(master_dnskey, 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();
@@ -228,12 +251,12 @@ ATF_TC_BODY(master_dnskey, tc) {
 
 
 /* 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);
@@ -241,19 +264,20 @@ ATF_TC_BODY(master_dnsnokey, 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);
@@ -261,19 +285,20 @@ ATF_TC_BODY(master_include, 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);
@@ -281,7 +306,8 @@ ATF_TC_BODY(master_includefail, 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();
@@ -289,12 +315,12 @@ ATF_TC_BODY(master_includefail, tc) {
 
 
 /* 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);
@@ -302,19 +328,20 @@ ATF_TC_BODY(master_blanklines, 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);
@@ -322,17 +349,18 @@ ATF_TC_BODY(master_leadingzero, 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;
@@ -372,22 +400,136 @@ ATF_TC_BODY(master_totext, tc) {
        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());
 }
diff --git a/lib/dns/tests/mkraw.pl b/lib/dns/tests/mkraw.pl
new file mode 100644 (file)
index 0000000..5290fd0
--- /dev/null
@@ -0,0 +1,31 @@
+#!/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);
index 9b8147407ce12d7123c9afe33a714333dd4c65a2..030bc689355a47b2e9d379349de22cbcf8e67aa0 100644 (file)
@@ -5,7 +5,7 @@ $TTL 1000
                                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
diff --git a/lib/dns/tests/testdata/master/master12.data.in b/lib/dns/tests/testdata/master/master12.data.in
new file mode 100644 (file)
index 0000000..3634388
--- /dev/null
@@ -0,0 +1 @@
+00000002000000004ed7306600000051000100060000000003e80000000100060474657374000035096c6f63616c686f7374000a706f73746d6173746572096c6f63616c686f73740076cb8ab100000e100000070800093a8000000e1000000046000100020000000003e8000000030006047465737400000c026e730376697803636f6d00000d036e73320376697803636f6d00000d036e73330376697803636f6d0000000022000100010000000003e80000000100080162047465737400000401020304
diff --git a/lib/dns/tests/testdata/master/master13.data.in b/lib/dns/tests/testdata/master/master13.data.in
new file mode 100644 (file)
index 0000000..d1c262f
--- /dev/null
@@ -0,0 +1 @@
+00000002000000014ed7337f00000000000000000000000000000051000100060000000003e80000000100060474657374000035096c6f63616c686f7374000a706f73746d6173746572096c6f63616c686f73740076cb8ab100000e100000070800093a8000000e1000000046000100020000000003e8000000030006047465737400000c026e730376697803636f6d00000d036e73320376697803636f6d00000d036e73330376697803636f6d0000000022000100010000000003e80000000100080162047465737400000401020304
diff --git a/lib/dns/tests/testdata/master/master14.data.in b/lib/dns/tests/testdata/master/master14.data.in
new file mode 100644 (file)
index 0000000..149a25f
--- /dev/null
@@ -0,0 +1 @@
+00000002000000014ed7337f0000000277df41e50000000000000051000100060000000003e80000000100060474657374000035096c6f63616c686f7374000a706f73746d6173746572096c6f63616c686f73740076cb8ab100000e100000070800093a8000000e1000000046000100020000000003e8000000030006047465737400000c026e730376697803636f6d00000d036e73320376697803636f6d00000d036e73330376697803636f6d0000000022000100010000000003e80000000100080162047465737400000401020304
index 782d9d22d51daf1e634343adeb68d12f2ca959bf..fe79101f88aeff8f17a25e51c14ae9021e0dcb14 100644 (file)
@@ -15,7 +15,7 @@
  * 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 */
 
@@ -363,6 +363,9 @@ struct dns_zone {
 
        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))
@@ -896,6 +899,8 @@ dns_zone_create(dns_zone_t **zonep, isc_mem_t *mctx) {
        ISC_LIST_INIT(zone->forwards);
        zone->raw = NULL;
        zone->secure = NULL;
+       zone->rawserial = 0;
+       zone->rawserialset = ISC_FALSE;
 
        zone->magic = ZONE_MAGIC;
 
@@ -1788,8 +1793,7 @@ zone_gotreadhandle(isc_task_t *task, isc_event_t *event) {
        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,
@@ -1804,12 +1808,29 @@ zone_gotreadhandle(isc_task_t *task, isc_event_t *event) {
        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);
@@ -1824,10 +1845,14 @@ 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_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);
@@ -1839,6 +1864,27 @@ zone_gotwritehandle(isc_task_t *task, isc_event_t *event) {
        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;
@@ -1866,6 +1912,8 @@ zone_startload(dns_db_t *db, dns_zone_t *zone, isc_time_t loadtime) {
                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)
@@ -1887,18 +1935,24 @@ zone_startload(dns_db_t *db, dns_zone_t *zone, isc_time_t loadtime) {
                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);
@@ -1907,6 +1961,7 @@ zone_startload(dns_db_t *db, dns_zone_t *zone, isc_time_t loadtime) {
        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);
@@ -8736,10 +8791,15 @@ zone_dump(dns_zone_t *zone, isc_boolean_t compact) {
                        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:
@@ -8778,11 +8838,12 @@ 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,
-            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));
 
@@ -8794,29 +8855,42 @@ 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_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
@@ -12147,6 +12221,8 @@ receive_secure_serial(isc_task_t *task, isc_event_t *event) {
        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);
@@ -12803,6 +12879,7 @@ zone_loaddone(void *arg, isc_result_t result) {
        (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.
         */