Commit 8e15d5eb authored by Mark Andrews's avatar Mark Andrews

3593. [func] Update EDNS processing to better track remote server

                        capabilities. [RT #30655]
parent 0ccb0e98
3593. [func] Update EDNS processing to better track remote server
capabilities. [RT #30655]
3592. [doc] Moved documentation of rndc command options to the
rndc man page. [RT #33506]
......
EDNS in BIND 9.10
The EDNS code in BIND 9.10 records successful plain and EDNS query
counts as well at timeouts for plain DNS and EDNS queries at various
EDNS buffer sizes: 4096, 1432, 1232 and 512 for each server named
talks to. A EDNS timeout for a lower buffer size is also counted
against higher buffer sizes. These are held in 8 bit counters and
are shifted on overflow of any counter. This will result in false
positives due to transitory network problems to be removed from the
history.
The buffer sizes of 1432 and 1232 are choosen to allow for a IPv4/IPv6
encapsulated UDP message to be sent without fragmentation at Ethernet
and IPv6 network mimimum MTU sizes.
Named also records the largest successful EDNS response size seen.
When talking to a new server named will send a EDNS query advertising
a 512 byte UDP buffer. This is the most conservative EDNS message
that can be sent. If this results in a response with TC=1 being
sent a larger EDNS buffer size will be used rather than a immediate
fallback to TCP.
If there are too many timeouts to EDNS queries without a successful EDNS
query and with successful plain DNS queries named will fallback to using
plain DNS when taking to a server. Named will periodically send a EDNS
query to see if the server now supports EDNS.
When talking to a server using EDNS named will choose a EDNS buffer size
based on the history of EDNS timeouts at various advertised sizes.
......@@ -419,7 +419,7 @@ parse_command_line(int argc, char *argv[]) {
isc_commandline_errprint = ISC_FALSE;
while ((ch = isc_commandline_parse(argc, argv,
"46c:C:d:E:fFgi:lm:n:N:p:P:"
"46c:C:d:D:E:fFgi:lm:n:N:p:P:"
"sS:t:T:U:u:vVx:")) != -1) {
switch (ch) {
case '4':
......@@ -455,6 +455,9 @@ parse_command_line(int argc, char *argv[]) {
ns_g_debuglevel = parse_int(isc_commandline_argument,
"debug level");
break;
case 'D':
/* Descriptive comment for 'ps'. */
break;
case 'E':
ns_g_engine = isc_commandline_argument;
break;
......
......@@ -62,6 +62,7 @@
<arg><option>-6</option></arg>
<arg><option>-c <replaceable class="parameter">config-file</replaceable></option></arg>
<arg><option>-d <replaceable class="parameter">debug-level</replaceable></option></arg>
<arg><option>-D <replaceable class="parameter">string</replaceable></option></arg>
<arg><option>-E <replaceable class="parameter">engine-name</replaceable></option></arg>
<arg><option>-f</option></arg>
<arg><option>-g</option></arg>
......@@ -149,6 +150,18 @@
</listitem>
</varlistentry>
<varlistentry>
<term>-D <replaceable class="parameter">string</replaceable></term>
<listitem>
<para>
Specifies a string that is used to identify a instance of
<command>named</command> in a process listing. The contents
of <replaceable class="parameter">string</replaceable> are
not examined.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>-E <replaceable class="parameter">engine-name</replaceable></term>
<listitem>
......
bash buildzones.sh < zones # creates setup, run, servers/* master/*
# named.conf
sudo sh setup # configure interfaces
sh run # setup
../named/named [-g] -c named.conf
sh tests.sh < zones
sudo sh teardown # teardown interfaces
The test server can controlled with
rndc -k rndc.key -s 127.127.0.0 -p 5300
#!/bin/bash
TOP=$( (cd ../../.. && pwd) )
addr=127.127.0.0
ttl=300
named=${TOP}/bin/named/named
keygen=${TOP}/bin/dnssec/dnssec-keygen
dsfromkey=${TOP}/bin/dnssec/dnssec-dsfromkey
nextaddr() {
OLDIF="$IFS"
IFS="${IFS}."
set $1
IFS="$OLDIFS"
_a=$1 _b=$2 _c=$3 _d=$4
_d=$(($_d + 1))
case $_d in
256) _c=$(($_c + 1)); _d=0;;
esac
case $_c in
256) _b=$(($_b + 1)); _c=0;;
esac
echo $_a.$_b.$_c.$_d
}
parent() {
OLDIF="$IFS"
IFS="${IFS}."
set $1
IFS="$OLDIFS"
shift
while [ $# -ne 0 ]
do
printf %s ${1}
shift
printf %s ${1:+.}
done
}
blackhole() {
echo 'options {'
echo ' port 5300;'
echo " listen-on { $1; };"
echo " query-source $1;"
echo " notify-source $1;"
echo " transfer-source $1;"
echo ' key-directory "keys";'
echo " recursion ${2:-no};"
echo ' pid-file "pids/'"${addr}"'.pid";'
echo ' blackhole { 127.127.0.0; };'
echo '};'
}
refuse() {
echo 'options {'
echo ' port 5300;'
echo " listen-on { $1; };"
echo " query-source $1;"
echo " notify-source $1;"
echo " transfer-source $1;"
echo ' key-directory "keys";'
echo " recursion ${2:-no};"
echo ' pid-file "pids/'"${addr}"'.pid";'
echo ' allow-query { !127.127.0.0; any; };'
echo '};'
}
options() {
echo 'options {'
echo ' port 5300;'
echo " listen-on { $1; };"
echo " query-source $1;"
echo " notify-source $1;"
echo " transfer-source $1;"
echo ' key-directory "keys";'
echo " recursion ${2:-no};"
echo ' pid-file "pids/'"${addr}"'.pid";'
echo '};'
}
controls() {
echo 'include "rndc.key";'
echo "controls { inet $addr port 9953 allow { any; } keys { "rndc-key"; }; };"
}
delay() {
_s=$1
OLDIF="$IFS"
IFS="${IFS}/"
set ${2:-.}
IFS="$OLDIFS"
case $1 in
.) _d=;;
*) _d=$1;;
esac
case $_s in
1) echo -T delay=${_d:-100};;
2) echo -T delay=${2:-50};;
3) echo -T delay=${3:-150};;
4) echo -T delay=${4:-250};;
5) echo -T delay=${5:-125};;
6) echo -T delay=${6:-25};;
7) echo -T delay=${7:-75};;
8) echo -T delay=${8:-125};;
9) echo -T delay=${9:-10};;
10) echo -T delay=${10:-40};;
11) echo -T delay=${11:-80};;
12) echo -T delay=${12:-90};;
*) echo -T delay=50;;
esac
}
trusted-keys () {
awk '$3 == "DNSKEY" {
b = ""; for (i=7; i <= NF; i++) { b = b $i; };
print "trusted-keys { \""$1"\"",$4,$5,$6,"\""b"\"; };" };'
}
signed-zone () {
echo "zone "'"'"${1:-.}"'"'" {"
echo " type master;"
echo " file "'"'"master/${2}.db"'"'";"
echo " auto-dnssec maintain;"
echo " allow-update { any; };"
echo "};"
}
unsigned-zone () {
echo "zone "'"'"${1:-.}"'"'" {"
echo " type master;"
echo " file "'"'"master/${2}.db"'"'";"
echo "};"
}
slave-zone () {
echo "zone "'"'"${zone:-.}"'"'" {"
echo " type slave;"
echo " masters { ${master}; };"
echo "};"
}
rm -rf servers master keys setup teardown run
mkdir -p servers
mkdir -p master
mkdir -p keys
echo "ifconfig lo0 $addr netmask 0xffffffff alias" >> setup
echo "ifconfig lo0 $addr -alias" >> teardown
controls $addr > named.conf
options $addr yes >> named.conf
echo 'zone "." { type hint; file "master/hint.db"; };' >> named.conf
while read zone servers nsfmt signed delay blackhole refuse flags
do
i=1
case "${zone}" in
.) file=root zone=;;
*) file="$zone";;
esac
if [ "${zone}" != "" ] ; then
p=$(parent $zone)
case "${p}" in
"") p=root;;
esac
else
p=hint
fi
#echo "zone='${zone}' parent='${p}'"
addr=$(nextaddr $addr)
ns=$(printf "$nsfmt" ${i} "${zone}")
d=$(delay $i ${delay:-.})
echo "${zone}. ${ttl} soa ${ns}. hostmaster.${zone}${zone:+.} 1 3600 1200 604800 1200" >> master/${file}.db
echo "${zone}. ${ttl} ns ${ns}." >> master/${file}.db
echo "${ns}. ${ttl} a ${addr}" >> master/${file}.db
echo "${zone}. ${ttl} ns ${ns}." >> master/${p}.db
echo "${ns}. ${ttl} a ${addr}" >> master/${p}.db
if [ $signed = "S" ]; then
kskkey=`${keygen} -K keys -f KSK ${zone:-.}`
zskkey=`${keygen} -K keys ${zone:-.}`
if [ "${zone}" != "" ] ; then
${dsfromkey} -T ${ttl} keys/${kskkey}.key >> master/${p}.db
else
trusted-keys < keys/${kskkey}.key >> named.conf
fi
fi
echo "ifconfig lo0 $addr netmask 0xffffffff alias" >> setup
echo "ifconfig lo0 $addr -alias" >> teardown
echo "${named} -D bigtest -c servers/${addr}.conf $d $flags" >> run
options ${addr} > servers/${addr}.conf
case ${signed} in
S) signed-zone ${zone:-.} ${file} >> servers/${addr}.conf;;
P) unsigned-zone ${zone:-.} ${file} >> servers/${addr}.conf;;
*) echo ${signed}; exit 1;;
esac
# slave servers
while [ $i -lt $servers ]
do
master=$addr
i=$(($i + 1))
ns=$(printf "$nsfmt" ${i} "${zone}")
d=$(delay $i ${delay:-.})
addr=$(nextaddr $addr)
echo "${zone}. ${ttl} ns ${ns}." >> master/${file}.db
echo "${ns}. ${ttl} a ${addr}" >> master/${file}.db
echo "${zone}. ${ttl} ns ${ns}." >> master/${p}.db
echo "${ns}. ${ttl} a ${addr}" >> master/${p}.db
echo "ifconfig lo0 $addr netmask 0xffffffff alias" >> setup
echo "ifconfig lo0 $addr -alias" >> teardown
echo "${named} -D bigtest -c servers/${addr}.conf $d $flags" >> run
if [ $i = ${refuse:-.} ]
then
refuse $addr > servers/${addr}.conf
elif [ $i = ${blackhole:-.} ]
then
blackhole $addr > servers/${addr}.conf
else
options $addr > servers/${addr}.conf
fi
slave-zone ${zone:-.} ${master} >> servers/${addr}.conf
done
if [ "${zone}" != "" ] ; then
echo "www.${zone}. ${ttl} a 127.0.0.1" >> master/${file}.db
echo "www.${zone}. ${ttl} aaaa ::1" >> master/${file}.db
echo "${zone}. ${ttl} mx 10 mail.${zone}." >> master/${file}.db
echo "mail.${zone}. ${ttl} a 127.0.0.1" >> master/${file}.db
echo "mail.${zone}. ${ttl} aaaa ::1" >> master/${file}.db
echo "*.big.${zone}. ${ttl} txt (" >> master/${file}.db
i=0
while [ $i -lt 150 ]
do
echo "1234567890" >> master/${file}.db
i=$(($i + 1))
done
echo ")" >> master/${file}.db
echo "*.medium.${zone}. ${ttl} txt (" >> master/${file}.db
i=0
while [ $i -lt 120 ]
do
echo "1234567890" >> master/${file}.db
i=$(($i + 1))
done
echo ")" >> master/${file}.db
echo "*.medium.${zone}. ${ttl} txt (" >> master/${file}.db
i=0
while [ $i -lt 120 ]
do
echo "1234567890" >> master/${file}.db
i=$(($i + 1))
done
echo ")" >> master/${file}.db
fi
done
key "rndc-key" {
algorithm hmac-md5;
secret "xxxxxxxxxxxxxxxxxxxxHg==";
};
#!/bin/bash
TOP=$( (cd ../../.. && pwd) )
dig=${TOP}/bin/dig/dig
cmd="${dig} -p 5300 @127.127.0.0 txt"
inner() {
zone=$1 i=$2 to=$3
x=$i
dout=dig$x.out
tout=time$x.out
while [ $i -lt $to ]
do
case $zone in
.) zone=;;
esac
(time -p $cmd $i.${sub}$zone > $dout ) 2> $tout
s=`sed -n '/real/s/[^0-9]*\([0-9]*\)\..*/\1/p' $tout`
case $s in
0);;
1) t1=`expr ${t1:-0} + 1`;;
2) t2=`expr ${t2:-0} + 1`;;
3) t3=`expr ${t3:-0} + 1`;;
*) echo $i `grep real $tout`;;
esac
grep "status: \(NXDOMAIN\|NOERROR\)" $dout > /dev/null || {
echo $cmd $i.${sub}$zone
cat $dout
}
i=`expr $i + 1`
done
if test ${t1:-0} -ne 0 -o ${t2:-0} -ne 0 -o ${t3:-0} -ne 0
then
echo "$x timeouts: t1=${t1:-0} t2=${t2:-0} t3=${t3:-0}"
fi
}
while read zone rest
do
for sub in "" medium. big.
do
case $zone in
.) echo doing ${sub:-.};;
*) echo doing $sub$zone;;
esac
( inner $zone 1 100) &
( inner $zone 101 200) &
( inner $zone 201 300) &
( inner $zone 301 400) &
( inner $zone 401 500) &
( inner $zone 501 600) &
( inner $zone 601 700) &
( inner $zone 701 800) &
( inner $zone 801 900) &
( inner $zone 901 1000) &
( inner $zone 1001 1100) &
( inner $zone 1101 1200) &
( inner $zone 1201 1300) &
( inner $zone 1301 1400) &
( inner $zone 1401 1500) &
( inner $zone 1501 1600) &
( inner $zone 1601 1700) &
wait
done
done
noedns-1.tld 1 ns%u.%s P . x x -T noedns
dropedns-1.tld 1 ns%u.%s P . x x -T dropedns
maxudp512-1.tld 1 ns%u.%s S . x x -T maxudp=512
maxudp1460-1.tld 1 ns%u.%s S . x x -T maxudp=1460
plain-1.tld 1 ns%u.%s S . x x
noedns-3.tld 3 ns%u.%s P . 2 x -T noedns
dropedns-3.tld 3 ns%u.%s P . 2 x -T dropedns
maxudp512-3.tld 3 ns%u.%s S . x x -T maxudp=512
maxudp1460-3.tld 3 ns%u.%s S . x x -T maxudp=1460
plain-3.tld 3 ns%u.%s S . x 3
noedns-5.tld 5 ns%u.%s P . 3 x -T noedns
dropedns-5.tld 5 ns%u.%s P . x x -T dropedns
maxudp512-5.tld 5 ns%u.%s S . x x -T maxudp=512
maxudp1460-5.tld 5 ns%u.%s S . x x -T maxudp=1460
400ms-1.tld 5 ns%u.%s S 400/400/400/400/400 2 x
plain-5.tld 5 ns%u.%s S . x x
tld 12 ns%u.%s S . 5 8
. 12 ns%u.root-servers.nil%s S . x x
......@@ -94,8 +94,8 @@ echo "I:reset and check that records are correctly cached initially"
ret=0
load_cache
dump_cache
nrecords=`grep flushtest.example ns2/named_dump.db | grep -v '^;' | wc -l`
[ $nrecords -eq 20 ] || ret=1
nrecords=`grep flushtest.example ns2/named_dump.db | grep -v '^;' | grep -w '\(TXT\|ANY\)'| wc -l`
[ $nrecords -eq 17 ] || { ret=1; echo "I: found $nrecords records expected 17"; }
if [ $ret != 0 ]; then echo "I:failed"; fi
status=`expr $status + $ret`
......@@ -180,8 +180,8 @@ status=`expr $status + $ret`
echo "I:check the number of cached records remaining"
ret=0
dump_cache
nrecords=`grep flushtest.example ns2/named_dump.db | grep -v '^;' | wc -l`
[ $nrecords -eq 19 ] || ret=1
nrecords=`grep flushtest.example ns2/named_dump.db | grep -v '^;' | grep -w '\(TXT\|ANY\)' | wc -l`
[ $nrecords -eq 17 ] || { ret=1; echo "I: found $nrecords records expected 17"; }
if [ $ret != 0 ]; then echo "I:failed"; fi
status=`expr $status + $ret`
......
......@@ -53,8 +53,8 @@ n=`expr $n + 1`
# Entry should exist
echo "I: check that 'check-names response warn;' works ($n)"
ret=0
$DIG $DIGOPTS yy_yy.ignore.example. @10.53.0.1 a > dig.out.ns1.test$n || ret=1
$DIG $DIGOPTS yy_yy.ignore.example. @10.53.0.2 a > dig.out.ns2.test$n || ret=1
$DIG $DIGOPTS +noauth yy_yy.ignore.example. @10.53.0.1 a > dig.out.ns1.test$n || ret=1
$DIG $DIGOPTS +noauth yy_yy.ignore.example. @10.53.0.2 a > dig.out.ns2.test$n || ret=1
$PERL ../digcomp.pl dig.out.ns1.test$n dig.out.ns2.test$n || ret=1
grep "check-names warning yy_yy.ignore.example/A/IN" ns2/named.run > /dev/null || ret=1
if [ $ret != 0 ]; then echo "I:failed"; fi
......
......@@ -76,6 +76,11 @@ israw1 () {
return $?
}
# strip NS and RRSIG NS from input
stripns () {
awk '($4 == "NS") || ($4 == "RRSIG" && $5 == "NS") { next} { print }' $1
}
# Check the example. domain
echo "I:checking that zone transfer worked ($n)"
......@@ -193,9 +198,13 @@ fi
echo "I:checking positive wildcard validation NSEC ($n)"
ret=0
$DIG $DIGOPTS a.wild.example. @10.53.0.2 a > dig.out.ns2.test$n || ret=1
$DIG $DIGOPTS a.wild.example. @10.53.0.3 a > dig.out.ns3.test$n || ret=1
$DIG $DIGOPTS a.wild.example. @10.53.0.4 a > dig.out.ns4.test$n || ret=1
$PERL ../digcomp.pl dig.out.ns2.test$n dig.out.ns4.test$n || ret=1
stripns dig.out.ns3.test$n > dig.out.ns3.stripped.test$n
stripns dig.out.ns4.test$n > dig.out.ns4.stripped.test$n
$PERL ../digcomp.pl dig.out.ns3.stripped.test$n dig.out.ns4.stripped.test$n || ret=1
grep "\*\.wild\.example\..*RRSIG NSEC" dig.out.ns4.test$n > /dev/null || ret=1
grep "\*\.wild\.example\..*NSEC z\.example" dig.out.ns4.test$n > /dev/null || ret=1
grep "flags:.*ad.*QUERY" dig.out.ns4.test$n > /dev/null || ret=1
grep "status: NOERROR" dig.out.ns4.test$n > /dev/null || ret=1
n=`expr $n + 1`
......@@ -235,7 +244,9 @@ echo "I:checking positive wildcard validation NSEC3 ($n)"
ret=0
$DIG $DIGOPTS a.wild.nsec3.example. @10.53.0.3 a > dig.out.ns3.test$n || ret=1
$DIG $DIGOPTS a.wild.nsec3.example. @10.53.0.4 a > dig.out.ns4.test$n || ret=1
$PERL ../digcomp.pl dig.out.ns3.test$n dig.out.ns4.test$n || ret=1
stripns dig.out.ns3.test$n > dig.out.ns3.stripped.test$n
stripns dig.out.ns4.test$n > dig.out.ns4.stripped.test$n
$PERL ../digcomp.pl dig.out.ns3.stripped.test$n dig.out.ns4.stripped.test$n || ret=1
grep "flags:.*ad.*QUERY" dig.out.ns4.test$n > /dev/null || ret=1
grep "status: NOERROR" dig.out.ns4.test$n > /dev/null || ret=1
n=`expr $n + 1`
......@@ -259,7 +270,9 @@ $DIG $DIGOPTS a.wild.optout.example. \
@10.53.0.3 a > dig.out.ns3.test$n || ret=1
$DIG $DIGOPTS a.wild.optout.example. \
@10.53.0.4 a > dig.out.ns4.test$n || ret=1
$PERL ../digcomp.pl dig.out.ns3.test$n dig.out.ns4.test$n || ret=1
stripns dig.out.ns3.test$n > dig.out.ns3.stripped.test$n
stripns dig.out.ns4.test$n > dig.out.ns4.stripped.test$n
$PERL ../digcomp.pl dig.out.ns3.stripped.test$n dig.out.ns4.stripped.test$n || ret=1
grep "flags:.*ad.*QUERY" dig.out.ns4.test$n > /dev/null || ret=1
grep "status: NOERROR" dig.out.ns4.test$n > /dev/null || ret=1
n=`expr $n + 1`
......
......@@ -27,56 +27,56 @@ status=0
echo "I:checking that a forward zone overrides global forwarders"
ret=0
$DIG txt.example1. txt @$hidden -p 5300 > dig.out.hidden || ret=1
$DIG txt.example1. txt @$f1 -p 5300 > dig.out.f1 || ret=1
$DIG +noadd +noauth txt.example1. txt @$hidden -p 5300 > dig.out.hidden || ret=1
$DIG +noadd +noauth txt.example1. txt @$f1 -p 5300 > dig.out.f1 || ret=1
$PERL ../digcomp.pl dig.out.hidden dig.out.f1 || ret=1
if [ $ret != 0 ]; then echo "I:failed"; fi
status=`expr $status + $ret`
echo "I:checking that a forward first zone no forwarders recurses"
ret=0
$DIG txt.example2. txt @$root -p 5300 > dig.out.root || ret=1
$DIG txt.example2. txt @$f1 -p 5300 > dig.out.f1 || ret=1
$DIG +noadd +noauth txt.example2. txt @$root -p 5300 > dig.out.root || ret=1
$DIG +noadd +noauth txt.example2. txt @$f1 -p 5300 > dig.out.f1 || ret=1
$PERL ../digcomp.pl dig.out.root dig.out.f1 || ret=1
if [ $ret != 0 ]; then echo "I:failed"; fi
status=`expr $status + $ret`
echo "I:checking that a forward only zone no forwarders fails"
ret=0
$DIG txt.example2. txt @$root -p 5300 > dig.out.root || ret=1
$DIG txt.example2. txt @$f1 -p 5300 > dig.out.f1 || ret=1
$DIG +noadd +noauth txt.example2. txt @$root -p 5300 > dig.out.root || ret=1
$DIG +noadd +noauth txt.example2. txt @$f1 -p 5300 > dig.out.f1 || ret=1
$PERL ../digcomp.pl dig.out.root dig.out.f1 || ret=1
if [ $ret != 0 ]; then echo "I:failed"; fi
status=`expr $status + $ret`
echo "I:checking that global forwarders work"
ret=0
$DIG txt.example4. txt @$hidden -p 5300 > dig.out.hidden || ret=1
$DIG txt.example4. txt @$f1 -p 5300 > dig.out.f1 || ret=1
$DIG +noadd +noauth txt.example4. txt @$hidden -p 5300 > dig.out.hidden || ret=1
$DIG +noadd +noauth txt.example4. txt @$f1 -p 5300 > dig.out.f1 || ret=1
$PERL ../digcomp.pl dig.out.hidden dig.out.f1 || ret=1
if [ $ret != 0 ]; then echo "I:failed"; fi
status=`expr $status + $ret`
echo "I:checking that a forward zone works"
ret=0
$DIG txt.example1. txt @$hidden -p 5300 > dig.out.hidden || ret=1
$DIG txt.example1. txt @$f2 -p 5300 > dig.out.f2 || ret=1
$DIG +noadd +noauth txt.example1. txt @$hidden -p 5300 > dig.out.hidden || ret=1
$DIG +noadd +noauth txt.example1. txt @$f2 -p 5300 > dig.out.f2 || ret=1
$PERL ../digcomp.pl dig.out.hidden dig.out.f2 || ret=1
if [ $ret != 0 ]; then echo "I:failed"; fi
status=`expr $status + $ret`
echo "I:checking that forwarding doesn't spontaneously happen"
ret=0
$DIG txt.example2. txt @$root -p 5300 > dig.out.root || ret=1
$DIG txt.example2. txt @$f2 -p 5300 > dig.out.f2 || ret=1
$DIG +noadd +noauth txt.example2. txt @$root -p 5300 > dig.out.root || ret=1
$DIG +noadd +noauth txt.example2. txt @$f2 -p 5300 > dig.out.f2 || ret=1
$PERL ../digcomp.pl dig.out.root dig.out.f2 || ret=1
if [ $ret != 0 ]; then echo "I:failed"; fi
status=`expr $status + $ret`
echo "I:checking that a forward zone with no specified policy works"
ret=0
$DIG txt.example3. txt @$hidden -p 5300 > dig.out.hidden || ret=1
$DIG txt.example3. txt @$f2 -p 5300 > dig.out.f2 || ret=1
$DIG +noadd +noauth txt.example3. txt @$hidden -p 5300 > dig.out.hidden || ret=1