1#!/bin/sh
2#
3# Copyright (C) 2005, 2007, 2011-2014  Internet Systems Consortium, Inc. ("ISC")
4#
5# Permission to use, copy, modify, and/or distribute this software for any
6# purpose with or without fee is hereby granted, provided that the above
7# copyright notice and this permission notice appear in all copies.
8#
9# THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
10# REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
11# AND FITNESS.  IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
12# INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
13# LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
14# OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
15# PERFORMANCE OF THIS SOFTWARE.
16
17# Id
18
19SYSTEMTESTTOP=..
20. $SYSTEMTESTTOP/conf.sh
21
22ismap () {
23    $PERL -e 'binmode STDIN;
24	     read(STDIN, $input, 8);
25             ($style, $version) = unpack("NN", $input);
26             exit 1 if ($style != 3 || $version > 1);' < $1
27    return $?
28}
29
30israw () {
31    $PERL -e 'binmode STDIN;
32             read(STDIN, $input, 8);
33             ($style, $version) = unpack("NN", $input);
34             exit 1 if ($style != 2 || $version > 1);' < $1
35    return $?
36}
37
38rawversion () {
39    $PERL -e 'binmode STDIN;
40             read(STDIN, $input, 8);
41             if (length($input) < 8) { print "not raw\n"; exit 0; };
42             ($style, $version) = unpack("NN", $input);
43             print ($style == 2 || $style == 3 ? "$version\n" :
44		"not raw or map\n");' < $1
45}
46
47sourceserial () {
48    $PERL -e 'binmode STDIN;
49             read(STDIN, $input, 20);
50             if (length($input) < 20) { print "UNSET\n"; exit; };
51             ($format, $version, $dumptime, $flags, $sourceserial) =
52                     unpack("NNNNN", $input);
53             if ($format != 2 || $version <  1) { print "UNSET\n"; exit; };
54             if ($flags & 02) {
55                     print $sourceserial . "\n";
56             } else {
57                     print "UNSET\n";
58             }' < $1
59}
60
61stomp () {
62        $PERL -e 'open(my $file, "+<", $ARGV[0]);
63                 binmode $file;
64                 seek($file, $ARGV[1], 0);
65                 for (my $i = 0; $i < $ARGV[2]; $i++) {
66                         print $file pack('C', $ARGV[3]);
67                 }
68                 close($file);' $1 $2 $3 $4
69}
70
71restart () {
72    sleep 1
73    (cd ..; $PERL start.pl --noclean --restart masterformat ns3)
74}
75
76DIGOPTS="+tcp +noauth +noadd +nosea +nostat +noquest +nocomm +nocmd"
77
78status=0
79
80echo "I:checking that master files in raw format loaded"
81ret=0
82set -- 1 2 3
83for zone in example example-explicit example-compat; do
84    for server in $*; do
85	for name in ns mx a aaaa cname dname txt rrsig nsec \
86		    dnskey ds cdnskey cds; do
87		$DIG $DIGOPTS $name.$zone. $name @10.53.0.$server -p 5300
88		echo
89	done > dig.out.$zone.$server
90    done
91    $PERL ../digcomp.pl dig.out.$zone.1 dig.out.$zone.2 || ret=1
92    if [ $zone = "example" ]; then
93            set -- 1 2
94            $PERL ../digcomp.pl dig.out.$zone.1 dig.out.$zone.3 || ret=1
95    fi
96done
97[ $ret -eq 0 ] || echo "I:failed"
98status=`expr $status + $ret`
99
100echo "I:checking raw format versions"
101ret=0
102israw ns1/example.db.raw || ret=1
103israw ns1/example.db.raw1 || ret=1
104israw ns1/example.db.compat || ret=1
105ismap ns1/example.db.map || ret=1
106[ "`rawversion ns1/example.db.raw`" = 1 ] || ret=1
107[ "`rawversion ns1/example.db.raw1`" = 1 ] || ret=1
108[ "`rawversion ns1/example.db.compat`" = 0 ] || ret=1
109[ "`rawversion ns1/example.db.map`" = 1 ] || ret=1
110[ $ret -eq 0 ] || echo "I:failed"
111status=`expr $status + $ret`
112
113echo "I:checking source serial numbers"
114ret=0
115[ "`sourceserial ns1/example.db.raw`" = "UNSET" ] || ret=1
116[ "`sourceserial ns1/example.db.serial.raw`" = "3333" ] || ret=1
117[ $ret -eq 0 ] || echo "I:failed"
118status=`expr $status + $ret`
119
120echo "I:waiting for transfers to complete"
121for i in 0 1 2 3 4 5 6 7 8 9
122do
123	test -f ns2/transfer.db.raw -a -f ns2/transfer.db.txt && break
124	sleep 1
125done
126
127echo "I:checking that slave was saved in raw format by default"
128ret=0
129israw ns2/transfer.db.raw || ret=1
130[ $ret -eq 0 ] || echo "I:failed"
131status=`expr $status + $ret`
132
133echo "I:checking that slave was saved in text format when configured"
134ret=0
135israw ns2/transfer.db.txt && ret=1
136[ $ret -eq 0 ] || echo "I:failed"
137status=`expr $status + $ret`
138
139echo "I:checking that slave formerly in text format is now raw"
140for i in 0 1 2 3 4 5 6 7 8 9
141do
142    ret=0
143    israw ns2/formerly-text.db > /dev/null 2>&1 || ret=1
144    [ "`rawversion ns2/formerly-text.db`" = 1 ] || ret=1
145    [ $ret -eq 0 ] && break
146    sleep 1
147done
148[ $ret -eq 0 ] || echo "I:failed"
149status=`expr $status + $ret`
150
151echo "I:checking that large rdatasets loaded"
152for i in 0 1 2 3 4 5 6 7 8 9
153do
154ret=0
155for a in a b c
156do
157	$DIG +tcp txt ${a}.large @10.53.0.2 -p 5300 > dig.out
158	grep "status: NOERROR" dig.out > /dev/null || ret=1
159done
160[ $ret -eq 0 ] && break
161sleep 1
162done
163
164echo "I:checking format transitions: text->raw->map->text"
165ret=0
166./named-compilezone -D -f text -F text -o baseline.txt example.nil ns1/example.db > /dev/null
167./named-compilezone -D -f text -F raw -o raw.1 example.nil baseline.txt > /dev/null
168./named-compilezone -D -f raw -F map -o map.1 example.nil raw.1 > /dev/null
169./named-compilezone -D -f map -F text -o text.1 example.nil map.1 > /dev/null
170cmp -s baseline.txt text.1 || ret=0
171[ $ret -eq 0 ] || echo "I:failed"
172status=`expr $status + $ret`
173
174echo "I:checking format transitions: text->map->raw->text"
175ret=0
176./named-compilezone -D -f text -F map -o map.2 example.nil baseline.txt > /dev/null
177./named-compilezone -D -f map -F raw -o raw.2 example.nil map.2 > /dev/null
178./named-compilezone -D -f raw -F text -o text.2 example.nil raw.2 > /dev/null
179cmp -s baseline.txt text.2 || ret=0
180[ $ret -eq 0 ] || echo "I:failed"
181status=`expr $status + $ret`
182
183echo "I:checking map format loading with journal file rollforward"
184ret=0
185$NSUPDATE <<END > /dev/null || status=1
186server 10.53.0.3 5300
187ttl 600
188update add newtext.dynamic IN TXT "added text"
189update delete aaaa.dynamic
190send
191END
192$DIG $DIGOPTS @10.53.0.3 -p 5300 newtext.dynamic txt > dig.out.dynamic.3.1
193grep "added text" dig.out.dynamic.3.1 > /dev/null 2>&1 || ret=1
194$DIG $DIGOPTS +comm @10.53.0.3 -p 5300 added.dynamic txt > dig.out.dynamic.3.2
195grep "NXDOMAIN"  dig.out.dynamic.3.2 > /dev/null 2>&1 || ret=1
196# using "rndc halt" ensures that we don't dump the zone file
197$RNDC -c ../common/rndc.conf -s 10.53.0.3 -p 9953 halt 2>&1 | sed 's/^/I:ns3 /'
198restart
199for i in 0 1 2 3 4 5 6 7 8 9; do
200    lret=0
201    $DIG $DIGOPTS @10.53.0.3 -p 5300 newtext.dynamic txt > dig.out.dynamic.3.3
202    grep "added text" dig.out.dynamic.3.3 > /dev/null 2>&1 || lret=1
203    [ $lret -eq 0 ] && break;
204done
205[ $lret -eq 1 ] && ret=1
206$DIG $DIGOPTS +comm @10.53.0.3 -p 5300 added.dynamic txt > dig.out.dynamic.3.4
207grep "NXDOMAIN"  dig.out.dynamic.3.4 > /dev/null 2>&1 || ret=1
208[ $ret -eq 0 ] || echo "I:failed"
209status=`expr $status + $ret`
210
211echo "I:checking map format file dumps correctly"
212ret=0
213$NSUPDATE <<END > /dev/null || status=1
214server 10.53.0.3 5300
215ttl 600
216update add moretext.dynamic IN TXT "more text"
217send
218END
219$DIG $DIGOPTS @10.53.0.3 -p 5300 moretext.dynamic txt > dig.out.dynamic.3.5
220grep "more text" dig.out.dynamic.3.5 > /dev/null 2>&1 || ret=1
221# using "rndc stop" will cause the zone file to flush before shutdown
222$RNDC -c ../common/rndc.conf -s 10.53.0.3 -p 9953 stop 2>&1 | sed 's/^/I:ns3 /'
223rm ns3/*.jnl
224restart
225for i in 0 1 2 3 4 5 6 7 8 9; do
226    lret=0
227    $DIG $DIGOPTS +comm @10.53.0.3 -p 5300 moretext.dynamic txt > dig.out.dynamic.3.6
228    grep "more text" dig.out.dynamic.3.6 > /dev/null 2>&1 || lret=1
229    [ $lret -eq 0 ] && break;
230done
231[ $lret -eq 1 ] && ret=1
232[ $ret -eq 0 ] || echo "I:failed"
233status=`expr $status + $ret`
234
235# stomp on the file data so it hashes differently.
236# these are small and subtle changes, so that the resulting file
237# would appear to be a legitimate map file and would not trigger an
238# assertion failure if loaded into memory, but should still fail to
239# load because of a SHA1 hash mismatch.
240echo "I:checking corrupt map files fail to load (bad node header)"
241ret=0
242./named-compilezone -D -f text -F map -o map.5 example.nil baseline.txt > /dev/null
243cp map.5 badmap
244stomp badmap 2754 2 99
245./named-compilezone -D -f map -F text -o text.5 example.nil badmap > /dev/null
246[ $? = 1 ] || ret=1
247[ $ret -eq 0 ] || echo "I:failed"
248status=`expr $status + $ret`
249
250echo "I:checking corrupt map files fail to load (bad node data)"
251ret=0
252cp map.5 badmap
253stomp badmap 2897 5 127
254./named-compilezone -D -f map -F text -o text.5 example.nil badmap > /dev/null
255[ $? = 1 ] || ret=1
256[ $ret -eq 0 ] || echo "I:failed"
257status=`expr $status + $ret`
258
259echo "I:checking map format zone is scheduled for resigning (compilezone)"
260ret=0
261$RNDC -c ../common/rndc.conf -s 10.53.0.1 -p 9953 zonestatus signed > rndc.out 2>&1 || ret=1
262grep 'next resign' rndc.out > /dev/null 2>&1 || ret=1
263[ $ret -eq 0 ] || echo "I:failed"
264status=`expr $status + $ret`
265
266echo "I:checking map format zone is scheduled for resigning (signzone)"
267ret=0
268$RNDC -c ../common/rndc.conf -s 10.53.0.1 -p 9953 freeze signed > rndc.out 2>&1 || ret=1
269cd ns1
270$SIGNER -S -O map -f signed.db.map -o signed signed.db > /dev/null 2>&1
271cd ..
272$RNDC -c ../common/rndc.conf -s 10.53.0.1 -p 9953 reload signed > rndc.out 2>&1 || ret=1
273$RNDC -c ../common/rndc.conf -s 10.53.0.1 -p 9953 zonestatus signed > rndc.out 2>&1 || ret=1
274grep 'next resign' rndc.out > /dev/null 2>&1 || ret=1
275[ $ret -eq 0 ] || echo "I:failed"
276status=`expr $status + $ret`
277
278echo "I:exit status: $status"
279exit $status
280