Home | History | Annotate | Line # | Download | only in digdelv
      1 #!/bin/sh
      2 
      3 # Copyright (C) Internet Systems Consortium, Inc. ("ISC")
      4 #
      5 # SPDX-License-Identifier: MPL-2.0
      6 #
      7 # This Source Code Form is subject to the terms of the Mozilla Public
      8 # License, v. 2.0.  If a copy of the MPL was not distributed with this
      9 # file, you can obtain one at https://mozilla.org/MPL/2.0/.
     10 #
     11 # See the COPYRIGHT file distributed with this work for additional
     12 # information regarding copyright ownership.
     13 
     14 set -e
     15 
     16 # shellcheck source=conf.sh
     17 . ../conf.sh
     18 
     19 status=0
     20 n=0
     21 
     22 sendcmd() {
     23   send "${1}" "$EXTRAPORT1"
     24 }
     25 
     26 dig_with_opts() {
     27   "$DIG" -p "$PORT" "$@"
     28 }
     29 
     30 mdig_with_opts() {
     31   "$MDIG" -p "$PORT" "$@"
     32 }
     33 
     34 # Check if response in file $1 has the correct TTL range.
     35 # The response record must have RRtype $2 and class IN (CLASS1).
     36 # Maximum TTL is given by $3.  This works in most cases where TTL is
     37 # the second word on the line.  TTL position can be adjusted with
     38 # setting the position $4, but that requires updating this function.
     39 check_ttl_range() {
     40   file=$1
     41   pos=$4
     42 
     43   case "$pos" in
     44     "3")
     45       {
     46         awk -v rrtype="$2" -v ttl="$3" '($4 == "IN" || $4 == "CLASS1" ) && $5 == rrtype { if ($3 <= ttl) { ok=1 } } END { exit(ok?0:1) }' <$file
     47         result=$?
     48       } || true
     49       ;;
     50     *)
     51       {
     52         awk -v rrtype="$2" -v ttl="$3" '($3 == "IN" || $3 == "CLASS1" ) && $4 == rrtype { if ($2 <= ttl) { ok=1 } } END { exit(ok?0:1) }' <$file
     53         result=$?
     54       } || true
     55       ;;
     56   esac
     57 
     58   [ $result -eq 0 ] || echo_i "ttl check failed"
     59   return $result
     60 }
     61 
     62 # use delv insecure mode by default, as we're mostly not testing dnssec
     63 delv_with_opts() {
     64   "$DELV" +noroot -p "$PORT" "$@"
     65 }
     66 
     67 KEYID="$(cat ns2/keyid)"
     68 KEYDATA="$(sed <ns2/keydata -e 's/+/[+]/g')"
     69 NOSPLIT="$(sed <ns2/keydata -e 's/+/[+]/g' -e 's/ //g')"
     70 
     71 HAS_PYYAML=0
     72 $PYTHON -c "import yaml" 2>/dev/null && HAS_PYYAML=1
     73 
     74 #
     75 # test whether ans7/ans.pl will be able to send a UPDATE response.
     76 # if it can't, we will log that below.
     77 #
     78 if "$PERL" -e 'use Net::DNS; use Net::DNS::Packet; my $p = new Net::DNS::Packet; $p->header->opcode(5);' >/dev/null 2>&1; then
     79   checkupdate=1
     80 else
     81   checkupdate=0
     82 fi
     83 
     84 if [ -x "$NSLOOKUP" -a $checkupdate -eq 1 ]; then
     85 
     86   n=$((n + 1))
     87   echo_i "check nslookup handles UPDATE response ($n)"
     88   ret=0
     89   "$NSLOOKUP" -q=CNAME -timeout=1 "-port=$PORT" foo.bar 10.53.0.7 >nslookup.out.test$n 2>&1 && ret=1
     90   grep "Opcode mismatch" nslookup.out.test$n >/dev/null || ret=1
     91   if [ $ret -ne 0 ]; then echo_i "failed"; fi
     92   status=$((status + ret))
     93 
     94 fi
     95 
     96 if [ -x "$HOST" -a $checkupdate -eq 1 ]; then
     97 
     98   n=$((n + 1))
     99   echo_i "check host handles UPDATE response ($n)"
    100   ret=0
    101   "$HOST" -W 1 -t CNAME -p $PORT foo.bar 10.53.0.7 >host.out.test$n 2>&1 && ret=1
    102   grep "Opcode mismatch" host.out.test$n >/dev/null || ret=1
    103   if [ $ret -ne 0 ]; then echo_i "failed"; fi
    104   status=$((status + ret))
    105 
    106 fi
    107 
    108 if [ -x "$NSUPDATE" -a $checkupdate -eq 1 ]; then
    109 
    110   n=$((n + 1))
    111   echo_i "check nsupdate handles UPDATE response to QUERY ($n)"
    112   ret=0
    113   res=0
    114   $NSUPDATE <<EOF >nsupdate.out.test$n 2>&1 || res=$?
    115 server 10.53.0.7 ${PORT}
    116 add x.example.com 300 in a 1.2.3.4
    117 send
    118 EOF
    119   test $res -eq 1 || ret=1
    120   grep "invalid OPCODE in response to SOA query" nsupdate.out.test$n >/dev/null || ret=1
    121   if [ $ret -ne 0 ]; then echo_i "failed"; fi
    122   status=$((status + ret))
    123 
    124 fi
    125 
    126 if [ -x "$DIG" ]; then
    127 
    128   if [ $checkupdate -eq 1 ]; then
    129 
    130     n=$((n + 1))
    131     echo_i "check dig handles UPDATE response ($n)"
    132     ret=0
    133     dig_with_opts @10.53.0.7 +tries=1 +timeout=1 cname foo.bar >dig.out.test$n 2>&1 && ret=1
    134     grep "Opcode mismatch" dig.out.test$n >/dev/null || ret=1
    135     if [ $ret -ne 0 ]; then echo_i "failed"; fi
    136     status=$((status + ret))
    137   else
    138     echo_i "Skipped UPDATE handling test"
    139   fi
    140 
    141   n=$((n + 1))
    142   echo_i "checking dig short form works ($n)"
    143   ret=0
    144   dig_with_opts @10.53.0.3 +short a a.example >dig.out.test$n || ret=1
    145   test "$(wc -l <dig.out.test$n)" -eq 1 || ret=1
    146   if [ $ret -ne 0 ]; then echo_i "failed"; fi
    147   status=$((status + ret))
    148 
    149   n=$((n + 1))
    150   echo_i "checking dig split width works ($n)"
    151   ret=0
    152   dig_with_opts @10.53.0.3 +split=4 -t sshfp foo.example >dig.out.test$n || ret=1
    153   grep " 9ABC DEF6 7890 " <dig.out.test$n >/dev/null || ret=1
    154   check_ttl_range dig.out.test$n "SSHFP" 300 || ret=1
    155   if [ $ret -ne 0 ]; then echo_i "failed"; fi
    156   status=$((status + ret))
    157 
    158   n=$((n + 1))
    159   echo_i "checking dig +unknownformat works ($n)"
    160   ret=0
    161   dig_with_opts @10.53.0.3 +unknownformat a a.example >dig.out.test$n || ret=1
    162   grep "CLASS1[ 	][ 	]*TYPE1[ 	][ 	]*\\\\# 4 0A000001" <dig.out.test$n >/dev/null || ret=1
    163   check_ttl_range dig.out.test$n "TYPE1" 300 || ret=1
    164   if [ $ret -ne 0 ]; then echo_i "failed"; fi
    165   status=$((status + ret))
    166 
    167   n=$((n + 1))
    168   echo_i "checking dig with reverse lookup works ($n)"
    169   ret=0
    170   dig_with_opts @10.53.0.3 -x 127.0.0.1 >dig.out.test$n 2>&1 || ret=1
    171   # doesn't matter if has answer
    172   grep -i "127\\.in-addr\\.arpa\\." <dig.out.test$n >/dev/null || ret=1
    173   check_ttl_range dig.out.test$n "SOA" 86400 || ret=1
    174   if [ $ret -ne 0 ]; then echo_i "failed"; fi
    175   status=$((status + ret))
    176 
    177   n=$((n + 1))
    178   echo_i "checking dig over TCP works ($n)"
    179   ret=0
    180   dig_with_opts +tcp @10.53.0.3 a a.example >dig.out.test$n || ret=1
    181   grep "10\\.0\\.0\\.1$" <dig.out.test$n >/dev/null || ret=1
    182   check_ttl_range dig.out.test$n "A" 300 || ret=1
    183   if [ $ret -ne 0 ]; then echo_i "failed"; fi
    184   status=$((status + ret))
    185 
    186   n=$((n + 1))
    187   echo_i "checking dig +multi +norrcomments works for DNSKEY (when default is rrcomments)($n)"
    188   ret=0
    189   dig_with_opts +tcp @10.53.0.3 +multi +norrcomments -t DNSKEY example >dig.out.test$n || ret=1
    190   grep "; ZSK; alg = $DEFAULT_ALGORITHM ; key id = $KEYID" dig.out.test$n >/dev/null && ret=1
    191   check_ttl_range dig.out.test$n "DNSKEY" 300 || ret=1
    192   if [ $ret -ne 0 ]; then echo_i "failed"; fi
    193   status=$((status + ret))
    194 
    195   n=$((n + 1))
    196   echo_i "checking dig +multi +norrcomments works for SOA (when default is rrcomments)($n)"
    197   ret=0
    198   dig_with_opts +tcp @10.53.0.3 +multi +norrcomments -t SOA example >dig.out.test$n || ret=1
    199   grep "; serial" dig.out.test$n >/dev/null && ret=1
    200   check_ttl_range dig.out.test$n "SOA" 300 || ret=1
    201   if [ $ret -ne 0 ]; then echo_i "failed"; fi
    202   status=$((status + ret))
    203 
    204   n=$((n + 1))
    205   echo_i "checking dig +rrcomments works for DNSKEY($n)"
    206   ret=0
    207   dig_with_opts +tcp @10.53.0.3 +rrcomments DNSKEY example >dig.out.test$n || ret=1
    208   grep "; ZSK; alg = $DEFAULT_ALGORITHM ; key id = $KEYID" <dig.out.test$n >/dev/null || ret=1
    209   check_ttl_range dig.out.test$n "DNSKEY" 300 || ret=1
    210   if [ $ret -ne 0 ]; then echo_i "failed"; fi
    211   status=$((status + ret))
    212 
    213   n=$((n + 1))
    214   echo_i "checking dig +short +rrcomments works for DNSKEY ($n)"
    215   ret=0
    216   dig_with_opts +tcp @10.53.0.3 +short +rrcomments DNSKEY example >dig.out.test$n || ret=1
    217   grep "; ZSK; alg = $DEFAULT_ALGORITHM ; key id = $KEYID" <dig.out.test$n >/dev/null || ret=1
    218   if [ $ret -ne 0 ]; then echo_i "failed"; fi
    219   status=$((status + ret))
    220 
    221   n=$((n + 1))
    222   echo_i "checking dig +short +nosplit works($n)"
    223   ret=0
    224   dig_with_opts +tcp @10.53.0.3 +short +nosplit DNSKEY example >dig.out.test$n || ret=1
    225   grep "$NOSPLIT" <dig.out.test$n >/dev/null || ret=1
    226   if [ $ret -ne 0 ]; then echo_i "failed"; fi
    227   status=$((status + ret))
    228 
    229   n=$((n + 1))
    230   echo_i "checking dig +short +rrcomments works($n)"
    231   ret=0
    232   dig_with_opts +tcp @10.53.0.3 +short +rrcomments DNSKEY example >dig.out.test$n || ret=1
    233   grep -q "$KEYDATA  ; ZSK; alg = $DEFAULT_ALGORITHM ; key id = $KEYID\$" <dig.out.test$n || ret=1
    234   if [ $ret -ne 0 ]; then echo_i "failed"; fi
    235   status=$((status + ret))
    236 
    237   n=$((n + 1))
    238   echo_i "checking dig multi flag is local($n)"
    239   ret=0
    240   dig_with_opts +tcp @10.53.0.3 -t DNSKEY example +nomulti example +nomulti >dig.out.nn.$n || ret=1
    241   dig_with_opts +tcp @10.53.0.3 -t DNSKEY example +multi example +nomulti >dig.out.mn.$n || ret=1
    242   dig_with_opts +tcp @10.53.0.3 -t DNSKEY example +nomulti example +multi >dig.out.nm.$n || ret=1
    243   dig_with_opts +tcp @10.53.0.3 -t DNSKEY example +multi example +multi >dig.out.mm.$n || ret=1
    244   lcnn=$(wc -l <dig.out.nn.$n)
    245   lcmn=$(wc -l <dig.out.mn.$n)
    246   lcnm=$(wc -l <dig.out.nm.$n)
    247   lcmm=$(wc -l <dig.out.mm.$n)
    248   test "$lcmm" -ge "$lcnm" || ret=1
    249   test "$lcmm" -ge "$lcmn" || ret=1
    250   test "$lcnm" -ge "$lcnn" || ret=1
    251   test "$lcmn" -ge "$lcnn" || ret=1
    252   check_ttl_range dig.out.nn.$n "DNSKEY" 300 || ret=1
    253   check_ttl_range dig.out.mn.$n "DNSKEY" 300 || ret=1
    254   check_ttl_range dig.out.nm.$n "DNSKEY" 300 || ret=1
    255   check_ttl_range dig.out.mm.$n "DNSKEY" 300 || ret=1
    256   if [ $ret -ne 0 ]; then echo_i "failed"; fi
    257   status=$((status + ret))
    258 
    259   n=$((n + 1))
    260   echo_i "checking dig +noheader-only works ($n)"
    261   ret=0
    262   dig_with_opts +tcp @10.53.0.3 +noheader-only A example >dig.out.test$n || ret=1
    263   grep "Got answer:" <dig.out.test$n >/dev/null || ret=1
    264   check_ttl_range dig.out.test$n "SOA" 300 || ret=1
    265   if [ $ret -ne 0 ]; then echo_i "failed"; fi
    266   status=$((status + ret))
    267 
    268   n=$((n + 1))
    269   echo_i "checking dig +short +rrcomments works($n)"
    270   ret=0
    271   dig_with_opts +tcp @10.53.0.3 +short +rrcomments DNSKEY example >dig.out.test$n || ret=1
    272   grep -q "$KEYDATA  ; ZSK; alg = $DEFAULT_ALGORITHM ; key id = $KEYID\$" <dig.out.test$n || ret=1
    273   if [ $ret -ne 0 ]; then echo_i "failed"; fi
    274   status=$((status + ret))
    275 
    276   n=$((n + 1))
    277   echo_i "checking dig +header-only works ($n)"
    278   ret=0
    279   dig_with_opts +tcp @10.53.0.3 +header-only example >dig.out.test$n || ret=1
    280   grep "^;; flags: qr rd; QUERY: 0, ANSWER: 0," <dig.out.test$n >/dev/null || ret=1
    281   grep "^;; QUESTION SECTION:" <dig.out.test$n >/dev/null && ret=1
    282   if [ $ret -ne 0 ]; then echo_i "failed"; fi
    283   status=$((status + ret))
    284 
    285   n=$((n + 1))
    286   echo_i "checking dig +coflag works ($n)"
    287   ret=0
    288   dig_with_opts +tcp @10.53.0.3 +coflag +qr example >dig.out.test$n || ret=1
    289   grep "^; EDNS: version: 0, flags: co;" <dig.out.test$n >/dev/null || ret=1
    290   check_ttl_range dig.out.test$n "SOA" 300 || ret=1
    291   if [ $ret -ne 0 ]; then echo_i "failed"; fi
    292   status=$((status + ret))
    293 
    294   if [ $HAS_PYYAML -ne 0 ]; then
    295     n=$((n + 1))
    296     echo_i "checking dig +coflag +yaml works ($n)"
    297     ret=0
    298     dig_with_opts +yaml +tcp @10.53.0.3 +coflag +qr example >dig.out.test$n || ret=1
    299     $PYTHON yamlget.py dig.out.test$n 0 message query_message_data OPT_PSEUDOSECTION EDNS flags >yamlget.out.test$n 2>&1 || ret=1
    300     read -r value <yamlget.out.test$n
    301     [ "$value" = "co" ] || ret=1
    302     if [ $ret -ne 0 ]; then echo_i "failed"; fi
    303     status=$((status + ret))
    304   fi
    305 
    306   n=$((n + 1))
    307   echo_i "checking dig +raflag works ($n)"
    308   ret=0
    309   dig_with_opts +tcp @10.53.0.3 +raflag +qr example >dig.out.test$n || ret=1
    310   grep "^;; flags: rd ra ad; QUERY: 1, ANSWER: 0," <dig.out.test$n >/dev/null || ret=1
    311   grep "^;; flags: qr rd ra; QUERY: 1, ANSWER: 0," <dig.out.test$n >/dev/null || ret=1
    312   check_ttl_range dig.out.test$n "SOA" 300 || ret=1
    313   if [ $ret -ne 0 ]; then echo_i "failed"; fi
    314   status=$((status + ret))
    315 
    316   n=$((n + 1))
    317   echo_i "checking dig +tcflag works ($n)"
    318   ret=0
    319   dig_with_opts +tcp @10.53.0.3 +tcflag +qr example >dig.out.test$n || ret=1
    320   grep "^;; flags: tc rd ad; QUERY: 1, ANSWER: 0" <dig.out.test$n >/dev/null || ret=1
    321   grep "^;; flags: qr rd ra; QUERY: 1, ANSWER: 0," <dig.out.test$n >/dev/null || ret=1
    322   check_ttl_range dig.out.test$n "SOA" 300 || ret=1
    323   if [ $ret -ne 0 ]; then echo_i "failed"; fi
    324   status=$((status + ret))
    325 
    326   n=$((n + 1))
    327   echo_i "checking dig +header-only works (with class and type set) ($n)"
    328   ret=0
    329   dig_with_opts +tcp @10.53.0.3 +header-only -c IN -t A example >dig.out.test$n || ret=1
    330   grep "^;; flags: qr rd; QUERY: 0, ANSWER: 0," <dig.out.test$n >/dev/null || ret=1
    331   grep "^;; QUESTION SECTION:" <dig.out.test$n >/dev/null && ret=1
    332   if [ $ret -ne 0 ]; then echo_i "failed"; fi
    333   status=$((status + ret))
    334 
    335   n=$((n + 1))
    336   echo_i "checking dig +zflag works, and that BIND properly ignores it ($n)"
    337   ret=0
    338   dig_with_opts +tcp @10.53.0.3 +zflag +qr A example >dig.out.test$n || ret=1
    339   sed -n '/Sending:/,/Got answer:/p' dig.out.test$n | grep "^;; flags: rd ad; MBZ: 0x4;" >/dev/null || ret=1
    340   sed -n '/Got answer:/,/AUTHORITY SECTION:/p' dig.out.test$n | grep "^;; flags: qr rd ra; QUERY: 1" >/dev/null || ret=1
    341   check_ttl_range dig.out.test$n "SOA" 300 || ret=1
    342   if [ $ret -ne 0 ]; then echo_i "failed"; fi
    343   status=$((status + ret))
    344 
    345   n=$((n + 1))
    346   echo_i "checking dig +qr +ednsopt=08 does not cause an INSIST failure ($n)"
    347   ret=0
    348   dig_with_opts @10.53.0.3 +ednsopt=08 +qr a a.example >dig.out.test$n || ret=1
    349   grep "INSIST" <dig.out.test$n >/dev/null && ret=1
    350   grep "FORMERR" <dig.out.test$n >/dev/null || ret=1
    351   if [ $ret -ne 0 ]; then echo_i "failed"; fi
    352   status=$((status + ret))
    353 
    354   n=$((n + 1))
    355   echo_i "checking dig +ttlunits works ($n)"
    356   ret=0
    357   dig_with_opts +tcp @10.53.0.2 +ttlunits A weeks.example >dig.out.test$n || ret=1
    358   grep "^weeks.example.		3w" <dig.out.test$n >/dev/null || ret=1
    359   dig_with_opts +tcp @10.53.0.2 +ttlunits A days.example >dig.out.test$n || ret=1
    360   grep "^days.example.		3d" <dig.out.test$n >/dev/null || ret=1
    361   dig_with_opts +tcp @10.53.0.2 +ttlunits A hours.example >dig.out.test$n || ret=1
    362   grep "^hours.example.		3h" <dig.out.test$n >/dev/null || ret=1
    363   dig_with_opts +tcp @10.53.0.2 +ttlunits A minutes.example >dig.out.test$n || ret=1
    364   grep "^minutes.example.	45m" <dig.out.test$n >/dev/null || ret=1
    365   dig_with_opts +tcp @10.53.0.2 +ttlunits A seconds.example >dig.out.test$n || ret=1
    366   grep "^seconds.example.	45s" <dig.out.test$n >/dev/null || ret=1
    367   if [ $ret -ne 0 ]; then echo_i "failed"; fi
    368   status=$((status + ret))
    369 
    370   n=$((n + 1))
    371   echo_i "checking dig respects precedence of options with +ttlunits ($n)"
    372   ret=0
    373   dig_with_opts +tcp @10.53.0.2 +ttlunits +nottlid A weeks.example >dig.out.test$n || ret=1
    374   grep "^weeks.example.		IN" <dig.out.test$n >/dev/null || ret=1
    375   dig_with_opts +tcp @10.53.0.2 +nottlid +ttlunits A weeks.example >dig.out.test$n || ret=1
    376   grep "^weeks.example.		3w" <dig.out.test$n >/dev/null || ret=1
    377   dig_with_opts +tcp @10.53.0.2 +nottlid +nottlunits A weeks.example >dig.out.test$n || ret=1
    378   grep "^weeks.example.		1814400" <dig.out.test$n >/dev/null || ret=1
    379   if [ $ret -ne 0 ]; then echo_i "failed"; fi
    380   status=$((status + ret))
    381 
    382   n=$((n + 1))
    383   echo_i "checking dig preserves origin on TCP retries ($n)"
    384   ret=0
    385   # Ask ans4 to still accept TCP connections, but not respond to queries
    386   echo "//" | sendcmd 10.53.0.4
    387   dig_with_opts -d +tcp @10.53.0.4 +retry=1 +time=1 +domain=bar foo >dig.out.test$n 2>&1 && ret=1
    388   test "$(grep -c "trying origin bar" dig.out.test$n)" -eq 2 || ret=1
    389   grep "using root origin" <dig.out.test$n >/dev/null && ret=1
    390   if [ $ret -ne 0 ]; then echo_i "failed"; fi
    391   status=$((status + ret))
    392 
    393   n=$((n + 1))
    394   echo_i "checking dig -6 -4 ($n)"
    395   ret=0
    396   dig_with_opts +tcp @10.53.0.2 -4 -6 A a.example >dig.out.test$n 2>&1 && ret=1
    397   grep "only one of -4 and -6 allowed" <dig.out.test$n >/dev/null || ret=1
    398   if [ $ret -ne 0 ]; then echo_i "failed"; fi
    399   status=$((status + ret))
    400 
    401   n=$((n + 1))
    402   echo_i "checking dig @IPv6addr -4 A a.example ($n)"
    403   if testsock6 fd92:7065:b8e:ffff::2 2>/dev/null; then
    404     ret=0
    405     dig_with_opts +tcp @fd92:7065:b8e:ffff::2 -4 A a.example >dig.out.test$n 2>&1 && ret=1
    406     grep "address family not supported" <dig.out.test$n >/dev/null || ret=1
    407     if [ $ret -ne 0 ]; then echo_i "failed"; fi
    408     status=$((status + ret))
    409   else
    410     echo_i "IPv6 unavailable; skipping"
    411   fi
    412 
    413   n=$((n + 1))
    414   echo_i "checking dig +tcp @IPv4addr -6 A a.example ($n)"
    415   if testsock6 fd92:7065:b8e:ffff::2 2>/dev/null; then
    416     ret=0
    417     dig_with_opts +tcp @10.53.0.2 -6 A a.example >dig.out.test$n 2>&1 || ret=1
    418     grep "SERVER: ::ffff:10.53.0.2#$PORT" <dig.out.test$n >/dev/null && ret=1
    419     if [ $ret -ne 0 ]; then echo_i "failed"; fi
    420     status=$((status + ret))
    421   else
    422     echo_i "IPv6 unavailable; skipping"
    423   fi
    424   n=$((n + 1))
    425 
    426   echo_i "checking dig +notcp @IPv4addr -6 A a.example ($n)"
    427   if testsock6 fd92:7065:b8e:ffff::2 2>/dev/null; then
    428     ret=0
    429     dig_with_opts +notcp @10.53.0.2 -6 A a.example >dig.out.test$n 2>&1 || ret=1
    430     grep "SERVER: ::ffff:10.53.0.2#$PORT" <dig.out.test$n >/dev/null && ret=1
    431     if [ $ret -ne 0 ]; then echo_i "failed"; fi
    432     status=$((status + ret))
    433   else
    434     echo_i "IPv6 unavailable; skipping"
    435   fi
    436 
    437   n=$((n + 1))
    438   echo_i "checking dig +subnet ($n)"
    439   ret=0
    440   dig_with_opts +tcp @10.53.0.2 +subnet=127.0.0.1 A a.example >dig.out.test$n 2>&1 || ret=1
    441   grep "CLIENT-SUBNET: 127.0.0.1/32/0" <dig.out.test$n >/dev/null || ret=1
    442   check_ttl_range dig.out.test$n "A" 300 || ret=1
    443   if [ $ret -ne 0 ]; then echo_i "failed"; fi
    444   status=$((status + ret))
    445 
    446   n=$((n + 1))
    447   echo_i "checking dig +subnet +subnet ($n)"
    448   ret=0
    449   dig_with_opts +tcp @10.53.0.2 +subnet=127.0.0.0 +subnet=127.0.0.1 A a.example >dig.out.test$n 2>&1 || ret=1
    450   grep "CLIENT-SUBNET: 127.0.0.1/32/0" <dig.out.test$n >/dev/null || ret=1
    451   check_ttl_range dig.out.test$n "A" 300 || ret=1
    452   if [ $ret -ne 0 ]; then echo_i "failed"; fi
    453   status=$((status + ret))
    454 
    455   n=$((n + 1))
    456   echo_i "checking dig +subnet with various prefix lengths ($n)"
    457   ret=0
    458   for i in 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24; do
    459     dig_with_opts +tcp @10.53.0.2 +subnet=255.255.255.255/$i A a.example >dig.out.$i.test$n 2>&1 || ret=1
    460     case $i in
    461       1 | 9 | 17) octet=128 ;;
    462       2 | 10 | 18) octet=192 ;;
    463       3 | 11 | 19) octet=224 ;;
    464       4 | 12 | 20) octet=240 ;;
    465       5 | 13 | 21) octet=248 ;;
    466       6 | 14 | 22) octet=252 ;;
    467       7 | 15 | 23) octet=254 ;;
    468       8 | 16 | 24) octet=255 ;;
    469     esac
    470     case $i in
    471       1 | 2 | 3 | 4 | 5 | 6 | 7 | 8) addr="${octet}.0.0.0" ;;
    472       9 | 10 | 11 | 12 | 13 | 14 | 15 | 16) addr="255.${octet}.0.0" ;;
    473       17 | 18 | 19 | 20 | 21 | 22 | 23 | 24) addr="255.255.${octet}.0" ;;
    474     esac
    475     grep "FORMERR" <dig.out.$i.test$n >/dev/null && ret=1
    476     grep "CLIENT-SUBNET: $addr/$i/0" <dig.out.$i.test$n >/dev/null || ret=1
    477     check_ttl_range dig.out.$i.test$n "A" 300 || ret=1
    478   done
    479   if [ $ret -ne 0 ]; then echo_i "failed"; fi
    480   status=$((status + ret))
    481 
    482   n=$((n + 1))
    483   echo_i "checking dig +subnet=0/0 ($n)"
    484   ret=0
    485   dig_with_opts +tcp @10.53.0.2 +subnet=0/0 A a.example >dig.out.test$n 2>&1 || ret=1
    486   grep "status: NOERROR" <dig.out.test$n >/dev/null || ret=1
    487   grep "CLIENT-SUBNET: 0.0.0.0/0/0" <dig.out.test$n >/dev/null || ret=1
    488   grep "10.0.0.1" <dig.out.test$n >/dev/null || ret=1
    489   check_ttl_range dig.out.test$n "A" 300 || ret=1
    490   if [ $ret -ne 0 ]; then echo_i "failed"; fi
    491   status=$((status + ret))
    492 
    493   n=$((n + 1))
    494   echo_i "checking dig +subnet=0 ($n)"
    495   ret=0
    496   dig_with_opts +tcp @10.53.0.2 +subnet=0 A a.example >dig.out.test$n 2>&1 || ret=1
    497   grep "status: NOERROR" <dig.out.test$n >/dev/null || ret=1
    498   grep "CLIENT-SUBNET: 0.0.0.0/0/0" <dig.out.test$n >/dev/null || ret=1
    499   grep "10.0.0.1" <dig.out.test$n >/dev/null || ret=1
    500   check_ttl_range dig.out.test$n "A" 300 || ret=1
    501   if [ $ret -ne 0 ]; then echo_i "failed"; fi
    502   status=$((status + ret))
    503 
    504   if [ $HAS_PYYAML -ne 0 ]; then
    505     n=$((n + 1))
    506     echo_i "checking dig +subnet=0 +yaml ($n)"
    507     ret=0
    508     dig_with_opts +yaml +tcp @10.53.0.2 +subnet=0 A a.example >dig.out.test$n 2>&1 || ret=1
    509     $PYTHON yamlget.py dig.out.test$n 0 message response_message_data OPT_PSEUDOSECTION EDNS CLIENT-SUBNET >yamlget.out.test$n 2>&1 || ret=1
    510     read -r value <yamlget.out.test$n
    511     [ "$value" = "0.0.0.0/0/0" ] || ret=1
    512     if [ $ret -ne 0 ]; then echo_i "failed"; fi
    513     status=$((status + ret))
    514   fi
    515 
    516   n=$((n + 1))
    517   echo_i "checking dig +subnet=::/0 ($n)"
    518   ret=0
    519   dig_with_opts +tcp @10.53.0.2 +subnet=::/0 A a.example >dig.out.test$n 2>&1 || ret=1
    520   grep "status: NOERROR" <dig.out.test$n >/dev/null || ret=1
    521   grep "CLIENT-SUBNET: ::/0/0" <dig.out.test$n >/dev/null || ret=1
    522   grep "10.0.0.1" <dig.out.test$n >/dev/null || ret=1
    523   check_ttl_range dig.out.test$n "A" 300 || ret=1
    524   if [ $ret -ne 0 ]; then echo_i "failed"; fi
    525   status=$((status + ret))
    526 
    527   if [ $HAS_PYYAML -ne 0 ]; then
    528     n=$((n + 1))
    529     echo_i "checking dig +subnet=::/0 +yaml ($n)"
    530     ret=0
    531     dig_with_opts +yaml +tcp @10.53.0.2 +subnet=::/0 A a.example >dig.out.test$n 2>&1 || ret=1
    532     $PYTHON yamlget.py dig.out.test$n 0 message response_message_data OPT_PSEUDOSECTION EDNS CLIENT-SUBNET >yamlget.out.test$n 2>&1 || ret=1
    533     read -r value <yamlget.out.test$n
    534     [ "$value" = "::/0/0" ] || ret=1
    535     if [ $ret -ne 0 ]; then echo_i "failed"; fi
    536     status=$((status + ret))
    537 
    538     n=$((n + 1))
    539     echo_i "checking dig +subnet=dead::/16 +yaml ($n)"
    540     ret=0
    541     dig_with_opts +yaml +tcp @10.53.0.2 +qr +subnet=dead::/16 A a.example >dig.out.test$n 2>&1 || ret=1
    542     $PYTHON yamlget.py dig.out.test$n 0 message query_message_data OPT_PSEUDOSECTION EDNS CLIENT-SUBNET >yamlget.out.test$n 2>&1 || ret=1
    543     read -r value <yamlget.out.test$n
    544     [ "$value" = "dead::/16/0" ] || ret=1
    545     if [ $ret -ne 0 ]; then echo_i "failed"; fi
    546     status=$((status + ret))
    547   fi
    548 
    549   n=$((n + 1))
    550   echo_i "checking dig +ednsopt=8:00000000 (family=0, source=0, scope=0) ($n)"
    551   ret=0
    552   dig_with_opts +tcp @10.53.0.2 +ednsopt=8:00000000 A a.example >dig.out.test$n 2>&1 || ret=1
    553   grep "status: NOERROR" <dig.out.test$n >/dev/null || ret=1
    554   grep "CLIENT-SUBNET: 0/0/0" <dig.out.test$n >/dev/null || ret=1
    555   grep "10.0.0.1" <dig.out.test$n >/dev/null || ret=1
    556   check_ttl_range dig.out.test$n "A" 300 || ret=1
    557   if [ $ret -ne 0 ]; then echo_i "failed"; fi
    558   status=$((status + ret))
    559 
    560   n=$((n + 1))
    561   echo_i "checking dig +ednsopt=8:00030000 (family=3, source=0, scope=0) ($n)"
    562   ret=0
    563   dig_with_opts +qr +tcp @10.53.0.2 +ednsopt=8:00030000 A a.example >dig.out.test$n 2>&1 || ret=1
    564   grep "status: FORMERR" <dig.out.test$n >/dev/null || ret=1
    565   grep "CLIENT-SUBNET: 00 03 00 00" <dig.out.test$n >/dev/null || ret=1
    566   test "$(grep -c "CLIENT-SUBNET: 00 03 00 00" dig.out.test$n)" -eq 1 || ret=1
    567   if [ $ret -ne 0 ]; then echo_i "failed"; fi
    568   status=$((status + ret))
    569 
    570   n=$((n + 1))
    571   echo_i "checking dig +subnet with prefix lengths between byte boundaries ($n)"
    572   ret=0
    573   for p in 9 10 11 12 13 14 15; do
    574     dig_with_opts +tcp @10.53.0.2 +subnet=10.53/$p A a.example >dig.out.test.$p.$n 2>&1 || ret=1
    575     grep "FORMERR" <dig.out.test.$p.$n >/dev/null && ret=1
    576     grep "CLIENT-SUBNET.*/$p/0" <dig.out.test.$p.$n >/dev/null || ret=1
    577     check_ttl_range dig.out.test.$p.$n "A" 300 || ret=1
    578   done
    579   if [ $ret -ne 0 ]; then echo_i "failed"; fi
    580   status=$((status + ret))
    581 
    582   n=$((n + 1))
    583   echo_i "checking dig +sp works as an abbreviated form of split ($n)"
    584   ret=0
    585   dig_with_opts @10.53.0.3 +sp=4 -t sshfp foo.example >dig.out.test$n || ret=1
    586   grep " 9ABC DEF6 7890 " <dig.out.test$n >/dev/null || ret=1
    587   check_ttl_range dig.out.test$n "SSHFP" 300 || ret=1
    588   if [ $ret -ne 0 ]; then echo_i "failed"; fi
    589   status=$((status + ret))
    590 
    591   n=$((n + 1))
    592   echo_i "checking dig -c works ($n)"
    593   ret=0
    594   dig_with_opts @10.53.0.3 -c CHAOS -t txt version.bind >dig.out.test$n || ret=1
    595   grep "version.bind.		0	CH	TXT" <dig.out.test$n >/dev/null || ret=1
    596   if [ $ret -ne 0 ]; then echo_i "failed"; fi
    597   status=$((status + ret))
    598 
    599   n=$((n + 1))
    600   echo_i "checking dig +ednsopt with option number ($n)"
    601   ret=0
    602   dig_with_opts @10.53.0.3 +ednsopt=3 a.example >dig.out.test$n 2>&1 || ret=1
    603   grep 'NSID: .* ("ns3")' dig.out.test$n >/dev/null || ret=1
    604   check_ttl_range dig.out.test$n "A" 300 || ret=1
    605   if [ $ret -ne 0 ]; then echo_i "failed"; fi
    606   status=$((status + ret))
    607 
    608   n=$((n + 1))
    609   echo_i "checking dig +ednsopt with option name ($n)"
    610   ret=0
    611   dig_with_opts @10.53.0.3 +ednsopt=nsid a.example >dig.out.test$n 2>&1 || ret=1
    612   grep 'NSID: .* ("ns3")' dig.out.test$n >/dev/null || ret=1
    613   check_ttl_range dig.out.test$n "A" 300 || ret=1
    614   if [ $ret -ne 0 ]; then echo_i "failed"; fi
    615   status=$((status + ret))
    616 
    617   n=$((n + 1))
    618   echo_i "checking ednsopt UPDATE-LEASE prints as expected (single lease) ($n)"
    619   ret=0
    620   dig_with_opts @10.53.0.3 +ednsopt=UPDATE-LEASE:00000e10 +qr a.example >dig.out.test$n 2>&1 || ret=1
    621   pat='UPDATE-LEASE: 3600 (1 hour)'
    622   grep "$pat" dig.out.test$n >/dev/null || ret=1
    623   if [ $ret -ne 0 ]; then echo_i "failed"; fi
    624   status=$((status + ret))
    625   n=$((n + 1))
    626 
    627   if [ $HAS_PYYAML -ne 0 ]; then
    628     n=$((n + 1))
    629     echo_i "checking ednsopt UPDATE-LEASE prints as expected (single lease) +yaml ($n)"
    630     ret=0
    631     dig_with_opts @10.53.0.3 +yaml +ednsopt=UPDATE-LEASE:00000e10 +qr a.example >dig.out.test$n 2>&1 || ret=1
    632     $PYTHON yamlget.py dig.out.test$n 0 message query_message_data OPT_PSEUDOSECTION EDNS UPDATE-LEASE LEASE >yamlget.out.test$n 2>&1 || ret=1
    633     read -r value <yamlget.out.test$n
    634     [ "$value" = "3600" ] || ret=1
    635     grep "LEASE: 3600 # 1 hour" dig.out.test$n >/dev/null || ret=1
    636     if [ $ret -ne 0 ]; then echo_i "failed"; fi
    637     status=$((status + ret))
    638   fi
    639 
    640   n=$((n + 1))
    641   echo_i "checking ednsopt UPDATE-LEASE prints as expected (split lease) ($n)"
    642   ret=0
    643   dig_with_opts @10.53.0.3 +ednsopt=UPDATE-LEASE:00000e1000127500 +qr a.example >dig.out.test$n 2>&1 || ret=1
    644   pat='UPDATE-LEASE: 3600/1209600 (1 hour/2 weeks)'
    645   grep "$pat" dig.out.test$n >/dev/null || ret=1
    646   if [ $ret -ne 0 ]; then echo_i "failed"; fi
    647   status=$((status + ret))
    648 
    649   if [ $HAS_PYYAML -ne 0 ]; then
    650     n=$((n + 1))
    651     echo_i "checking ednsopt UPDATE-LEASE prints as expected (split lease) +yaml ($n)"
    652     ret=0
    653     dig_with_opts @10.53.0.3 +yaml +ednsopt=UPDATE-LEASE:00000e1000127500 +qr a.example >dig.out.test$n 2>&1 || ret=1
    654     $PYTHON yamlget.py dig.out.test$n 0 message query_message_data OPT_PSEUDOSECTION EDNS UPDATE-LEASE LEASE >yamlget.out.test$n 2>&1 || ret=1
    655     read -r value <yamlget.out.test$n
    656     [ "$value" = "3600" ] || ret=1
    657     grep "LEASE: 3600 # 1 hour" dig.out.test$n >/dev/null || ret=1
    658     $PYTHON yamlget.py dig.out.test$n 0 message query_message_data OPT_PSEUDOSECTION EDNS UPDATE-LEASE KEY-LEASE >yamlget.out.test$n 2>&1 || ret=1
    659     read -r value <yamlget.out.test$n
    660     [ "$value" = "1209600" ] || ret=1
    661     grep "KEY-LEASE: 1209600 # 2 weeks" dig.out.test$n >/dev/null || ret=1
    662     if [ $ret -ne 0 ]; then echo_i "failed"; fi
    663     status=$((status + ret))
    664   fi
    665 
    666   echo_i "checking ednsopt LLQ prints as expected ($n)"
    667   ret=0
    668   dig_with_opts @10.53.0.3 +ednsopt=llq:0001000200001234567812345678fefefefe +qr a.example >dig.out.test$n 2>&1 || ret=1
    669   pat='LLQ: Version: 1, Opcode: 2, Error: 0, Identifier: 1311768465173141112, Lifetime: 4278124286$'
    670   grep "$pat" dig.out.test$n >/dev/null || ret=1
    671   if [ $ret -ne 0 ]; then echo_i "failed"; fi
    672   status=$((status + ret))
    673 
    674   if [ $HAS_PYYAML -ne 0 ]; then
    675     n=$((n + 1))
    676     echo_i "checking ednsopt LLQ prints as expected +yaml ($n)"
    677     ret=0
    678     dig_with_opts @10.53.0.3 +yaml +ednsopt=llq:0001000200001234567812345678fefefefe +qr a.example >dig.out.test$n 2>&1 || ret=1
    679     $PYTHON yamlget.py dig.out.test$n 0 message query_message_data OPT_PSEUDOSECTION EDNS LLQ LLQ-VERSION >yamlget.out.test$n 2>&1 || ret=1
    680     read -r value <yamlget.out.test$n
    681     [ "$value" = "1" ] || ret=1
    682     $PYTHON yamlget.py dig.out.test$n 0 message query_message_data OPT_PSEUDOSECTION EDNS LLQ LLQ-OPCODE >yamlget.out.test$n 2>&1 || ret=1
    683     read -r value <yamlget.out.test$n
    684     [ "$value" = "2" ] || ret=1
    685     $PYTHON yamlget.py dig.out.test$n 0 message query_message_data OPT_PSEUDOSECTION EDNS LLQ LLQ-ERROR >yamlget.out.test$n 2>&1 || ret=1
    686     read -r value <yamlget.out.test$n
    687     [ "$value" = "0" ] || ret=1
    688     $PYTHON yamlget.py dig.out.test$n 0 message query_message_data OPT_PSEUDOSECTION EDNS LLQ LLQ-ID >yamlget.out.test$n 2>&1 || ret=1
    689     read -r value <yamlget.out.test$n
    690     [ "$value" = "1311768465173141112" ] || ret=1
    691     $PYTHON yamlget.py dig.out.test$n 0 message query_message_data OPT_PSEUDOSECTION EDNS LLQ LLQ-LEASE >yamlget.out.test$n 2>&1 || ret=1
    692     read -r value <yamlget.out.test$n
    693     [ "$value" = "4278124286" ] || ret=1
    694     if [ $ret -ne 0 ]; then echo_i "failed"; fi
    695     status=$((status + ret))
    696   fi
    697 
    698   n=$((n + 1))
    699   echo_i "checking that dig warns about .local queries ($n)"
    700   ret=0
    701   dig_with_opts @10.53.0.3 local soa >dig.out.test$n 2>&1 || ret=1
    702   grep ";; WARNING: .local is reserved for Multicast DNS" dig.out.test$n >/dev/null || ret=1
    703   if [ $ret -ne 0 ]; then echo_i "failed"; fi
    704   status=$((status + ret))
    705 
    706   n=$((n + 1))
    707   echo_i "check that dig processes +ednsopt=key-tag and FORMERR is returned ($n)"
    708   ret=0
    709   dig_with_opts @10.53.0.3 +ednsopt=key-tag a.example +qr >dig.out.test$n 2>&1 || ret=1
    710   grep "; KEY-TAG: *$" dig.out.test$n >/dev/null || ret=1
    711   grep "status: FORMERR" dig.out.test$n >/dev/null || ret=1
    712   if [ $ret -ne 0 ]; then echo_i "failed"; fi
    713   status=$((status + ret))
    714 
    715   n=$((n + 1))
    716   echo_i "check that dig processes +ednsopt=key-tag:<value-list> ($n)"
    717   ret=0
    718   dig_with_opts @10.53.0.3 +ednsopt=key-tag:00010002 a.example +qr >dig.out.test$n 2>&1 || ret=1
    719   grep "; KEY-TAG: 1, 2$" dig.out.test$n >/dev/null || ret=1
    720   grep "status: FORMERR" dig.out.test$n >/dev/null && ret=1
    721   check_ttl_range dig.out.test$n "A" 300 || ret=1
    722   if [ $ret -ne 0 ]; then echo_i "failed"; fi
    723   status=$((status + ret))
    724 
    725   if [ $HAS_PYYAML -ne 0 ]; then
    726     n=$((n + 1))
    727     ret=0
    728     echo_i "check that dig processes +ednsopt=key-tag:<value-list> +yaml ($n)"
    729     dig_with_opts @10.53.0.3 +yaml +ednsopt=key-tag:00010002 a.example +qr >dig.out.test$n 2>&1 || ret=1
    730     $PYTHON yamlget.py dig.out.test$n 0 message query_message_data OPT_PSEUDOSECTION EDNS KEY-TAG >yamlget.out.test$n 2>&1 || ret=1
    731     read -r value <yamlget.out.test$n
    732     [ "$value" = "[1, 2]" ] || ret=1
    733     if [ $ret -ne 0 ]; then echo_i "failed"; fi
    734     status=$((status + ret))
    735   fi
    736 
    737   n=$((n + 1))
    738   echo_i "check that dig processes +ednsopt=key-tag:<malformed-value-list> and FORMERR is returned ($n)"
    739   ret=0
    740   dig_with_opts @10.53.0.3 +ednsopt=key-tag:0001000201 a.example +qr >dig.out.test$n 2>&1 || ret=1
    741   grep "; KEY-TAG: 00 01 00 02 01" dig.out.test$n >/dev/null || ret=1
    742   grep "status: FORMERR" dig.out.test$n >/dev/null || ret=1
    743   if [ $ret -ne 0 ]; then echo_i "failed"; fi
    744   status=$((status + ret))
    745 
    746   n=$((n + 1))
    747   echo_i "check that dig processes +ednsopt=client-tag:value ($n)"
    748   ret=0
    749   dig_with_opts @10.53.0.3 +ednsopt=client-tag:0001 a.example +qr >dig.out.test$n 2>&1 || ret=1
    750   grep "; CLIENT-TAG: 1$" dig.out.test$n >/dev/null || ret=1
    751   grep "status: FORMERR" dig.out.test$n >/dev/null && ret=1
    752   if [ $ret -ne 0 ]; then echo_i "failed"; fi
    753   status=$((status + ret))
    754 
    755   if [ $HAS_PYYAML -ne 0 ]; then
    756     n=$((n + 1))
    757     echo_i "check that dig processes +ednsopt=client-tag:value +yaml ($n)"
    758     ret=0
    759     dig_with_opts @10.53.0.3 +yaml +ednsopt=client-tag:0001 a.example +qr >dig.out.test$n 2>&1 || ret=1
    760     $PYTHON yamlget.py dig.out.test$n 0 message query_message_data OPT_PSEUDOSECTION EDNS CLIENT-TAG >yamlget.out.test$n 2>&1 || ret=1
    761     read -r value <yamlget.out.test$n
    762     [ "$value" = "1" ] || ret=1
    763     if [ $ret -ne 0 ]; then echo_i "failed"; fi
    764     status=$((status + ret))
    765   fi
    766 
    767   n=$((n + 1))
    768   echo_i "check that FORMERR is returned for a too short client-tag ($n)"
    769   ret=0
    770   dig_with_opts @10.53.0.3 +ednsopt=client-tag:01 a.example +qr >dig.out.test$n 2>&1 || ret=1
    771   grep "; CLIENT-TAG" dig.out.test$n >/dev/null || ret=1
    772   grep "status: FORMERR" dig.out.test$n >/dev/null || ret=1
    773   if [ $ret -ne 0 ]; then echo_i "failed"; fi
    774   status=$((status + ret))
    775 
    776   n=$((n + 1))
    777   echo_i "check that FORMERR is returned for a too long client-tag ($n)"
    778   ret=0
    779   dig_with_opts @10.53.0.3 +ednsopt=client-tag:000001 a.example +qr >dig.out.test$n 2>&1 || ret=1
    780   grep "; CLIENT-TAG" dig.out.test$n >/dev/null || ret=1
    781   grep "status: FORMERR" dig.out.test$n >/dev/null || ret=1
    782   if [ $ret -ne 0 ]; then echo_i "failed"; fi
    783   status=$((status + ret))
    784 
    785   n=$((n + 1))
    786   echo_i "check that dig processes +ednsopt=server-tag:value ($n)"
    787   ret=0
    788   dig_with_opts @10.53.0.3 +ednsopt=server-tag:0001 a.example +qr >dig.out.test$n 2>&1 || ret=1
    789   grep "; SERVER-TAG: 1$" dig.out.test$n >/dev/null || ret=1
    790   grep "status: FORMERR" dig.out.test$n >/dev/null && ret=1
    791   if [ $ret -ne 0 ]; then echo_i "failed"; fi
    792   status=$((status + ret))
    793 
    794   if [ $HAS_PYYAML -ne 0 ]; then
    795     n=$((n + 1))
    796     echo_i "check that dig processes +ednsopt=server-tag:value +yaml ($n)"
    797     ret=0
    798     dig_with_opts @10.53.0.3 +yaml +ednsopt=server-tag:0001 a.example +qr >dig.out.test$n 2>&1 || ret=1
    799     $PYTHON yamlget.py dig.out.test$n 0 message query_message_data OPT_PSEUDOSECTION EDNS SERVER-TAG >yamlget.out.test$n 2>&1 || ret=1
    800     read -r value <yamlget.out.test$n
    801     [ "$value" = "1" ] || ret=1
    802     if [ $ret -ne 0 ]; then echo_i "failed"; fi
    803     status=$((status + ret))
    804   fi
    805 
    806   n=$((n + 1))
    807   echo_i "check that FORMERR is returned for a too short server-tag ($n)"
    808   ret=0
    809   dig_with_opts @10.53.0.3 +ednsopt=server-tag:01 a.example +qr >dig.out.test$n 2>&1 || ret=1
    810   grep "; SERVER-TAG" dig.out.test$n >/dev/null || ret=1
    811   grep "status: FORMERR" dig.out.test$n >/dev/null || ret=1
    812   if [ $ret -ne 0 ]; then echo_i "failed"; fi
    813   status=$((status + ret))
    814 
    815   n=$((n + 1))
    816   echo_i "check that FORMERR is returned for a too long server-tag ($n)"
    817   ret=0
    818   dig_with_opts @10.53.0.3 +ednsopt=server-tag:000001 a.example +qr >dig.out.test$n 2>&1 || ret=1
    819   grep "; SERVER-TAG" dig.out.test$n >/dev/null || ret=1
    820   grep "status: FORMERR" dig.out.test$n >/dev/null || ret=1
    821   if [ $ret -ne 0 ]; then echo_i "failed"; fi
    822   status=$((status + ret))
    823 
    824   n=$((n + 1))
    825   echo_i "check that dig processes +ednsopt=chain:02002200 ($n)"
    826   ret=0
    827   dig_with_opts @10.53.0.3 +ednsopt=chain:02002200 'a.\000"' +qr >dig.out.test$n 2>&1 || ret=1
    828   grep '; CHAIN: "\\000\\""' dig.out.test$n >/dev/null || ret=1
    829   if [ $ret -ne 0 ]; then echo_i "failed"; fi
    830   status=$((status + ret))
    831 
    832   if [ $HAS_PYYAML -ne 0 ]; then
    833     n=$((n + 1))
    834     echo_i "check that dig processes +ednsopt=chain:02002200 +yaml ($n)"
    835     ret=0
    836     dig_with_opts @10.53.0.3 +yaml +ednsopt=chain:02002200 'a.\000"' +qr >dig.out.test$n 2>&1 || ret=1
    837     $PYTHON yamlget.py dig.out.test$n 0 message query_message_data OPT_PSEUDOSECTION EDNS CHAIN >yamlget.out.test$n 2>&1 || ret=1
    838     read -r value <yamlget.out.test$n
    839     [ "$value" = '\000\"' ] || ret=1
    840     if [ $ret -ne 0 ]; then echo_i "failed"; fi
    841     status=$((status + ret))
    842   fi
    843 
    844   n=$((n + 1))
    845   echo_i "check that dig processes +expire ($n)"
    846   ret=0
    847   dig_with_opts @10.53.0.1 +expire . soa >dig.out.test$n 2>&1 || ret=1
    848   grep '; EXPIRE: 1200 (20 minutes)' dig.out.test$n >/dev/null || ret=1
    849   if [ $ret -ne 0 ]; then echo_i "failed"; fi
    850   status=$((status + ret))
    851 
    852   if [ $HAS_PYYAML -ne 0 ]; then
    853     n=$((n + 1))
    854     echo_i "check that dig processes +expire +yaml ($n)"
    855     ret=0
    856     dig_with_opts @10.53.0.1 +yaml +expire . soa >dig.out.test$n 2>&1 || ret=1
    857     $PYTHON yamlget.py dig.out.test$n 0 message response_message_data OPT_PSEUDOSECTION EDNS EXPIRE >yamlget.out.test$n 2>&1 || ret=1
    858     read -r value <yamlget.out.test$n
    859     [ "$value" = "1200" ] || ret=1
    860     grep "EXPIRE: 1200 # 20 minutes" dig.out.test$n >/dev/null || ret=1
    861     if [ $ret -ne 0 ]; then echo_i "failed"; fi
    862     status=$((status + ret))
    863   fi
    864 
    865   n=$((n + 1))
    866   echo_i "check that dig processes +keepalive ($n)"
    867   ret=0
    868   dig_with_opts @10.53.0.1 +keepalive . soa +tcp >dig.out.test$n 2>&1 || ret=1
    869   grep '; TCP-KEEPALIVE: 30.0 secs' dig.out.test$n >/dev/null || ret=1
    870   if [ $ret -ne 0 ]; then echo_i "failed"; fi
    871   status=$((status + ret))
    872 
    873   if [ $HAS_PYYAML -ne 0 ]; then
    874     n=$((n + 1))
    875     echo_i "check that dig processes +keepalive +yaml ($n)"
    876     ret=0
    877     dig_with_opts @10.53.0.1 +yaml +keepalive . soa +tcp >dig.out.test$n 2>&1 || ret=1
    878     $PYTHON yamlget.py dig.out.test$n 0 message response_message_data OPT_PSEUDOSECTION EDNS TCP-KEEPALIVE >yamlget.out.test$n 2>&1 || ret=1
    879     read -r value <yamlget.out.test$n
    880     [ "$value" = "30.0 secs" ] || ret=1
    881     if [ $ret -ne 0 ]; then echo_i "failed"; fi
    882     status=$((status + ret))
    883   fi
    884 
    885   n=$((n + 1))
    886   echo_i "check that Extended DNS Error 0 is printed correctly ($n)"
    887   ret=0
    888   # First defined EDE code, additional text "foo".
    889   dig_with_opts @10.53.0.3 +ednsopt=ede:0000666f6f a.example +qr >dig.out.test$n 2>&1 || ret=1
    890   pat='^; EDE: 0 (Other): (foo)$'
    891   grep "$pat" dig.out.test$n >/dev/null || ret=1
    892   if [ $ret -ne 0 ]; then echo_i "failed"; fi
    893   status=$((status + ret))
    894 
    895   if [ $HAS_PYYAML -ne 0 ]; then
    896     n=$((n + 1))
    897     echo_i "check that Extended DNS Error 0 is printed correctly +yaml ($n)"
    898     ret=0
    899     # add specials '"' and '\'
    900     dig_with_opts @10.53.0.3 +yaml +ednsopt=ede:0000666f6f225c a.example +qr >dig.out.test$n 2>&1 || ret=1
    901     $PYTHON yamlget.py dig.out.test$n 0 message query_message_data OPT_PSEUDOSECTION EDNS EDE EXTRA-TEXT >yamlget.out.test$n 2>&1 || ret=1
    902     read -r value <yamlget.out.test$n
    903     [ "$value" = 'foo"\' ] || ret=1
    904     if [ $ret -ne 0 ]; then echo_i "failed"; fi
    905     status=$((status + ret))
    906   fi
    907 
    908   n=$((n + 1))
    909   echo_i "check that Extended DNS Error 24 is printed correctly ($n)"
    910   ret=0
    911   # Last defined EDE code, no additional text.
    912   dig_with_opts @10.53.0.3 +ednsopt=ede:0018 a.example +qr >dig.out.test$n 2>&1 || ret=1
    913   pat='^; EDE: 24 (Invalid Data)$'
    914   grep "$pat" dig.out.test$n >/dev/null || ret=1
    915   if [ $ret -ne 0 ]; then echo_i "failed"; fi
    916   status=$((status + ret))
    917 
    918   n=$((n + 1))
    919   echo_i "check that Extended DNS Error 25 is printed correctly ($n)"
    920   ret=0
    921   # First undefined EDE code, additional text "foo".
    922   dig_with_opts @10.53.0.3 +ednsopt=ede:0019666f6f a.example +qr >dig.out.test$n 2>&1 || ret=1
    923   pat='^; EDE: 25: (foo)$'
    924   grep "$pat" dig.out.test$n >/dev/null || ret=1
    925   if [ $ret -ne 0 ]; then echo_i "failed"; fi
    926   status=$((status + ret))
    927 
    928   n=$((n + 1))
    929   echo_i "check that invalid Extended DNS Error (length 0) is printed ($n)"
    930   ret=0
    931   # EDE payload is too short
    932   dig_with_opts @10.53.0.3 +ednsopt=ede a.example +qr >dig.out.test$n 2>&1 || ret=1
    933   pat='^; EDE:$'
    934   grep "$pat" dig.out.test$n >/dev/null || ret=1
    935   if [ $ret -ne 0 ]; then echo_i "failed"; fi
    936   status=$((status + ret))
    937 
    938   n=$((n + 1))
    939   echo_i "check that invalid Extended DNS Error (length 1) is printed ($n)"
    940   ret=0
    941   # EDE payload is too short
    942   dig_with_opts @10.53.0.3 +ednsopt=ede:00 a.example +qr >dig.out.test$n 2>&1 || ret=1
    943   pat='^; EDE: 00 (".")$'
    944   grep "$pat" dig.out.test$n >/dev/null || ret=1
    945   if [ $ret -ne 0 ]; then echo_i "failed"; fi
    946   status=$((status + ret))
    947 
    948   if [ $HAS_PYYAML -ne 0 ]; then
    949     n=$((n + 1))
    950     echo_i "check that +yaml Extended DNS Error 0 is printed correctly ($n)"
    951     ret=0
    952     # First defined EDE code, additional text "foo".
    953     dig_with_opts @10.53.0.3 +yaml +ednsopt=ede:0000666f6f a.example +qr >dig.out.test$n 2>&1 || ret=1
    954     $PYTHON yamlget.py dig.out.test$n 0 message query_message_data OPT_PSEUDOSECTION EDNS EDE INFO-CODE >yamlget.out.test$n 2>&1 || ret=1
    955     read -r value <yamlget.out.test$n
    956     [ "$value" = "0 (Other)" ] || ret=1
    957     $PYTHON yamlget.py dig.out.test$n 0 message query_message_data OPT_PSEUDOSECTION EDNS EDE EXTRA-TEXT >yamlget.out.test$n 2>&1 || ret=1
    958     read -r value <yamlget.out.test$n
    959     [ "$value" = "foo" ] || ret=1
    960     if [ $ret -ne 0 ]; then echo_i "failed"; fi
    961     status=$((status + ret))
    962 
    963     n=$((n + 1))
    964     echo_i "check that +yaml Extended DNS Error 24 is printed correctly ($n)"
    965     ret=0
    966     # Last defined EDE code, no additional text.
    967     dig_with_opts @10.53.0.3 +yaml +ednsopt=ede:0018 a.example +qr >dig.out.test$n 2>&1 || ret=1
    968     $PYTHON yamlget.py dig.out.test$n 0 message query_message_data OPT_PSEUDOSECTION EDNS EDE INFO-CODE >yamlget.out.test$n 2>&1 || ret=1
    969     read -r value <yamlget.out.test$n
    970     [ "$value" = "24 (Invalid Data)" ] || ret=1
    971     $PYTHON yamlget.py dig.out.test$n 0 message query_message_data OPT_PSEUDOSECTION EDNS EDE EXTRA-TEXT >yamlget.out.test$n 2>&1 && ret=1
    972     if [ $ret -ne 0 ]; then echo_i "failed"; fi
    973     status=$((status + ret))
    974 
    975     n=$((n + 1))
    976     echo_i "check that +yaml Extended DNS Error 25 is printed correctly ($n)"
    977     ret=0
    978     # First undefined EDE code, additional text "foo".
    979     dig_with_opts @10.53.0.3 +yaml +ednsopt=ede:0019666f6f a.example +qr >dig.out.test$n 2>&1 || ret=1
    980     $PYTHON yamlget.py dig.out.test$n 0 message query_message_data OPT_PSEUDOSECTION EDNS EDE INFO-CODE >yamlget.out.test$n 2>&1 || ret=1
    981     read -r value <yamlget.out.test$n
    982     [ "$value" = "25" ] || ret=1
    983     $PYTHON yamlget.py dig.out.test$n 0 message query_message_data OPT_PSEUDOSECTION EDNS EDE EXTRA-TEXT >yamlget.out.test$n 2>&1 || ret=1
    984     read -r value <yamlget.out.test$n
    985     [ "$value" = "foo" ] || ret=1
    986     if [ $ret -ne 0 ]; then echo_i "failed"; fi
    987     status=$((status + ret))
    988 
    989     n=$((n + 1))
    990     echo_i "check that invalid Extended DNS Error (length 0) is printed ($n)"
    991     ret=0
    992     # EDE payload is too short
    993     dig_with_opts @10.53.0.3 +yaml +ednsopt=ede a.example +qr >dig.out.test$n 2>&1 || ret=1
    994     $PYTHON yamlget.py dig.out.test$n 0 message query_message_data OPT_PSEUDOSECTION EDNS EDE >yamlget.out.test$n 2>&1 || ret=1
    995     read -r value <yamlget.out.test$n
    996     [ "$value" = "None" ] || ret=1
    997     if [ $ret -ne 0 ]; then echo_i "failed"; fi
    998     status=$((status + ret))
    999 
   1000     n=$((n + 1))
   1001     echo_i "check that invalid +yaml Extended DNS Error (length 1) is printed ($n)"
   1002     ret=0
   1003     # EDE payload is too short
   1004     dig_with_opts @10.53.0.3 +yaml +ednsopt=ede:00 a.example +qr >dig.out.test$n 2>&1 || ret=1
   1005     $PYTHON yamlget.py dig.out.test$n 0 message query_message_data OPT_PSEUDOSECTION EDNS EDE >yamlget.out.test$n 2>&1 || ret=1
   1006     read -r value <yamlget.out.test$n
   1007     [ "$value" = '00 (".")' ] || ret=1
   1008     if [ $ret -ne 0 ]; then echo_i "failed"; fi
   1009     status=$((status + ret))
   1010   fi
   1011 
   1012   n=$((n + 1))
   1013   echo_i "check that dig handles malformed option '+ednsopt=:' gracefully ($n)"
   1014   ret=0
   1015   dig_with_opts @10.53.0.3 +ednsopt=: a.example >dig.out.test$n 2>&1 && ret=1
   1016   grep "ednsopt no code point specified" dig.out.test$n >/dev/null || ret=1
   1017   if [ $ret -ne 0 ]; then echo_i "failed"; fi
   1018   status=$((status + ret))
   1019 
   1020   n=$((n + 1))
   1021   echo_i "check that dig gracefully handles bad escape in domain name ($n)"
   1022   ret=0
   1023   digstatus=0
   1024   dig_with_opts @10.53.0.3 '\0.' >dig.out.test$n 2>&1 || digstatus=$?
   1025   echo digstatus=$digstatus >>dig.out.test$n
   1026   test $digstatus -eq 10 || ret=1
   1027   grep REQUIRE dig.out.test$n >/dev/null && ret=1
   1028   grep "is not a legal name (bad escape)" dig.out.test$n >/dev/null || ret=1
   1029   if [ $ret -ne 0 ]; then echo_i "failed"; fi
   1030   status=$((status + ret))
   1031 
   1032   n=$((n + 1))
   1033   echo_i "check that dig -q -m works ($n)"
   1034   ret=0
   1035   dig_with_opts @10.53.0.3 -q -m >dig.out.test$n 2>&1
   1036   pat='^;-m\..*IN.*A$'
   1037   grep "$pat" dig.out.test$n >/dev/null || ret=1
   1038   grep "Dump of all outstanding memory allocations" dig.out.test$n >/dev/null && ret=1
   1039   if [ $ret -ne 0 ]; then echo_i "failed"; fi
   1040   status=$((status + ret))
   1041 
   1042   n=$((n + 1))
   1043   echo_i "checking exit code for a retry upon TCP EOF (immediate -> immediate) ($n)"
   1044   ret=0
   1045   echo "no_response no_response" | sendcmd 10.53.0.5
   1046   dig_with_opts @10.53.0.5 example AXFR +tries=2 >dig.out.test$n 2>&1 && ret=1
   1047   # Sanity check: ensure ans5 behaves as expected.
   1048   [ $(grep "communications error.*end of file" dig.out.test$n | wc -l) -eq 2 ] || ret=1
   1049   if [ $ret -ne 0 ]; then echo_i "failed"; fi
   1050   status=$((status + ret))
   1051 
   1052   n=$((n + 1))
   1053   echo_i "checking exit code for a retry upon TCP EOF (partial AXFR -> partial AXFR) ($n)"
   1054   ret=0
   1055   echo "partial_axfr partial_axfr" | sendcmd 10.53.0.5
   1056   dig_with_opts @10.53.0.5 example AXFR +tries=2 >dig.out.test$n 2>&1 && ret=1
   1057   # Sanity check: ensure ans5 behaves as expected.
   1058   [ $(grep "communications error.*end of file" dig.out.test$n | wc -l) -eq 2 ] || ret=1
   1059   if [ $ret -ne 0 ]; then echo_i "failed"; fi
   1060   status=$((status + ret))
   1061 
   1062   n=$((n + 1))
   1063   echo_i "checking exit code for a retry upon TCP EOF (immediate -> partial AXFR) ($n)"
   1064   ret=0
   1065   echo "no_response partial_axfr" | sendcmd 10.53.0.5
   1066   dig_with_opts @10.53.0.5 example AXFR +tries=2 >dig.out.test$n 2>&1 && ret=1
   1067   # Sanity check: ensure ans5 behaves as expected.
   1068   [ $(grep "communications error.*end of file" dig.out.test$n | wc -l) -eq 2 ] || ret=1
   1069   if [ $ret -ne 0 ]; then echo_i "failed"; fi
   1070   status=$((status + ret))
   1071 
   1072   n=$((n + 1))
   1073   echo_i "checking exit code for a retry upon TCP EOF (partial AXFR -> immediate) ($n)"
   1074   ret=0
   1075   echo "partial_axfr no_response" | sendcmd 10.53.0.5
   1076   dig_with_opts @10.53.0.5 example AXFR +tries=2 >dig.out.test$n 2>&1 && ret=1
   1077   # Sanity check: ensure ans5 behaves as expected.
   1078   [ $(grep "communications error.*end of file" dig.out.test$n | wc -l) -eq 2 ] || ret=1
   1079   if [ $ret -ne 0 ]; then echo_i "failed"; fi
   1080   status=$((status + ret))
   1081 
   1082   n=$((n + 1))
   1083   echo_i "checking exit code for a retry upon TCP EOF (immediate -> complete AXFR) ($n)"
   1084   ret=0
   1085   echo "no_response complete_axfr" | sendcmd 10.53.0.5
   1086   dig_with_opts @10.53.0.5 example AXFR +tries=2 >dig.out.test$n 2>&1 || ret=1
   1087   # Sanity check: ensure ans5 behaves as expected.
   1088   [ $(grep "communications error.*end of file" dig.out.test$n | wc -l) -eq 1 ] || ret=1
   1089   if [ $ret -ne 0 ]; then echo_i "failed"; fi
   1090   status=$((status + ret))
   1091 
   1092   n=$((n + 1))
   1093   echo_i "checking exit code for a retry upon TCP EOF (partial AXFR -> complete AXFR) ($n)"
   1094   ret=0
   1095   echo "partial_axfr complete_axfr" | sendcmd 10.53.0.5
   1096   dig_with_opts @10.53.0.5 example AXFR +tries=2 >dig.out.test$n 2>&1 || ret=1
   1097   # Sanity check: ensure ans5 behaves as expected.
   1098   [ $(grep "communications error.*end of file" dig.out.test$n | wc -l) -eq 1 ] || ret=1
   1099   if [ $ret -ne 0 ]; then echo_i "failed"; fi
   1100   status=$((status + ret))
   1101 
   1102   n=$((n + 1))
   1103   echo_i "checking +tries=1 won't retry twice upon TCP EOF ($n)"
   1104   ret=0
   1105   echo "no_response no_response" | sendcmd 10.53.0.5
   1106   dig_with_opts @10.53.0.5 example AXFR +tries=1 >dig.out.test$n 2>&1 && ret=1
   1107   # Sanity check: ensure ans5 behaves as expected.
   1108   [ $(grep "communications error.*end of file" dig.out.test$n | wc -l) -eq 1 ] || ret=1
   1109   if [ $ret -ne 0 ]; then echo_i "failed"; fi
   1110   status=$((status + ret))
   1111 
   1112   n=$((n + 1))
   1113   echo_i "checking +retry=0 won't retry twice upon TCP EOF ($n)"
   1114   ret=0
   1115   dig_with_opts @10.53.0.5 example AXFR +retry=0 >dig.out.test$n 2>&1 && ret=1
   1116   # Sanity check: ensure ans5 behaves as expected.
   1117   [ $(grep "communications error.*end of file" dig.out.test$n | wc -l) -eq 1 ] || ret=1
   1118   if [ $ret -ne 0 ]; then echo_i "failed"; fi
   1119   status=$((status + ret))
   1120 
   1121   n=$((n + 1))
   1122   echo_i "check that dig +expandaaaa works ($n)"
   1123   ret=0
   1124   dig_with_opts @10.53.0.3 +expandaaaa AAAA ns2.example >dig.out.test$n 2>&1 || ret=1
   1125   grep "ns2.example.*fd92:7065:0b8e:ffff:0000:0000:0000:0002" dig.out.test$n >/dev/null || ret=1
   1126   if [ $ret -ne 0 ]; then echo_i "failed"; fi
   1127   status=$((status + ret))
   1128 
   1129   n=$((n + 1))
   1130   echo_i "check that dig +noexpandaaaa works ($n)"
   1131   ret=0
   1132   dig_with_opts @10.53.0.3 +noexpandaaaa AAAA ns2.example >dig.out.test$n 2>&1 || ret=1
   1133   grep "ns2.example.*fd92:7065:b8e:ffff::2" dig.out.test$n >/dev/null || ret=1
   1134   if [ $ret -ne 0 ]; then echo_i "failed"; fi
   1135   status=$((status + ret))
   1136 
   1137   n=$((n + 1))
   1138   echo_i "check that dig default for +[no]expandaaa (+noexpandaaaa) works ($n)"
   1139   ret=0
   1140   dig_with_opts @10.53.0.3 AAAA ns2.example >dig.out.test$n 2>&1 || ret=1
   1141   grep "ns2.example.*fd92:7065:b8e:ffff::2" dig.out.test$n >/dev/null || ret=1
   1142   if [ $ret -ne 0 ]; then echo_i "failed"; fi
   1143   status=$((status + ret))
   1144 
   1145   n=$((n + 1))
   1146 
   1147   echo_i "check that dig +short +expandaaaa works ($n)"
   1148   ret=0
   1149   dig_with_opts @10.53.0.3 +short +expandaaaa AAAA ns2.example >dig.out.test$n 2>&1 || ret=1
   1150   pat='^fd92:7065:0b8e:ffff:0000:0000:0000:0002$'
   1151   grep "$pat" dig.out.test$n >/dev/null || ret=1
   1152   if [ $ret -ne 0 ]; then echo_i "failed"; fi
   1153   status=$((status + ret))
   1154 
   1155   if [ $HAS_PYYAML -ne 0 ]; then
   1156     n=$((n + 1))
   1157     echo_i "check dig +yaml ANY output ($n)"
   1158     ret=0
   1159     dig_with_opts +qr +yaml @10.53.0.3 any ns2.example >dig.out.test$n 2>&1 || ret=1
   1160     $PYTHON yamlget.py dig.out.test$n 0 message query_message_data status >yamlget.out.test$n 2>&1 || ret=1
   1161     read -r value <yamlget.out.test$n
   1162     [ "$value" = "NOERROR" ] || ret=1
   1163     $PYTHON yamlget.py dig.out.test$n 1 message response_message_data status >yamlget.out.test$n 2>&1 || ret=1
   1164     read -r value <yamlget.out.test$n
   1165     [ "$value" = "NOERROR" ] || ret=1
   1166     $PYTHON yamlget.py dig.out.test$n 1 message response_message_data QUESTION_SECTION 0 >yamlget.out.test$n 2>&1 || ret=1
   1167     read -r value <yamlget.out.test$n
   1168     [ "$value" = "ns2.example. IN ANY" ] || ret=1
   1169     if [ $ret -ne 0 ]; then echo_i "failed"; fi
   1170     status=$((status + ret))
   1171 
   1172     n=$((n + 1))
   1173     echo_i "check dig +yaml output of an IPv6 address ending in zeroes ($n)"
   1174     ret=0
   1175     dig_with_opts +qr +yaml @10.53.0.3 aaaa d.example >dig.out.test$n 2>&1 || ret=1
   1176     $PYTHON yamlget.py dig.out.test$n 1 message response_message_data ANSWER_SECTION 0 >yamlget.out.test$n 2>&1 || ret=1
   1177     read -r value <yamlget.out.test$n
   1178     [ "$value" = "d.example. 300 IN AAAA fd92:7065:b8e:ffff::0" ] || ret=1
   1179     if [ $ret -ne 0 ]; then echo_i "failed"; fi
   1180     status=$((status + ret))
   1181   fi
   1182 
   1183   n=$((n + 1))
   1184   echo_i "check that dig +bufsize=0 just sets the buffer size to 0 ($n)"
   1185   ret=0
   1186   dig_with_opts @10.53.0.3 a.example +bufsize=0 +qr >dig.out.test$n 2>&1 || ret=1
   1187   grep "EDNS:" dig.out.test$n >/dev/null || ret=1
   1188   if [ $ret -ne 0 ]; then echo_i "failed"; fi
   1189   status=$((status + ret))
   1190 
   1191   n=$((n + 1))
   1192   echo_i "check that dig +bufsize restores default bufsize ($n)"
   1193   ret=0
   1194   dig_with_opts @10.53.0.3 a.example +bufsize=0 +bufsize +qr >dig.out.test$n 2>&1 || ret=1
   1195   lines=$(grep "EDNS:.* udp:" dig.out.test$n | wc -l)
   1196   lines1232=$(grep "EDNS:.* udp: 1232" dig.out.test$n | wc -l)
   1197   test $lines -eq 2 || ret=1
   1198   test $lines1232 -eq 2 || ret=1
   1199   if [ $ret -ne 0 ]; then echo_i "failed"; fi
   1200   status=$((status + ret))
   1201 
   1202   n=$((n + 1))
   1203   echo_i "check that dig without -u displays 'Query time' in millseconds ($n)"
   1204   ret=0
   1205   dig_with_opts @10.53.0.3 a.example >dig.out.test$n 2>&1 || ret=1
   1206   grep ';; Query time: [0-9][0-9]* msec' dig.out.test$n >/dev/null || ret=1
   1207   if [ $ret -ne 0 ]; then echo_i "failed"; fi
   1208   status=$((status + ret))
   1209 
   1210   n=$((n + 1))
   1211   echo_i "check that dig -u displays 'Query time' in microseconds ($n)"
   1212   ret=0
   1213   dig_with_opts -u @10.53.0.3 a.example >dig.out.test$n 2>&1 || ret=1
   1214   grep ';; Query time: [0-9][0-9]* usec' dig.out.test$n >/dev/null || ret=1
   1215   if [ $ret -ne 0 ]; then echo_i "failed"; fi
   1216   status=$((status + ret))
   1217 
   1218   n=$((n + 1))
   1219   echo_i "check that dig +yaml without -u displays timestamps in milliseconds ($n)"
   1220   ret=0
   1221   dig_with_opts +yaml @10.53.0.3 a.example >dig.out.test$n 2>&1 || ret=1
   1222   grep 'query_time: !!timestamp ....-..-..T..:..:..\....Z' dig.out.test$n >/dev/null || ret=1
   1223   grep 'response_time: !!timestamp ....-..-..T..:..:..\....Z' dig.out.test$n >/dev/null || ret=1
   1224   if [ $ret -ne 0 ]; then echo_i "failed"; fi
   1225   status=$((status + ret))
   1226 
   1227   n=$((n + 1))
   1228   echo_i "check that dig -u +yaml displays timestamps in microseconds ($n)"
   1229   ret=0
   1230   dig_with_opts -u +yaml @10.53.0.3 a.example >dig.out.test$n 2>&1 || ret=1
   1231   grep 'query_time: !!timestamp ....-..-..T..:..:..\.......Z' dig.out.test$n >/dev/null || ret=1
   1232   grep 'response_time: !!timestamp ....-..-..T..:..:..\.......Z' dig.out.test$n >/dev/null || ret=1
   1233   if [ $ret -ne 0 ]; then echo_i "failed"; fi
   1234   status=$((status + ret))
   1235 
   1236   # See [GL #3020] for more information
   1237   n=$((n + 1))
   1238   echo_i "check that dig handles UDP timeout followed by a SERVFAIL correctly ($n)"
   1239   # Ask ans8 to be in "unstable" mode (switching between "silent" and "servfail" modes)
   1240   echo "unstable" | sendcmd 10.53.0.8
   1241   ret=0
   1242   dig_with_opts +timeout=1 +nofail @10.53.0.8 a.example >dig.out.test$n 2>&1 || ret=1
   1243   grep -F "status: SERVFAIL" dig.out.test$n >/dev/null || ret=1
   1244   if [ $ret -ne 0 ]; then echo_i "failed"; fi
   1245   status=$((status + ret))
   1246 
   1247   n=$((n + 1))
   1248   echo_i "check that dig handles TCP timeout followed by a SERVFAIL correctly ($n)"
   1249   # Ask ans8 to be in "unstable" mode (switching between "silent" and "servfail" modes)
   1250   echo "unstable" | sendcmd 10.53.0.8
   1251   ret=0
   1252   dig_with_opts +timeout=1 +nofail +tcp @10.53.0.8 a.example >dig.out.test$n 2>&1 || ret=1
   1253   grep -F "status: SERVFAIL" dig.out.test$n >/dev/null || ret=1
   1254   if [ $ret -ne 0 ]; then echo_i "failed"; fi
   1255   status=$((status + ret))
   1256 
   1257   n=$((n + 1))
   1258   echo_i "check that dig tries the next server after a UDP socket network unreachable error ($n)"
   1259   ret=0
   1260   dig_with_opts @192.0.2.128 @10.53.0.3 a.example >dig.out.test$n 2>&1 || ret=1
   1261   test $(grep -F -e "connection refused" -e "timed out" -e "network unreachable" -e "host unreachable" dig.out.test$n | wc -l) -eq 3 || ret=1
   1262   grep -F "status: NOERROR" dig.out.test$n >/dev/null || ret=1
   1263   if [ $ret -ne 0 ]; then echo_i "failed"; fi
   1264   status=$((status + ret))
   1265 
   1266   n=$((n + 1))
   1267   echo_i "check that dig tries the next server after a TCP socket network unreachable error ($n)"
   1268   ret=0
   1269   dig_with_opts +tcp @192.0.2.128 @10.53.0.3 a.example >dig.out.test$n 2>&1 || ret=1
   1270   test $(grep -F -e "connection refused" -e "timed out" -e "network unreachable" -e "host unreachable" dig.out.test$n | wc -l) -eq 3 || ret=1
   1271   grep -F "status: NOERROR" dig.out.test$n >/dev/null || ret=1
   1272   if [ $ret -ne 0 ]; then echo_i "failed"; fi
   1273   status=$((status + ret))
   1274 
   1275   n=$((n + 1))
   1276   echo_i "check that dig tries the next server after a UDP socket read error ($n)"
   1277   ret=0
   1278   dig_with_opts @10.53.0.99 @10.53.0.3 a.example >dig.out.test$n 2>&1 || ret=1
   1279   grep -F "status: NOERROR" dig.out.test$n >/dev/null || ret=1
   1280   if [ $ret -ne 0 ]; then echo_i "failed"; fi
   1281   status=$((status + ret))
   1282 
   1283   n=$((n + 1))
   1284   echo_i "check that dig tries the next server after a TCP socket read error ($n)"
   1285   # Ask ans8 to be in "close" mode, which closes the connection after accepting it
   1286   echo "close" | sendcmd 10.53.0.8
   1287   ret=0
   1288   dig_with_opts +tcp @10.53.0.8 @10.53.0.3 a.example >dig.out.test$n 2>&1 || ret=1
   1289   grep -F "status: NOERROR" dig.out.test$n >/dev/null || ret=1
   1290   if [ $ret -ne 0 ]; then echo_i "failed"; fi
   1291   status=$((status + ret))
   1292 
   1293   # Note that we combine TCP socket "connection error" and "timeout" cases in
   1294   # one, because it is not trivial to simulate the timeout case in a system test
   1295   # in Linux without a firewall, but the code which handles error cases during
   1296   # the connection establishment time does not differentiate between timeout and
   1297   # other types of errors (unlike during reading), so this one check should be
   1298   # sufficient for both cases.
   1299   n=$((n + 1))
   1300   echo_i "check that dig tries the next server after a TCP socket connection error/timeout ($n)"
   1301   ret=0
   1302   dig_with_opts +tcp @10.53.0.99 @10.53.0.3 a.example >dig.out.test$n 2>&1 || ret=1
   1303   test $(grep -F -e "connection refused" -e "timed out" -e "network unreachable" -e "host unreachable" dig.out.test$n | wc -l) -eq 3 || ret=1
   1304   grep -F "status: NOERROR" dig.out.test$n >/dev/null || ret=1
   1305   if [ $ret -ne 0 ]; then echo_i "failed"; fi
   1306   status=$((status + ret))
   1307 
   1308   n=$((n + 1))
   1309   echo_i "check that dig tries the next server after UDP socket read timeouts ($n)"
   1310   # Ask ans8 to be in "silent" mode
   1311   echo "silent" | sendcmd 10.53.0.8
   1312   ret=0
   1313   dig_with_opts +timeout=1 @10.53.0.8 @10.53.0.3 a.example >dig.out.test$n 2>&1 || ret=1
   1314   grep -F "status: NOERROR" dig.out.test$n >/dev/null || ret=1
   1315   if [ $ret -ne 0 ]; then echo_i "failed"; fi
   1316   status=$((status + ret))
   1317 
   1318   n=$((n + 1))
   1319   echo_i "check that dig tries the next server after TCP socket read timeouts ($n)"
   1320   # Ask ans8 to be in "silent" mode
   1321   echo "silent" | sendcmd 10.53.0.8
   1322   ret=0
   1323   dig_with_opts +timeout=1 +tcp @10.53.0.8 @10.53.0.3 a.example >dig.out.test$n 2>&1 || ret=1
   1324   grep -F "status: NOERROR" dig.out.test$n >/dev/null || ret=1
   1325   if [ $ret -ne 0 ]; then echo_i "failed"; fi
   1326   status=$((status + ret))
   1327 
   1328   # See [GL #3248] for more information
   1329   n=$((n + 1))
   1330   echo_i "check that dig correctly refuses to use a server with a IPv4 mapped IPv6 address after failing with a regular IP address ($n)"
   1331   ret=0
   1332   dig_with_opts @10.53.0.8 @::ffff:10.53.0.8 a.example >dig.out.test$n 2>&1 || ret=1
   1333   grep -F ";; Skipping mapped address" dig.out.test$n >/dev/null || ret=1
   1334   grep -F ";; No acceptable nameservers" dig.out.test$n >/dev/null || ret=1
   1335   if [ $ret -ne 0 ]; then echo_i "failed"; fi
   1336   status=$((status + ret))
   1337 
   1338   # See [GL #3244] for more information
   1339   n=$((n + 1))
   1340   echo_i "check that dig handles printing query information with +qr and +y when multiple queries are involved (including a failed query) ($n)"
   1341   ret=0
   1342   dig_with_opts +timeout=1 +qr +y @127.0.0.1 @10.53.0.3 a.example >dig.out.test$n 2>&1 || ret=1
   1343   grep -F "IN A 10.0.0.1" dig.out.test$n >/dev/null || ret=1
   1344   if [ $ret -ne 0 ]; then echo_i "failed"; fi
   1345   status=$((status + ret))
   1346 
   1347   n=$((n + 1))
   1348   echo_i "check that dig +noedns +ednsflags=<nonzero> re-enables EDNS ($n)"
   1349   dig_with_opts @10.53.0.3 +qr +noedns +ednsflags=0x70 a.example >dig.out.test$n 2>&1 || ret=1
   1350   grep "; EDNS: version: 0, flags:; MBZ: 0x0070, udp: 1232" dig.out.test$n >/dev/null || ret=1
   1351   grep "; EDNS: version: 0, flags:; udp: 1232" dig.out.test$n >/dev/null || ret=1
   1352   if [ $ret -ne 0 ]; then echo_i "failed"; fi
   1353   status=$((status + ret))
   1354 
   1355   n=$((n + 1))
   1356   echo_i "check that dig +showbadvers works ($n)"
   1357   dig_with_opts @10.53.0.3 +edns=1 +qr +showbadvers a.example >dig.out.test$n 2>&1 || ret=1
   1358   grep "; EDNS: version: 1, flags:; udp: 1232" dig.out.test$n >/dev/null || ret=1
   1359   grep "; EDNS: version: 0, flags:; udp: 1232" dig.out.test$n >/dev/null || ret=1
   1360   grep -F "status: BADVERS" dig.out.test$n >/dev/null || ret=1
   1361   grep -F "status: NOERROR" dig.out.test$n >/dev/null || ret=1
   1362   if [ $ret -ne 0 ]; then echo_i "failed"; fi
   1363   status=$((status + ret))
   1364 
   1365   # See GL#5609
   1366   n=$((n + 1))
   1367   echo_i "check dig with a IPv4 source address and a server with both IPv4 and IPv6 addresses doesn't crash ($n)"
   1368   ret=0
   1369   dig_with_opts @localhost example -b 10.53.0.1 >dig.out.test$n 2>&1 || ret=1
   1370   # We only care about an assertion failure, otherwise reset 'ret' to 0, because
   1371   # @localhost is't really expected to have an answer for our query.
   1372   grep -F "core dumped" dig.out.test$n >/dev/null || ret=0
   1373   if [ $ret -ne 0 ]; then echo_i "failed"; fi
   1374   status=$((status + ret))
   1375 else
   1376   echo_i "$DIG is needed, so skipping these dig tests"
   1377 fi
   1378 
   1379 if [ -x "$MDIG" ]; then
   1380   n=$((n + 1))
   1381   echo_i "checking mdig +tcp works with a source address and port ($n)"
   1382   ret=0
   1383   # When running more than once in quick succession with a source address#port,
   1384   # we can get a "response failed with address not available" error because
   1385   # the address#port is still busy, but we are not interested in that error,
   1386   # as we are only looking for the unexpected error case, that's why we ignore
   1387   # the return code from mdig, but we check for the unexpected error message
   1388   # using grep. See GitLab #4969.
   1389   mdig_with_opts -b "10.53.0.3#${EXTRAPORT8}" +tcp @10.53.0.3 example >dig.out.test$n 2>&1 || true
   1390   grep -F "unexpected error" dig.out.test$n >/dev/null && ret=1
   1391   if [ $ret -ne 0 ]; then echo_i "failed"; fi
   1392   status=$((status + ret))
   1393 
   1394   n=$((n + 1))
   1395   echo_i "check that mdig handles malformed option '+ednsopt=:' gracefully ($n)"
   1396   ret=0
   1397   mdig_with_opts @10.53.0.3 +ednsopt=: a.example >dig.out.test$n 2>&1 && ret=1
   1398   grep "ednsopt no code point specified" dig.out.test$n >/dev/null || ret=1
   1399   if [ $ret -ne 0 ]; then echo_i "failed"; fi
   1400   status=$((status + ret))
   1401 
   1402   n=$((n + 1))
   1403   echo_i "checking mdig +multi +norrcomments works for DNSKEY (when default is rrcomments)($n)"
   1404   ret=0
   1405   mdig_with_opts +tcp @10.53.0.3 +multi +norrcomments -t DNSKEY example >dig.out.test$n || ret=1
   1406   grep "; ZSK; alg = $DEFAULT_ALGORITHM ; key id = $KEYID" dig.out.test$n && ret=1
   1407   if [ $ret -ne 0 ]; then echo_i "failed"; fi
   1408   status=$((status + ret))
   1409 
   1410   n=$((n + 1))
   1411   echo_i "checking mdig +multi +norrcomments works for SOA (when default is rrcomments)($n)"
   1412   ret=0
   1413   mdig_with_opts +tcp @10.53.0.3 +multi +norrcomments -t SOA example >dig.out.test$n || ret=1
   1414   grep "; serial" <dig.out.test$n >/dev/null && ret=1
   1415   if [ $ret -ne 0 ]; then echo_i "failed"; fi
   1416   status=$((status + ret))
   1417 
   1418   if [ $HAS_PYYAML -ne 0 ]; then
   1419     n=$((n + 1))
   1420     echo_i "check mdig +yaml output ($n)"
   1421     ret=0
   1422     mdig_with_opts +yaml @10.53.0.3 -t any ns2.example >dig.out.test$n 2>&1 || ret=1
   1423     $PYTHON yamlget.py dig.out.test$n 0 message response_message_data status >yamlget.out.test$n 2>&1 || ret=1
   1424     read -r value <yamlget.out.test$n
   1425     [ "$value" = "NOERROR" ] || ret=1
   1426     $PYTHON yamlget.py dig.out.test$n 0 message response_message_data QUESTION_SECTION 0 >yamlget.out.test$n 2>&1 || ret=1
   1427     read -r value <yamlget.out.test$n
   1428     [ "$value" = "ns2.example. IN ANY" ] || ret=1
   1429     if [ $ret -ne 0 ]; then echo_i "failed"; fi
   1430     status=$((status + ret))
   1431   fi
   1432 else
   1433   echo_i "$MDIG is needed, so skipping these mdig tests"
   1434 fi
   1435 
   1436 if [ -x "$DELV" ]; then
   1437   n=$((n + 1))
   1438   echo_i "checking delv short form works ($n)"
   1439   ret=0
   1440   delv_with_opts @10.53.0.3 +short a a.example >delv.out.test$n || ret=1
   1441   test "$(wc -l <delv.out.test$n)" -eq 1 || ret=1
   1442   if [ $ret -ne 0 ]; then echo_i "failed"; fi
   1443   status=$((status + ret))
   1444 
   1445   n=$((n + 1))
   1446   echo_i "checking delv split width works ($n)"
   1447   ret=0
   1448   delv_with_opts @10.53.0.3 +split=4 -t sshfp foo.example >delv.out.test$n || ret=1
   1449   grep " 9ABC DEF6 7890 " <delv.out.test$n >/dev/null || ret=1
   1450   check_ttl_range delv.out.test$n "SSHFP" 300 || ret=1
   1451   if [ $ret -ne 0 ]; then echo_i "failed"; fi
   1452   status=$((status + ret))
   1453 
   1454   n=$((n + 1))
   1455   echo_i "checking delv +unknownformat works ($n)"
   1456   ret=0
   1457   delv_with_opts @10.53.0.3 +unknownformat a a.example >delv.out.test$n || ret=1
   1458   grep "CLASS1[ 	][ 	]*TYPE1[ 	][ 	]*\\\\# 4 0A000001" <delv.out.test$n >/dev/null || ret=1
   1459   check_ttl_range delv.out.test$n "TYPE1" 300 || ret=1
   1460   if [ $ret -ne 0 ]; then echo_i "failed"; fi
   1461   status=$((status + ret))
   1462 
   1463   n=$((n + 1))
   1464   echo_i "checking delv -4 -6 ($n)"
   1465   ret=0
   1466   delv_with_opts @10.53.0.3 -4 -6 A a.example >delv.out.test$n 2>&1 && ret=1
   1467   grep "only one of -4 and -6 allowed" <delv.out.test$n >/dev/null || ret=1
   1468   if [ $ret -ne 0 ]; then echo_i "failed"; fi
   1469   status=$((status + ret))
   1470 
   1471   n=$((n + 1))
   1472   echo_i "checking delv with IPv6 on IPv4 does not work ($n)"
   1473   if testsock6 fd92:7065:b8e:ffff::3 2>/dev/null; then
   1474     ret=0
   1475     # following should fail because @IPv4 overrides earlier @IPv6 above
   1476     # and -6 forces IPv6 so this should fail, with a message
   1477     # "Use of IPv4 disabled by -6"
   1478     delv_with_opts @fd92:7065:b8e:ffff::3 @10.53.0.3 -6 -t txt foo.example >delv.out.test$n 2>&1 && ret=1
   1479     # it should have no results but error output
   1480     grep "testing" <delv.out.test$n >/dev/null && ret=1
   1481     grep "Use of IPv4 disabled by -6" delv.out.test$n >/dev/null || ret=1
   1482     if [ $ret -ne 0 ]; then echo_i "failed"; fi
   1483     status=$((status + ret))
   1484   else
   1485     echo_i "IPv6 unavailable; skipping"
   1486   fi
   1487 
   1488   n=$((n + 1))
   1489   echo_i "checking delv with IPv4 on IPv6 does not work ($n)"
   1490   if testsock6 fd92:7065:b8e:ffff::3 2>/dev/null; then
   1491     ret=0
   1492     # following should fail because @IPv6 overrides earlier @IPv4 above
   1493     # and -4 forces IPv4 so this should fail, with a message
   1494     # "Use of IPv6 disabled by -4"
   1495     delv_with_opts @10.53.0.3 @fd92:7065:b8e:ffff::3 -4 -t txt foo.example >delv.out.test$n 2>&1 && ret=1
   1496     # it should have no results but error output
   1497     grep "testing" delv.out.test$n >/dev/null && ret=1
   1498     grep "Use of IPv6 disabled by -4" delv.out.test$n >/dev/null || ret=1
   1499     if [ $ret -ne 0 ]; then echo_i "failed"; fi
   1500     status=$((status + ret))
   1501   else
   1502     echo_i "IPv6 unavailable; skipping"
   1503   fi
   1504 
   1505   n=$((n + 1))
   1506   echo_i "checking delv with reverse lookup works ($n)"
   1507   ret=0
   1508   delv_with_opts @10.53.0.3 -x 127.0.0.1 >delv.out.test$n 2>&1 || ret=1
   1509   # doesn't matter if has answer
   1510   grep -i "127\\.in-addr\\.arpa\\." <delv.out.test$n >/dev/null || ret=1
   1511   check_ttl_range delv.out.test$n '\\-ANY' 10800 3 || ret=1
   1512   if [ $ret -ne 0 ]; then echo_i "failed"; fi
   1513   status=$((status + ret))
   1514 
   1515   n=$((n + 1))
   1516   echo_i "checking delv over TCP works ($n)"
   1517   ret=0
   1518   delv_with_opts +tcp @10.53.0.3 a a.example >delv.out.test$n || ret=1
   1519   grep "10\\.0\\.0\\.1$" <delv.out.test$n >/dev/null || ret=1
   1520   check_ttl_range delv.out.test$n "A" 300 || ret=1
   1521   if [ $ret -ne 0 ]; then echo_i "failed"; fi
   1522   status=$((status + ret))
   1523 
   1524   n=$((n + 1))
   1525   echo_i "checking delv +multi +norrcomments works for DNSKEY (when default is rrcomments)($n)"
   1526   ret=0
   1527   delv_with_opts +tcp @10.53.0.3 +multi +norrcomments DNSKEY example >delv.out.test$n || ret=1
   1528   grep "; ZSK; alg = $DEFAULT_ALGORITHM ; key id = $KEYID" <delv.out.test$n >/dev/null && ret=1
   1529   check_ttl_range delv.out.test$n "DNSKEY" 300 || ret=1
   1530   if [ $ret -ne 0 ]; then echo_i "failed"; fi
   1531   status=$((status + ret))
   1532 
   1533   n=$((n + 1))
   1534   echo_i "checking delv +multi +norrcomments works for SOA (when default is rrcomments)($n)"
   1535   ret=0
   1536   delv_with_opts +tcp @10.53.0.3 +multi +norrcomments SOA example >delv.out.test$n || ret=1
   1537   grep "; ZSK; alg = $DEFAULT_ALGORITHM ; key id = $KEYID" <delv.out.test$n >/dev/null && ret=1
   1538   check_ttl_range delv.out.test$n "SOA" 300 || ret=1
   1539   if [ $ret -ne 0 ]; then echo_i "failed"; fi
   1540   status=$((status + ret))
   1541 
   1542   n=$((n + 1))
   1543   echo_i "checking delv +rrcomments works for DNSKEY($n)"
   1544   ret=0
   1545   delv_with_opts +tcp @10.53.0.3 +rrcomments DNSKEY example >delv.out.test$n || ret=1
   1546   grep "; ZSK; alg = $DEFAULT_ALGORITHM ; key id = $KEYID" <delv.out.test$n >/dev/null || ret=1
   1547   check_ttl_range delv.out.test$n "DNSKEY" 300 || ret=1
   1548   if [ $ret -ne 0 ]; then echo_i "failed"; fi
   1549   status=$((status + ret))
   1550 
   1551   n=$((n + 1))
   1552   echo_i "checking delv +short +rrcomments works for DNSKEY ($n)"
   1553   ret=0
   1554   delv_with_opts +tcp @10.53.0.3 +short +rrcomments DNSKEY example >delv.out.test$n || ret=1
   1555   grep "; ZSK; alg = $DEFAULT_ALGORITHM ; key id = $KEYID" <delv.out.test$n >/dev/null || ret=1
   1556   if [ $ret -ne 0 ]; then echo_i "failed"; fi
   1557   status=$((status + ret))
   1558 
   1559   n=$((n + 1))
   1560   echo_i "checking delv +short +rrcomments works ($n)"
   1561   ret=0
   1562   delv_with_opts +tcp @10.53.0.3 +short +rrcomments DNSKEY example >delv.out.test$n || ret=1
   1563   grep -q "$KEYDATA  ; ZSK; alg = $DEFAULT_ALGORITHM ; key id = $KEYID" <delv.out.test$n || ret=1
   1564   if [ $ret -ne 0 ]; then echo_i "failed"; fi
   1565   status=$((status + ret))
   1566 
   1567   n=$((n + 1))
   1568   echo_i "checking delv +short +nosplit works ($n)"
   1569   ret=0
   1570   delv_with_opts +tcp @10.53.0.3 +short +nosplit DNSKEY example >delv.out.test$n || ret=1
   1571   grep -q "$NOSPLIT" <delv.out.test$n || ret=1
   1572   test "$(wc -l <delv.out.test$n)" -eq 1 || ret=1
   1573   test "$(awk '{print NF}' <delv.out.test$n)" -eq 14 || ret=1
   1574   if [ $ret -ne 0 ]; then echo_i "failed"; fi
   1575   status=$((status + ret))
   1576 
   1577   n=$((n + 1))
   1578   echo_i "checking delv +short +nosplit +norrcomments works ($n)"
   1579   ret=0
   1580   delv_with_opts +tcp @10.53.0.3 +short +nosplit +norrcomments DNSKEY example >delv.out.test$n || ret=1
   1581   grep -q "$NOSPLIT\$" <delv.out.test$n || ret=1
   1582   test "$(wc -l <delv.out.test$n)" -eq 1 || ret=1
   1583   test "$(awk '{print NF}' <delv.out.test$n)" -eq 4 || ret=1
   1584   if [ $ret -ne 0 ]; then echo_i "failed"; fi
   1585   status=$((status + ret))
   1586 
   1587   n=$((n + 1))
   1588   echo_i "checking delv +sp works as an abbriviated form of split ($n)"
   1589   ret=0
   1590   delv_with_opts @10.53.0.3 +sp=4 -t sshfp foo.example >delv.out.test$n || ret=1
   1591   grep " 9ABC DEF6 7890 " <delv.out.test$n >/dev/null || ret=1
   1592   check_ttl_range delv.out.test$n "SSHFP" 300 || ret=1
   1593   if [ $ret -ne 0 ]; then echo_i "failed"; fi
   1594   status=$((status + ret))
   1595 
   1596   n=$((n + 1))
   1597   echo_i "checking delv +sh works as an abbriviated form of short ($n)"
   1598   ret=0
   1599   delv_with_opts @10.53.0.3 +sh a a.example >delv.out.test$n || ret=1
   1600   test "$(wc -l <delv.out.test$n)" -eq 1 || ret=1
   1601   if [ $ret -ne 0 ]; then echo_i "failed"; fi
   1602   status=$((status + ret))
   1603 
   1604   n=$((n + 1))
   1605   echo_i "checking delv -c IN works ($n)"
   1606   ret=0
   1607   delv_with_opts @10.53.0.3 -c IN -t a a.example >delv.out.test$n || ret=1
   1608   grep "a.example." <delv.out.test$n >/dev/null || ret=1
   1609   check_ttl_range delv.out.test$n "A" 300 || ret=1
   1610   if [ $ret -ne 0 ]; then echo_i "failed"; fi
   1611   status=$((status + ret))
   1612 
   1613   n=$((n + 1))
   1614   echo_i "checking delv -c CH is ignored, and treated like IN ($n)"
   1615   ret=0
   1616   delv_with_opts @10.53.0.3 -c CH -t a a.example >delv.out.test$n || ret=1
   1617   grep "a.example." <delv.out.test$n >/dev/null || ret=1
   1618   check_ttl_range delv.out.test$n "A" 300 || ret=1
   1619   if [ $ret -ne 0 ]; then echo_i "failed"; fi
   1620   status=$((status + ret))
   1621 
   1622   n=$((n + 1))
   1623   echo_i "checking delv -c CH is ignored, and treated like IN ($n)"
   1624   ret=0
   1625   delv_with_opts @10.53.0.3 -c CH -t a a.example >delv.out.test$n || ret=1
   1626   grep "a.example." <delv.out.test$n >/dev/null || ret=1
   1627   check_ttl_range delv.out.test$n "A" 300 || ret=1
   1628   if [ $ret -ne 0 ]; then echo_i "failed"; fi
   1629   status=$((status + ret))
   1630 
   1631   n=$((n + 1))
   1632   echo_i "check that delv -q -m works ($n)"
   1633   ret=0
   1634   delv_with_opts @10.53.0.3 -q -m >delv.out.test$n 2>&1 || ret=1
   1635   grep '^; -m\..*[0-9]*.*IN.*ANY.*;' delv.out.test$n >/dev/null || ret=1
   1636   grep "^add " delv.out.test$n >/dev/null && ret=1
   1637   grep "^del " delv.out.test$n >/dev/null && ret=1
   1638   check_ttl_range delv.out.test$n '\\-ANY' 300 3 || ret=1
   1639   if [ $ret -ne 0 ]; then echo_i "failed"; fi
   1640   status=$((status + ret))
   1641 
   1642   n=$((n + 1))
   1643   echo_i "check that delv -t ANY works ($n)"
   1644   ret=0
   1645   delv_with_opts @10.53.0.3 -t ANY example >delv.out.test$n 2>&1 || ret=1
   1646   grep "^example." <delv.out.test$n >/dev/null || ret=1
   1647   check_ttl_range delv.out.test$n NS 300 || ret=1
   1648   check_ttl_range delv.out.test$n SOA 300 || ret=1
   1649   if [ $ret -ne 0 ]; then echo_i "failed"; fi
   1650   status=$((status + ret))
   1651 
   1652   n=$((n + 1))
   1653   echo_i "check that delv loads key-style trust anchors ($n)"
   1654   ret=0
   1655   delv_with_opts -a ns3/anchor.dnskey +root=example @10.53.0.3 -t DNSKEY example >delv.out.test$n 2>&1 || ret=1
   1656   grep "fully validated" delv.out.test$n >/dev/null || ret=1
   1657   if [ $ret -ne 0 ]; then echo_i "failed"; fi
   1658   status=$((status + ret))
   1659 
   1660   n=$((n + 1))
   1661   echo_i "check that delv loads DS-style trust anchors ($n)"
   1662   ret=0
   1663   delv_with_opts -a ns3/anchor.ds +root=example @10.53.0.3 -t DNSKEY example >delv.out.test$n 2>&1 || ret=1
   1664   grep "fully validated" delv.out.test$n >/dev/null || ret=1
   1665   if [ $ret -ne 0 ]; then echo_i "failed"; fi
   1666   status=$((status + ret))
   1667 
   1668   if [ $HAS_PYYAML -ne 0 ]; then
   1669     n=$((n + 1))
   1670     echo_i "check delv +yaml ANY output ($n)"
   1671     ret=0
   1672     delv_with_opts +yaml @10.53.0.3 any ns2.example >delv.out.test$n || ret=1
   1673     $PYTHON yamlget.py delv.out.test$n status >yamlget.out.test$n 2>&1 || ret=1
   1674     read -r value <yamlget.out.test$n
   1675     [ "$value" = "success" ] || ret=1
   1676     $PYTHON yamlget.py delv.out.test$n query_name >yamlget.out.test$n 2>&1 || ret=1
   1677     read -r value <yamlget.out.test$n
   1678     [ "$value" = "ns2.example" ] || ret=1
   1679     $PYTHON yamlget.py delv.out.test$n records 0 answer_not_validated 0 >yamlget.out.test$n 2>&1 || ret=1
   1680     read -r value <yamlget.out.test$n
   1681     count=$(echo $value | wc -w)
   1682     [ ${count:-0} -eq 5 ] || ret=1
   1683     if [ $ret -ne 0 ]; then echo_i "failed"; fi
   1684     status=$((status + ret))
   1685 
   1686     n=$((n + 1))
   1687     echo_i "check delv +yaml NODATA output ($n)"
   1688     ret=0
   1689     delv_with_opts +yaml @10.53.0.3 type500 ns2.example >delv.out.test$n || ret=1
   1690     $PYTHON yamlget.py delv.out.test$n status >yamlget.out.test$n 2>&1 || ret=1
   1691     read -r value <yamlget.out.test$n
   1692     [ "$value" = "ncache nxrrset" ] || ret=1
   1693     $PYTHON yamlget.py delv.out.test$n query_name >yamlget.out.test$n 2>&1 || ret=1
   1694     read -r value <yamlget.out.test$n
   1695     [ "$value" = "ns2.example" ] || ret=1
   1696     $PYTHON yamlget.py delv.out.test$n records 0 negative_response_answer_not_validated 0 >yamlget.out.test$n 2>&1 || ret=1
   1697     read -r value <yamlget.out.test$n
   1698     count=$(echo $value | wc -w)
   1699     [ ${count:-0} -eq 5 ] || ret=1
   1700     if [ $ret -ne 0 ]; then echo_i "failed"; fi
   1701     status=$((status + ret))
   1702 
   1703     n=$((n + 1))
   1704     echo_i "check delv +yaml NXDOMAIN output ($n)"
   1705     ret=0
   1706     delv_with_opts +yaml @10.53.0.3 a this-does-not-exist.ns2.example >delv.out.test$n || ret=1
   1707     $PYTHON yamlget.py delv.out.test$n status >yamlget.out.test$n 2>&1 || ret=1
   1708     read -r value <yamlget.out.test$n
   1709     [ "$value" = "ncache nxdomain" ] || ret=1
   1710     $PYTHON yamlget.py delv.out.test$n query_name >yamlget.out.test$n 2>&1 || ret=1
   1711     read -r value <yamlget.out.test$n
   1712     [ "$value" = "this-does-not-exist.ns2.example" ] || ret=1
   1713     $PYTHON yamlget.py delv.out.test$n records 0 negative_response_answer_not_validated 0 >yamlget.out.test$n 2>&1 || ret=1
   1714     read -r value <yamlget.out.test$n
   1715     count=$(echo $value | wc -w)
   1716     [ ${count:-0} -eq 5 ] || ret=1
   1717     if [ $ret -ne 0 ]; then echo_i "failed"; fi
   1718     status=$((status + ret))
   1719   fi
   1720 
   1721   n=$((n + 1))
   1722   echo_i "check that delv handles REFUSED when chasing DS records ($n)"
   1723   delv_with_opts @10.53.0.2 +root xxx.example.tld A >delv.out.test$n 2>&1 || ret=1
   1724   grep ";; resolution failed: broken trust chain" delv.out.test$n >/dev/null || ret=1
   1725   if [ $ret -ne 0 ]; then echo_i "failed"; fi
   1726   status=$((status + ret))
   1727 
   1728   n=$((n + 1))
   1729   echo_i "check NS output from delv +ns ($n)"
   1730   ret=0
   1731   delv_with_opts -i +ns +nortrace +nostrace +nomtrace +novtrace +hint=root.hint ns example >delv.out.test$n || ret=1
   1732   lines=$(awk '$1 == "example." && $4 == "NS" {print}' delv.out.test$n | wc -l)
   1733   [ $lines -eq 2 ] || ret=1
   1734   status=$((status + ret))
   1735 
   1736   n=$((n + 1))
   1737   echo_i "checking delv +ns (no validation) ($n)"
   1738   ret=0
   1739   delv_with_opts -i +ns +hint=root.hint a a.example >delv.out.test$n || ret=1
   1740   grep -q '; authoritative' delv.out.test$n || ret=1
   1741   grep -q '_.example' delv.out.test$n && ret=1
   1742   if [ $ret -ne 0 ]; then echo_i "failed"; fi
   1743   status=$((status + ret))
   1744 
   1745   n=$((n + 1))
   1746   echo_i "checking delv +ns +qmin (no validation) ($n)"
   1747   ret=0
   1748   delv_with_opts -i +ns +qmin +hint=root.hint a a.example >delv.out.test$n || ret=1
   1749   grep -q '; authoritative' delv.out.test$n || ret=1
   1750   if [ $ret -ne 0 ]; then echo_i "failed"; fi
   1751   status=$((status + ret))
   1752 
   1753   n=$((n + 1))
   1754   echo_i "checking delv +ns (with validation) ($n)"
   1755   ret=0
   1756   delv_with_opts -a ns1/anchor.dnskey +root +ns +hint=root.hint a a.example >delv.out.test$n || ret=1
   1757   grep -q '; fully validated' delv.out.test$n || ret=1
   1758   grep -q '_.example' delv.out.test$n && ret=1
   1759   if [ $ret -ne 0 ]; then echo_i "failed"; fi
   1760   status=$((status + ret))
   1761 
   1762   n=$((n + 1))
   1763   echo_i "checking delv +ns +qmin (with validation) ($n)"
   1764   ret=0
   1765   delv_with_opts -a ns1/anchor.dnskey +root +ns +qmin +hint=root.hint a a.example >delv.out.test$n || ret=1
   1766   grep -q '; fully validated' delv.out.test$n || ret=1
   1767   if [ $ret -ne 0 ]; then echo_i "failed"; fi
   1768   status=$((status + ret))
   1769 
   1770   if testsock6 fd92:7065:b8e:ffff::2 2>/dev/null; then
   1771     n=$((n + 1))
   1772     echo_i "checking delv -4 +ns uses only IPv4 ($n)"
   1773     ret=0
   1774     delv_with_opts -a ns1/anchor.dnskey +root -4 +ns +hint=root.hint a a.example >delv.out.test$n || ret=1
   1775     grep -qF 'sending packet to 10.53' delv.out.test$n >/dev/null || ret=1
   1776     grep -qF 'sending packet to fd92:7065' delv.out.test$n >/dev/null && ret=1
   1777     if [ $ret -ne 0 ]; then echo_i "failed"; fi
   1778     status=$((status + ret))
   1779 
   1780     n=$((n + 1))
   1781     echo_i "checking delv -6 +ns uses only IPv6 ($n)"
   1782     ret=0
   1783     delv_with_opts -a ns1/anchor.dnskey +root -6 +ns +hint=root.hint a a.example >delv.out.test$n || ret=1
   1784     grep -qF 'sending packet to 10.53' delv.out.test$n >/dev/null && ret=1
   1785     grep -qF 'sending packet to fd92:7065' delv.out.test$n >/dev/null || ret=1
   1786     if [ $ret -ne 0 ]; then echo_i "failed"; fi
   1787     status=$((status + ret))
   1788   fi
   1789 
   1790 else
   1791   echo_i "$DELV is needed, so skipping these delv tests"
   1792 fi
   1793 
   1794 if [ $HAS_PYYAML -ne 0 ]; then
   1795   for qname in "yaml" "'.yaml" "[.yaml" "{.yaml" "&.yaml" "#.yaml"; do
   1796     n=$((n + 1))
   1797     echo_i "check yaml special '${yaml}.example' ($n)"
   1798     ret=0
   1799     dig_with_opts @10.53.0.3 +yaml "${qname}.example" TXT +qr >dig.out.test$n 2>&1 || ret=1
   1800     $PYTHON yamlget.py dig.out.test$n 0 message query_message_data QUESTION_SECTION 0 >yamlget.out.test$n 2>&1 || ret=1
   1801     read -r value <yamlget.out.test$n
   1802     [ "$value" = "${qname}.example. IN TXT" ] || ret=1
   1803     $PYTHON yamlget.py dig.out.test$n 1 message response_message_data ANSWER_SECTION 0 >yamlget.out.test$n 2>&1 || ret=1
   1804     read -r value <yamlget.out.test$n
   1805     [ "$value" = "${qname}"'.example. 300 IN TXT "a: b"' ] || ret=1
   1806     if [ $ret -ne 0 ]; then echo_i "failed"; fi
   1807     status=$((status + ret))
   1808   done
   1809 
   1810   n=$((n + 1))
   1811   echo_i "check yaml character values ($n)"
   1812   ret=0
   1813   dig_with_opts @10.53.0.3 +yaml "all.yaml.example" TXT +qr >dig.out.test$n 2>&1 || ret=1
   1814   $PYTHON yamlget.py dig.out.test$n 1 message response_message_data ANSWER_SECTION 0 >yamlget.out.test$n 2>&1 || ret=1
   1815   read -r value <yamlget.out.test$n
   1816   expected='all.yaml.example. 300 IN TXT'
   1817   expected="$expected "'"\000" "\001" "\002" "\003" "\004" "\005" "\006" "\007"'
   1818   expected="$expected "'"\008" "\009" "\010" "\011" "\012" "\013" "\014" "\015"'
   1819   expected="$expected "'"\016" "\017" "\018" "\019" "\020" "\021" "\022" "\023"'
   1820   expected="$expected "'"\024" "\025" "\026" "\027" "\028" "\029" "\030" "\031"'
   1821   expected="$expected "'" " "!" "\"" "#" "$" "%" "&" "'"'"'" "(" ")" "*" "+" ","'
   1822   expected="$expected "'"-" "." "/" "0" "1" "2" "3" "4" "5" "6" "7" "8" "9" ":"'
   1823   expected="$expected "'";" "<" "=" ">" "?" "@" "A" "B" "C" "D" "E" "F" "G" "H"'
   1824   expected="$expected "'"I" "J" "K" "L" "M" "N" "O" "P" "Q" "R" "S" "T" "U" "V"'
   1825   expected="$expected "'"W" "X" "Y" "Z" "[" "\\" "]" "^" "_" "`" "a" "b" "c" "d"'
   1826   expected="$expected "'"e" "f" "g" "h" "i" "j" "k" "l" "m" "n" "o" "p" "q" "r"'
   1827   expected="$expected "'"s" "t" "u" "v" "w" "x" "y" "z" "{" "|" "}" "~" "\127"'
   1828   expected="$expected "'"\128" "\129" "\130" "\131" "\132" "\133" "\134" "\135"'
   1829   expected="$expected "'"\136" "\137" "\138" "\139" "\140" "\141" "\142" "\143"'
   1830   expected="$expected "'"\144" "\145" "\146" "\147" "\148" "\149" "\150" "\151"'
   1831   expected="$expected "'"\152" "\153" "\154" "\155" "\156" "\157" "\158" "\159"'
   1832   expected="$expected "'"\160" "\161" "\162" "\163" "\164" "\165" "\166" "\167"'
   1833   expected="$expected "'"\168" "\169" "\170" "\171" "\172" "\173" "\174" "\175"'
   1834   expected="$expected "'"\176" "\177" "\178" "\179" "\180" "\181" "\182" "\183"'
   1835   expected="$expected "'"\184" "\185" "\186" "\187" "\188" "\189" "\190" "\191"'
   1836   expected="$expected "'"\192" "\193" "\194" "\195" "\196" "\197" "\198" "\199"'
   1837   expected="$expected "'"\200" "\201" "\202" "\203" "\204" "\205" "\206" "\207"'
   1838   expected="$expected "'"\208" "\209" "\210" "\211" "\212" "\213" "\214" "\215"'
   1839   expected="$expected "'"\216" "\217" "\218" "\219" "\220" "\221" "\222" "\223"'
   1840   expected="$expected "'"\224" "\225" "\226" "\227" "\228" "\229" "\230" "\231"'
   1841   expected="$expected "'"\232" "\233" "\234" "\235" "\236" "\237" "\238" "\239"'
   1842   expected="$expected "'"\240" "\241" "\242" "\243" "\244" "\245" "\246" "\247"'
   1843   expected="$expected "'"\248" "\249" "\250" "\251" "\252" "\253" "\254" "\255"'
   1844   [ "$value" = "$expected" ] || ret=1
   1845   if [ $ret -ne 0 ]; then echo_i "failed"; fi
   1846   status=$((status + ret))
   1847 fi
   1848 
   1849 echo_i "exit status: $status"
   1850 [ $status -eq 0 ] || exit 1
   1851