$PYTHON -c "import yaml" 2>/dev/null && HAS_PYYAML=1
if [ -x "$DIG" ]; then
- n=$((n + 1))
- echo_i "checking dig +coflag works ($n)"
- ret=0
- dig_with_opts +tcp @10.53.0.3 +coflag +qr example >dig.out.test$n || ret=1
- grep "^; EDNS: version: 0, flags: co;" <dig.out.test$n >/dev/null || ret=1
- check_ttl_range dig.out.test$n "SOA" 300 || ret=1
- if [ $ret -ne 0 ]; then echo_i "failed"; fi
- status=$((status + ret))
-
- if [ $HAS_PYYAML -ne 0 ]; then
- n=$((n + 1))
- echo_i "checking dig +coflag +yaml works ($n)"
- ret=0
- dig_with_opts +yaml +tcp @10.53.0.3 +coflag +qr example >dig.out.test$n || ret=1
- $PYTHON yamlget.py dig.out.test$n 0 message query_message_data OPT_PSEUDOSECTION EDNS flags >yamlget.out.test$n 2>&1 || ret=1
- read -r value <yamlget.out.test$n
- [ "$value" = "co" ] || ret=1
- if [ $ret -ne 0 ]; then echo_i "failed"; fi
- status=$((status + ret))
- fi
-
- n=$((n + 1))
- echo_i "checking dig +raflag works ($n)"
- ret=0
- dig_with_opts +tcp @10.53.0.3 +raflag +qr example >dig.out.test$n || ret=1
- grep "^;; flags: rd ra ad; QUERY: 1, ANSWER: 0," <dig.out.test$n >/dev/null || ret=1
- grep "^;; flags: qr rd ra; QUERY: 1, ANSWER: 0," <dig.out.test$n >/dev/null || ret=1
- check_ttl_range dig.out.test$n "SOA" 300 || ret=1
- if [ $ret -ne 0 ]; then echo_i "failed"; fi
- status=$((status + ret))
-
- n=$((n + 1))
- echo_i "checking dig +tcflag works ($n)"
- ret=0
- dig_with_opts +tcp @10.53.0.3 +tcflag +qr example >dig.out.test$n || ret=1
- grep "^;; flags: tc rd ad; QUERY: 1, ANSWER: 0" <dig.out.test$n >/dev/null || ret=1
- grep "^;; flags: qr rd ra; QUERY: 1, ANSWER: 0," <dig.out.test$n >/dev/null || ret=1
- check_ttl_range dig.out.test$n "SOA" 300 || ret=1
- if [ $ret -ne 0 ]; then echo_i "failed"; fi
- status=$((status + ret))
-
- n=$((n + 1))
- echo_i "checking dig +zflag works, and that BIND properly ignores it ($n)"
- ret=0
- dig_with_opts +tcp @10.53.0.3 +zflag +qr A example >dig.out.test$n || ret=1
- sed -n '/Sending:/,/Got answer:/p' dig.out.test$n | grep "^;; flags: rd ad; MBZ: 0x4;" >/dev/null || ret=1
- sed -n '/Got answer:/,/AUTHORITY SECTION:/p' dig.out.test$n | grep "^;; flags: qr rd ra; QUERY: 1" >/dev/null || ret=1
- check_ttl_range dig.out.test$n "SOA" 300 || ret=1
- if [ $ret -ne 0 ]; then echo_i "failed"; fi
- status=$((status + ret))
-
- n=$((n + 1))
- echo_i "checking dig +qr +ednsopt=08 does not cause an INSIST failure ($n)"
- ret=0
- dig_with_opts @10.53.0.3 +ednsopt=08 +qr a a.example >dig.out.test$n || ret=1
- grep "INSIST" <dig.out.test$n >/dev/null && ret=1
- grep "FORMERR" <dig.out.test$n >/dev/null || ret=1
- if [ $ret -ne 0 ]; then echo_i "failed"; fi
- status=$((status + ret))
-
n=$((n + 1))
echo_i "checking dig preserves origin on TCP retries ($n)"
ret=0
status=$((status + ret))
n=$((n + 1))
- echo_i "checking dig +ednsopt with option number ($n)"
- ret=0
- dig_with_opts @10.53.0.3 +ednsopt=3 a.example >dig.out.test$n 2>&1 || ret=1
- grep 'NSID: .* ("ns3")' dig.out.test$n >/dev/null || ret=1
- check_ttl_range dig.out.test$n "A" 300 || ret=1
- if [ $ret -ne 0 ]; then echo_i "failed"; fi
- status=$((status + ret))
-
- n=$((n + 1))
- echo_i "checking dig +ednsopt with option name ($n)"
- ret=0
- dig_with_opts @10.53.0.3 +ednsopt=nsid a.example >dig.out.test$n 2>&1 || ret=1
- grep 'NSID: .* ("ns3")' dig.out.test$n >/dev/null || ret=1
- check_ttl_range dig.out.test$n "A" 300 || ret=1
- if [ $ret -ne 0 ]; then echo_i "failed"; fi
- status=$((status + ret))
-
- n=$((n + 1))
- echo_i "checking ednsopt UPDATE-LEASE prints as expected (single lease) ($n)"
- ret=0
- dig_with_opts @10.53.0.3 +ednsopt=UPDATE-LEASE:00000e10 +qr a.example >dig.out.test$n 2>&1 || ret=1
- pat='UPDATE-LEASE: 3600 (1 hour)'
- grep "$pat" dig.out.test$n >/dev/null || ret=1
- if [ $ret -ne 0 ]; then echo_i "failed"; fi
- status=$((status + ret))
- n=$((n + 1))
-
- if [ $HAS_PYYAML -ne 0 ]; then
- n=$((n + 1))
- echo_i "checking ednsopt UPDATE-LEASE prints as expected (single lease) +yaml ($n)"
- ret=0
- dig_with_opts @10.53.0.3 +yaml +ednsopt=UPDATE-LEASE:00000e10 +qr a.example >dig.out.test$n 2>&1 || ret=1
- $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
- read -r value <yamlget.out.test$n
- [ "$value" = "3600" ] || ret=1
- grep "LEASE: 3600 # 1 hour" dig.out.test$n >/dev/null || ret=1
- if [ $ret -ne 0 ]; then echo_i "failed"; fi
- status=$((status + ret))
- fi
-
- n=$((n + 1))
- echo_i "checking ednsopt UPDATE-LEASE prints as expected (split lease) ($n)"
- ret=0
- dig_with_opts @10.53.0.3 +ednsopt=UPDATE-LEASE:00000e1000127500 +qr a.example >dig.out.test$n 2>&1 || ret=1
- pat='UPDATE-LEASE: 3600/1209600 (1 hour/2 weeks)'
- grep "$pat" dig.out.test$n >/dev/null || ret=1
- if [ $ret -ne 0 ]; then echo_i "failed"; fi
- status=$((status + ret))
-
- if [ $HAS_PYYAML -ne 0 ]; then
- n=$((n + 1))
- echo_i "checking ednsopt UPDATE-LEASE prints as expected (split lease) +yaml ($n)"
- ret=0
- dig_with_opts @10.53.0.3 +yaml +ednsopt=UPDATE-LEASE:00000e1000127500 +qr a.example >dig.out.test$n 2>&1 || ret=1
- $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
- read -r value <yamlget.out.test$n
- [ "$value" = "3600" ] || ret=1
- grep "LEASE: 3600 # 1 hour" dig.out.test$n >/dev/null || ret=1
- $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
- read -r value <yamlget.out.test$n
- [ "$value" = "1209600" ] || ret=1
- grep "KEY-LEASE: 1209600 # 2 weeks" dig.out.test$n >/dev/null || ret=1
- if [ $ret -ne 0 ]; then echo_i "failed"; fi
- status=$((status + ret))
- fi
-
- echo_i "checking ednsopt LLQ prints as expected ($n)"
- ret=0
- dig_with_opts @10.53.0.3 +ednsopt=llq:0001000200001234567812345678fefefefe +qr a.example >dig.out.test$n 2>&1 || ret=1
- pat='LLQ: Version: 1, Opcode: 2, Error: 0, Identifier: 1311768465173141112, Lifetime: 4278124286$'
- grep "$pat" dig.out.test$n >/dev/null || ret=1
- if [ $ret -ne 0 ]; then echo_i "failed"; fi
- status=$((status + ret))
-
- if [ $HAS_PYYAML -ne 0 ]; then
- n=$((n + 1))
- echo_i "checking ednsopt LLQ prints as expected +yaml ($n)"
- ret=0
- dig_with_opts @10.53.0.3 +yaml +ednsopt=llq:0001000200001234567812345678fefefefe +qr a.example >dig.out.test$n 2>&1 || ret=1
- $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
- read -r value <yamlget.out.test$n
- [ "$value" = "1" ] || ret=1
- $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
- read -r value <yamlget.out.test$n
- [ "$value" = "2" ] || ret=1
- $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
- read -r value <yamlget.out.test$n
- [ "$value" = "0" ] || ret=1
- $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
- read -r value <yamlget.out.test$n
- [ "$value" = "1311768465173141112" ] || ret=1
- $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
- read -r value <yamlget.out.test$n
- [ "$value" = "4278124286" ] || ret=1
- if [ $ret -ne 0 ]; then echo_i "failed"; fi
- status=$((status + ret))
- fi
-
- n=$((n + 1))
- echo_i "check that dig processes +ednsopt=key-tag and FORMERR is returned ($n)"
- ret=0
- dig_with_opts @10.53.0.3 +ednsopt=key-tag a.example +qr >dig.out.test$n 2>&1 || ret=1
- grep "; KEY-TAG: *$" dig.out.test$n >/dev/null || ret=1
- grep "status: FORMERR" dig.out.test$n >/dev/null || ret=1
- if [ $ret -ne 0 ]; then echo_i "failed"; fi
- status=$((status + ret))
-
- n=$((n + 1))
- echo_i "check that dig processes +ednsopt=key-tag:<value-list> ($n)"
- ret=0
- dig_with_opts @10.53.0.3 +ednsopt=key-tag:00010002 a.example +qr >dig.out.test$n 2>&1 || ret=1
- grep "; KEY-TAG: 1, 2$" dig.out.test$n >/dev/null || ret=1
- grep "status: FORMERR" dig.out.test$n >/dev/null && ret=1
- check_ttl_range dig.out.test$n "A" 300 || ret=1
- if [ $ret -ne 0 ]; then echo_i "failed"; fi
- status=$((status + ret))
-
- if [ $HAS_PYYAML -ne 0 ]; then
- n=$((n + 1))
- ret=0
- echo_i "check that dig processes +ednsopt=key-tag:<value-list> +yaml ($n)"
- dig_with_opts @10.53.0.3 +yaml +ednsopt=key-tag:00010002 a.example +qr >dig.out.test$n 2>&1 || ret=1
- $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
- read -r value <yamlget.out.test$n
- [ "$value" = "[1, 2]" ] || ret=1
- if [ $ret -ne 0 ]; then echo_i "failed"; fi
- status=$((status + ret))
- fi
-
- n=$((n + 1))
- echo_i "check that dig processes +ednsopt=key-tag:<malformed-value-list> and FORMERR is returned ($n)"
- ret=0
- dig_with_opts @10.53.0.3 +ednsopt=key-tag:0001000201 a.example +qr >dig.out.test$n 2>&1 || ret=1
- grep "; KEY-TAG: 00 01 00 02 01" dig.out.test$n >/dev/null || ret=1
- grep "status: FORMERR" dig.out.test$n >/dev/null || ret=1
- if [ $ret -ne 0 ]; then echo_i "failed"; fi
- status=$((status + ret))
-
- n=$((n + 1))
- echo_i "check that dig processes +ednsopt=client-tag:value ($n)"
- ret=0
- dig_with_opts @10.53.0.3 +ednsopt=client-tag:0001 a.example +qr >dig.out.test$n 2>&1 || ret=1
- grep "; CLIENT-TAG: 1$" dig.out.test$n >/dev/null || ret=1
- grep "status: FORMERR" dig.out.test$n >/dev/null && ret=1
- if [ $ret -ne 0 ]; then echo_i "failed"; fi
- status=$((status + ret))
-
- if [ $HAS_PYYAML -ne 0 ]; then
- n=$((n + 1))
- echo_i "check that dig processes +ednsopt=client-tag:value +yaml ($n)"
- ret=0
- dig_with_opts @10.53.0.3 +yaml +ednsopt=client-tag:0001 a.example +qr >dig.out.test$n 2>&1 || ret=1
- $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
- read -r value <yamlget.out.test$n
- [ "$value" = "1" ] || ret=1
- if [ $ret -ne 0 ]; then echo_i "failed"; fi
- status=$((status + ret))
- fi
-
- n=$((n + 1))
- echo_i "check that FORMERR is returned for a too short client-tag ($n)"
- ret=0
- dig_with_opts @10.53.0.3 +ednsopt=client-tag:01 a.example +qr >dig.out.test$n 2>&1 || ret=1
- grep "; CLIENT-TAG" dig.out.test$n >/dev/null || ret=1
- grep "status: FORMERR" dig.out.test$n >/dev/null || ret=1
- if [ $ret -ne 0 ]; then echo_i "failed"; fi
- status=$((status + ret))
-
- n=$((n + 1))
- echo_i "check that FORMERR is returned for a too long client-tag ($n)"
- ret=0
- dig_with_opts @10.53.0.3 +ednsopt=client-tag:000001 a.example +qr >dig.out.test$n 2>&1 || ret=1
- grep "; CLIENT-TAG" dig.out.test$n >/dev/null || ret=1
- grep "status: FORMERR" dig.out.test$n >/dev/null || ret=1
- if [ $ret -ne 0 ]; then echo_i "failed"; fi
- status=$((status + ret))
-
- n=$((n + 1))
- echo_i "check that dig processes +ednsopt=server-tag:value ($n)"
- ret=0
- dig_with_opts @10.53.0.3 +ednsopt=server-tag:0001 a.example +qr >dig.out.test$n 2>&1 || ret=1
- grep "; SERVER-TAG: 1$" dig.out.test$n >/dev/null || ret=1
- grep "status: FORMERR" dig.out.test$n >/dev/null && ret=1
- if [ $ret -ne 0 ]; then echo_i "failed"; fi
- status=$((status + ret))
-
- if [ $HAS_PYYAML -ne 0 ]; then
- n=$((n + 1))
- echo_i "check that dig processes +ednsopt=server-tag:value +yaml ($n)"
- ret=0
- dig_with_opts @10.53.0.3 +yaml +ednsopt=server-tag:0001 a.example +qr >dig.out.test$n 2>&1 || ret=1
- $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
- read -r value <yamlget.out.test$n
- [ "$value" = "1" ] || ret=1
- if [ $ret -ne 0 ]; then echo_i "failed"; fi
- status=$((status + ret))
- fi
-
- n=$((n + 1))
- echo_i "check that FORMERR is returned for a too short server-tag ($n)"
- ret=0
- dig_with_opts @10.53.0.3 +ednsopt=server-tag:01 a.example +qr >dig.out.test$n 2>&1 || ret=1
- grep "; SERVER-TAG" dig.out.test$n >/dev/null || ret=1
- grep "status: FORMERR" dig.out.test$n >/dev/null || ret=1
- if [ $ret -ne 0 ]; then echo_i "failed"; fi
- status=$((status + ret))
-
- n=$((n + 1))
- echo_i "check that FORMERR is returned for a too long server-tag ($n)"
- ret=0
- dig_with_opts @10.53.0.3 +ednsopt=server-tag:000001 a.example +qr >dig.out.test$n 2>&1 || ret=1
- grep "; SERVER-TAG" dig.out.test$n >/dev/null || ret=1
- grep "status: FORMERR" dig.out.test$n >/dev/null || ret=1
- if [ $ret -ne 0 ]; then echo_i "failed"; fi
- status=$((status + ret))
-
- n=$((n + 1))
- echo_i "check that dig processes +ednsopt=chain:02002200 ($n)"
- ret=0
- dig_with_opts @10.53.0.3 +ednsopt=chain:02002200 'a.\000"' +qr >dig.out.test$n 2>&1 || ret=1
- grep '; CHAIN: "\\000\\""' dig.out.test$n >/dev/null || ret=1
- if [ $ret -ne 0 ]; then echo_i "failed"; fi
- status=$((status + ret))
-
- if [ $HAS_PYYAML -ne 0 ]; then
- n=$((n + 1))
- echo_i "check that dig processes +ednsopt=chain:02002200 +yaml ($n)"
- ret=0
- dig_with_opts @10.53.0.3 +yaml +ednsopt=chain:02002200 'a.\000"' +qr >dig.out.test$n 2>&1 || ret=1
- $PYTHON yamlget.py dig.out.test$n 0 message query_message_data OPT_PSEUDOSECTION EDNS CHAIN >yamlget.out.test$n 2>&1 || ret=1
- read -r value <yamlget.out.test$n
- [ "$value" = '\000\"' ] || ret=1
- if [ $ret -ne 0 ]; then echo_i "failed"; fi
- status=$((status + ret))
- fi
-
- n=$((n + 1))
- echo_i "check that dig processes +expire ($n)"
- ret=0
- dig_with_opts @10.53.0.1 +expire . soa >dig.out.test$n 2>&1 || ret=1
- grep '; EXPIRE: 1200 (20 minutes)' dig.out.test$n >/dev/null || ret=1
- if [ $ret -ne 0 ]; then echo_i "failed"; fi
- status=$((status + ret))
-
- if [ $HAS_PYYAML -ne 0 ]; then
- n=$((n + 1))
- echo_i "check that dig processes +expire +yaml ($n)"
- ret=0
- dig_with_opts @10.53.0.1 +yaml +expire . soa >dig.out.test$n 2>&1 || ret=1
- $PYTHON yamlget.py dig.out.test$n 0 message response_message_data OPT_PSEUDOSECTION EDNS EXPIRE >yamlget.out.test$n 2>&1 || ret=1
- read -r value <yamlget.out.test$n
- [ "$value" = "1200" ] || ret=1
- grep "EXPIRE: 1200 # 20 minutes" dig.out.test$n >/dev/null || ret=1
- if [ $ret -ne 0 ]; then echo_i "failed"; fi
- status=$((status + ret))
- fi
-
- n=$((n + 1))
- echo_i "check that dig processes +keepalive ($n)"
- ret=0
- dig_with_opts @10.53.0.1 +keepalive . soa +tcp >dig.out.test$n 2>&1 || ret=1
- grep '; TCP-KEEPALIVE: 30.0 secs' dig.out.test$n >/dev/null || ret=1
- if [ $ret -ne 0 ]; then echo_i "failed"; fi
- status=$((status + ret))
-
- if [ $HAS_PYYAML -ne 0 ]; then
- n=$((n + 1))
- echo_i "check that dig processes +keepalive +yaml ($n)"
- ret=0
- dig_with_opts @10.53.0.1 +yaml +keepalive . soa +tcp >dig.out.test$n 2>&1 || ret=1
- $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
- read -r value <yamlget.out.test$n
- [ "$value" = "30.0 secs" ] || ret=1
- if [ $ret -ne 0 ]; then echo_i "failed"; fi
- status=$((status + ret))
- fi
-
- n=$((n + 1))
- echo_i "check that Extended DNS Error 0 is printed correctly ($n)"
- ret=0
- # First defined EDE code, additional text "foo".
- dig_with_opts @10.53.0.3 +ednsopt=ede:0000666f6f a.example +qr >dig.out.test$n 2>&1 || ret=1
- pat='^; EDE: 0 (Other): (foo)$'
- grep "$pat" dig.out.test$n >/dev/null || ret=1
- if [ $ret -ne 0 ]; then echo_i "failed"; fi
- status=$((status + ret))
-
- if [ $HAS_PYYAML -ne 0 ]; then
- n=$((n + 1))
- echo_i "check that Extended DNS Error 0 is printed correctly +yaml ($n)"
- ret=0
- # add specials '"' and '\'
- dig_with_opts @10.53.0.3 +yaml +ednsopt=ede:0000666f6f225c a.example +qr >dig.out.test$n 2>&1 || ret=1
- $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
- read -r value <yamlget.out.test$n
- [ "$value" = 'foo"\' ] || ret=1
- if [ $ret -ne 0 ]; then echo_i "failed"; fi
- status=$((status + ret))
- fi
-
- n=$((n + 1))
- echo_i "check that Extended DNS Error 24 is printed correctly ($n)"
- ret=0
- # Last defined EDE code, no additional text.
- dig_with_opts @10.53.0.3 +ednsopt=ede:0018 a.example +qr >dig.out.test$n 2>&1 || ret=1
- pat='^; EDE: 24 (Invalid Data)$'
- grep "$pat" dig.out.test$n >/dev/null || ret=1
- if [ $ret -ne 0 ]; then echo_i "failed"; fi
- status=$((status + ret))
-
- n=$((n + 1))
- echo_i "check that Extended DNS Error 25 is printed correctly ($n)"
- ret=0
- # First undefined EDE code, additional text "foo".
- dig_with_opts @10.53.0.3 +ednsopt=ede:0019666f6f a.example +qr >dig.out.test$n 2>&1 || ret=1
- pat='^; EDE: 25: (foo)$'
- grep "$pat" dig.out.test$n >/dev/null || ret=1
- if [ $ret -ne 0 ]; then echo_i "failed"; fi
- status=$((status + ret))
-
- n=$((n + 1))
- echo_i "check that invalid Extended DNS Error (length 0) is printed ($n)"
- ret=0
- # EDE payload is too short
- dig_with_opts @10.53.0.3 +ednsopt=ede a.example +qr >dig.out.test$n 2>&1 || ret=1
- pat='^; EDE:$'
- grep "$pat" dig.out.test$n >/dev/null || ret=1
- if [ $ret -ne 0 ]; then echo_i "failed"; fi
- status=$((status + ret))
-
- n=$((n + 1))
- echo_i "check that invalid Extended DNS Error (length 1) is printed ($n)"
- ret=0
- # EDE payload is too short
- dig_with_opts @10.53.0.3 +ednsopt=ede:00 a.example +qr >dig.out.test$n 2>&1 || ret=1
- pat='^; EDE: 00 (".")$'
- grep "$pat" dig.out.test$n >/dev/null || ret=1
- if [ $ret -ne 0 ]; then echo_i "failed"; fi
- status=$((status + ret))
-
- if [ $HAS_PYYAML -ne 0 ]; then
- n=$((n + 1))
- echo_i "check that +yaml Extended DNS Error 0 is printed correctly ($n)"
- ret=0
- # First defined EDE code, additional text "foo".
- dig_with_opts @10.53.0.3 +yaml +ednsopt=ede:0000666f6f a.example +qr >dig.out.test$n 2>&1 || ret=1
- $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
- read -r value <yamlget.out.test$n
- [ "$value" = "0 (Other)" ] || ret=1
- $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
- read -r value <yamlget.out.test$n
- [ "$value" = "foo" ] || ret=1
- if [ $ret -ne 0 ]; then echo_i "failed"; fi
- status=$((status + ret))
-
- n=$((n + 1))
- echo_i "check that +yaml Extended DNS Error 24 is printed correctly ($n)"
- ret=0
- # Last defined EDE code, no additional text.
- dig_with_opts @10.53.0.3 +yaml +ednsopt=ede:0018 a.example +qr >dig.out.test$n 2>&1 || ret=1
- $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
- read -r value <yamlget.out.test$n
- [ "$value" = "24 (Invalid Data)" ] || ret=1
- $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
- if [ $ret -ne 0 ]; then echo_i "failed"; fi
- status=$((status + ret))
-
- n=$((n + 1))
- echo_i "check that +yaml Extended DNS Error 25 is printed correctly ($n)"
- ret=0
- # First undefined EDE code, additional text "foo".
- dig_with_opts @10.53.0.3 +yaml +ednsopt=ede:0019666f6f a.example +qr >dig.out.test$n 2>&1 || ret=1
- $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
- read -r value <yamlget.out.test$n
- [ "$value" = "25" ] || ret=1
- $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
- read -r value <yamlget.out.test$n
- [ "$value" = "foo" ] || ret=1
- if [ $ret -ne 0 ]; then echo_i "failed"; fi
- status=$((status + ret))
-
- n=$((n + 1))
- echo_i "check that invalid Extended DNS Error (length 0) is printed ($n)"
- ret=0
- # EDE payload is too short
- dig_with_opts @10.53.0.3 +yaml +ednsopt=ede a.example +qr >dig.out.test$n 2>&1 || ret=1
- $PYTHON yamlget.py dig.out.test$n 0 message query_message_data OPT_PSEUDOSECTION EDNS EDE >yamlget.out.test$n 2>&1 || ret=1
- read -r value <yamlget.out.test$n
- [ "$value" = "None" ] || ret=1
- if [ $ret -ne 0 ]; then echo_i "failed"; fi
- status=$((status + ret))
-
- n=$((n + 1))
- echo_i "check that invalid +yaml Extended DNS Error (length 1) is printed ($n)"
- ret=0
- # EDE payload is too short
- dig_with_opts @10.53.0.3 +yaml +ednsopt=ede:00 a.example +qr >dig.out.test$n 2>&1 || ret=1
- $PYTHON yamlget.py dig.out.test$n 0 message query_message_data OPT_PSEUDOSECTION EDNS EDE >yamlget.out.test$n 2>&1 || ret=1
- read -r value <yamlget.out.test$n
- [ "$value" = '00 (".")' ] || ret=1
- if [ $ret -ne 0 ]; then echo_i "failed"; fi
- status=$((status + ret))
- fi
-
- n=$((n + 1))
- echo_i "check that dig handles malformed option '+ednsopt=:' gracefully ($n)"
- ret=0
- dig_with_opts @10.53.0.3 +ednsopt=: a.example >dig.out.test$n 2>&1 && ret=1
- grep "ednsopt no code point specified" dig.out.test$n >/dev/null || ret=1
- if [ $ret -ne 0 ]; then echo_i "failed"; fi
- status=$((status + ret))
-
- n=$((n + 1))
- echo_i "checking dig +zoneversion to a authoritative server ($n)"
- ret=0
- dig_with_opts @10.53.0.2 +zoneversion a.example >dig.out.test$n 2>&1 || ret=1
- pat="; ZONEVERSION: ZONE: example, SOA-SERIAL: 2000042407"
- grep "$pat" dig.out.test$n >/dev/null || ret=1
- if [ $ret -ne 0 ]; then echo_i "failed"; fi
- status=$((status + ret))
-
- n=$((n + 1))
- echo_i "checking dig +zoneversion to a authoritative server with zoneversion disabled ($n)"
- ret=0
- dig_with_opts @10.53.0.2 +zoneversion a.example.tld >dig.out.test$n 2>&1 || ret=1
- grep "status: NOERROR" dig.out.test$n >/dev/null || ret=1
- grep "; ZONEVERSION:" dig.out.test$n >/dev/null && ret=1
- if [ $ret -ne 0 ]; then echo_i "failed"; fi
- status=$((status + ret))
-
- if [ $HAS_PYYAML -ne 0 ]; then
- n=$((n + 1))
- echo_i "checking dig +yaml +zoneversion to a authoritative server ($n)"
- ret=0
- dig_with_opts @10.53.0.2 +yaml +zoneversion a.example >dig.out.test$n 2>&1 || ret=1
- $PYTHON yamlget.py dig.out.test$n 0 message response_message_data OPT_PSEUDOSECTION EDNS ZONEVERSION >yamlget.out.test$n 2>&1 || ret=1
- read -r value <yamlget.out.test$n
- expected="{'ZONE': 'example', 'SOA-SERIAL': 2000042407}"
- [ "$value" = "$expected" ] || ret=1
- if [ $ret -ne 0 ]; then echo_i "failed"; fi
- status=$((status + ret))
- fi
-
- n=$((n + 1))
- echo_i "checking dig +ednsopt=ZONEVERSION:<answer> to a authoritative server ($n)"
- ret=0
- dig_with_opts @10.53.0.2 +ednsopt=ZONEVERSION:0100000007DA a.example >dig.out.test$n 2>&1 || ret=1
- grep "status: FORMERR" dig.out.test$n >/dev/null || ret=1
- grep "; ZONEVERSION:" dig.out.test$n >/dev/null && ret=1
- if [ $ret -ne 0 ]; then echo_i "failed"; fi
- status=$((status + ret))
-
- n=$((n + 1))
- echo_i "checking dig +zoneversion to a recursive server ($n)"
- ret=0
- dig_with_opts @10.53.0.3 +zoneversion a.example >dig.out.test$n 2>&1 || ret=1
- grep '; ZONEVERSION:' dig.out.test$n >/dev/null && ret=1
- if [ $ret -ne 0 ]; then echo_i "failed"; fi
- status=$((status + ret))
-
- n=$((n + 1))
- echo_i "checking display of non serial type zoneversion ($n)"
- ret=0
- dig_with_opts @10.53.0.2 +qr +ednsopt=ZONEVERSION:0100000007DA a.example >dig.out.test$n 2>&1 || ret=1
- grep '; ZONEVERSION: LABELS: 1, TYPE: 0, VALUE: 000007da ("....")' dig.out.test$n >/dev/null && ret=1
- if [ $ret -ne 0 ]; then echo_i "failed"; fi
- status=$((status + ret))
-
- if [ $HAS_PYYAML -ne 0 ]; then
- n=$((n + 1))
- echo_i "checking display of non serial type zoneversion +yaml ($n)"
- ret=0
- dig_with_opts @10.53.0.2 +qr +ednsopt=ZONEVERSION:0100000007DA a.example +yaml >dig.out.test$n 2>&1 || ret=1
- $PYTHON yamlget.py dig.out.test$n 0 message query_message_data OPT_PSEUDOSECTION EDNS ZONEVERSION >yamlget.out.test$n 2>&1 || ret=1
- expected="{'ZONE': 'example', 'TYPE': 1, 'VALUE': 000007da, PVALUE: '....'}"
- if [ $ret -ne 0 ]; then echo_i "failed"; fi
- status=$((status + ret))
- fi
n=$((n + 1))
echo_i "checking exit code for a retry upon TCP EOF (immediate -> immediate) ($n)"
if [ $ret -ne 0 ]; then echo_i "failed"; fi
status=$((status + ret))
- n=$((n + 1))
- echo_i "check that dig +noedns +ednsflags=<nonzero> re-enables EDNS ($n)"
- dig_with_opts @10.53.0.3 +qr +noedns +ednsflags=0x70 a.example >dig.out.test$n 2>&1 || ret=1
- grep "; EDNS: version: 0, flags:; MBZ: 0x0070, udp: 1232" dig.out.test$n >/dev/null || ret=1
- grep "; EDNS: version: 0, flags:; udp: 1232" dig.out.test$n >/dev/null || ret=1
- if [ $ret -ne 0 ]; then echo_i "failed"; fi
- status=$((status + ret))
-
- n=$((n + 1))
- echo_i "check that dig +showbadvers works ($n)"
- dig_with_opts @10.53.0.3 +edns=1 +qr +showbadvers a.example >dig.out.test$n 2>&1 || ret=1
- grep "; EDNS: version: 1, flags:; udp: 1232" dig.out.test$n >/dev/null || ret=1
- grep "; EDNS: version: 0, flags:; udp: 1232" dig.out.test$n >/dev/null || ret=1
- grep -F "status: BADVERS" dig.out.test$n >/dev/null || ret=1
- grep -F "status: NOERROR" dig.out.test$n >/dev/null || ret=1
- if [ $ret -ne 0 ]; then echo_i "failed"; fi
- status=$((status + ret))
-
- n=$((n + 1))
- echo_i "check that dig +showtruncated works ($n)"
- dig_with_opts @10.53.0.2 +qr +showtruncated truncated.example TXT >dig.out.test$n 2>&1 || ret=1
- grep 'flags:[^;]* tc[ ;].*ANSWER: 0' dig.out.test$n >/dev/null || ret=1
- grep 'ANSWER: 100,' dig.out.test$n >/dev/null || ret=1
- if [ $ret -ne 0 ]; then echo_i "failed"; fi
- status=$((status + ret))
-
# See GL#5609
n=$((n + 1))
echo_i "check dig with a IPv4 source address and a server with both IPv4 and IPv6 addresses doesn't crash ($n)"
import pytest
-from digdelv.common import ARTIFACTS, check_ttl_range
+from digdelv.common import ARTIFACTS, check_ttl_range, needs_pyyaml, parse_yaml
from isctest.util import param
import isctest
return isctest.run.EnvCmd("DIG", f"-p {named_port}")
+def edns_yaml(text, direction="query"):
+ """Get the EDNS OPT pseudosection mapping of the first message in
+ dig +yaml output."""
+ message = parse_yaml(text)[0]["message"]
+ return message[f"{direction}_message_data"]["OPT_PSEUDOSECTION"]["EDNS"]
+
+
def test_update_response(dig, ans6):
"""Check that dig rejects a response with the UPDATE opcode."""
result = dig(
assert Re(r"RRSIG.* \[omitted]") in result.out
result = dig(f"+norec +nocrypto DS example @{ns1.ip}")
assert Re(r"DS.* \d+ [12] \[omitted]") in result.out
+
+
+def test_coflag(dig, ns3):
+ """Check that dig +coflag sets the EDNS CO flag in the sent query."""
+ result = dig(f"+tcp @{ns3.ip} +coflag +qr example")
+ assert Re(r"^; EDNS: version: 0, flags: co;") in result.out
+ assert check_ttl_range(result.out, "SOA", 300)
+
+
+@needs_pyyaml
+def test_coflag_yaml(dig, ns3):
+ """Check that dig +coflag +yaml shows the CO flag in the sent query."""
+ result = dig(f"+yaml +tcp @{ns3.ip} +coflag +qr example")
+ assert edns_yaml(result.out)["flags"] == "co"
+
+
+@pytest.mark.parametrize(
+ "option,sent_flags",
+ [
+ param("+raflag", "rd ra ad"),
+ param("+tcflag", "tc rd ad"),
+ ],
+)
+def test_header_flag_options(dig, ns3, option, sent_flags):
+ """Check that +raflag/+tcflag set the flag in the sent query and that
+ the response is unaffected."""
+ result = dig(f"+tcp @{ns3.ip} {option} +qr example")
+ assert Re(rf"^;; flags: {sent_flags}; QUERY: 1, ANSWER: 0") in result.out
+ assert Re(r"^;; flags: qr rd ra; QUERY: 1, ANSWER: 0,") in result.out
+ assert check_ttl_range(result.out, "SOA", 300)
+
+
+def test_zflag(dig, ns3):
+ """Check that dig +zflag sets the MBZ bit and that named ignores it."""
+ result = dig(f"+tcp @{ns3.ip} +zflag +qr A example")
+ assert Re(r"^;; flags: rd ad; MBZ: 0x4;") in result.out
+ assert Re(r"^;; flags: qr rd ra; QUERY: 1") in result.out
+ assert check_ttl_range(result.out, "SOA", 300)
+
+
+def test_ednsopt_08_no_insist(dig, ns3):
+ """Check that +qr +ednsopt=08 does not cause an INSIST failure."""
+ result = dig(f"@{ns3.ip} +ednsopt=08 +qr a a.example")
+ assert "INSIST" not in result.out
+ assert "FORMERR" in result.out
+
+
+@pytest.mark.parametrize(
+ "option",
+ [
+ param("3", id="number"),
+ param("nsid", id="name"),
+ ],
+)
+def test_ednsopt_nsid(dig, ns3, option):
+ """Check that +ednsopt accepts an option number as well as a name."""
+ result = dig(f"@{ns3.ip} +ednsopt={option} a.example")
+ assert Re(r'NSID: .* \("ns3"\)') in result.out
+ assert check_ttl_range(result.out, "A", 300)
+
+
+def test_ednsopt_update_lease(dig, ns3):
+ """Check that a single-lease UPDATE-LEASE option prints as expected."""
+ result = dig(f"@{ns3.ip} +ednsopt=UPDATE-LEASE:00000e10 +qr a.example")
+ assert "UPDATE-LEASE: 3600 (1 hour)" in result.out
+
+
+@needs_pyyaml
+def test_ednsopt_update_lease_yaml(dig, ns3):
+ """Check that a single-lease UPDATE-LEASE option prints as expected
+ with +yaml."""
+ result = dig(f"@{ns3.ip} +yaml +ednsopt=UPDATE-LEASE:00000e10 +qr a.example")
+ assert edns_yaml(result.out)["UPDATE-LEASE"]["LEASE"] == 3600
+ assert "LEASE: 3600 # 1 hour" in result.out
+
+
+def test_ednsopt_update_lease_split(dig, ns3):
+ """Check that a split-lease UPDATE-LEASE option prints as expected."""
+ result = dig(f"@{ns3.ip} +ednsopt=UPDATE-LEASE:00000e1000127500 +qr a.example")
+ assert "UPDATE-LEASE: 3600/1209600 (1 hour/2 weeks)" in result.out
+
+
+@needs_pyyaml
+def test_ednsopt_update_lease_split_yaml(dig, ns3):
+ """Check that a split-lease UPDATE-LEASE option prints as expected
+ with +yaml."""
+ result = dig(
+ f"@{ns3.ip} +yaml +ednsopt=UPDATE-LEASE:00000e1000127500 +qr a.example"
+ )
+ update_lease = edns_yaml(result.out)["UPDATE-LEASE"]
+ assert update_lease["LEASE"] == 3600
+ assert update_lease["KEY-LEASE"] == 1209600
+ assert "LEASE: 3600 # 1 hour" in result.out
+ assert "KEY-LEASE: 1209600 # 2 weeks" in result.out
+
+
+def test_ednsopt_llq(dig, ns3):
+ """Check that the LLQ option prints as expected."""
+ result = dig(
+ f"@{ns3.ip} +ednsopt=llq:0001000200001234567812345678fefefefe +qr a.example"
+ )
+ pattern = (
+ r"LLQ: Version: 1, Opcode: 2, Error: 0, "
+ r"Identifier: 1311768465173141112, Lifetime: 4278124286$"
+ )
+ assert Re(pattern) in result.out
+
+
+@needs_pyyaml
+def test_ednsopt_llq_yaml(dig, ns3):
+ """Check that the LLQ option prints as expected with +yaml."""
+ result = dig(
+ f"@{ns3.ip} +yaml +ednsopt=llq:0001000200001234567812345678fefefefe "
+ "+qr a.example"
+ )
+ llq = edns_yaml(result.out)["LLQ"]
+ assert llq["LLQ-VERSION"] == 1
+ assert llq["LLQ-OPCODE"] == 2
+ assert llq["LLQ-ERROR"] == 0
+ assert llq["LLQ-ID"] == 1311768465173141112
+ assert llq["LLQ-LEASE"] == 4278124286
+
+
+def test_ednsopt_key_tag_empty(dig, ns3):
+ """Check that an empty key-tag option is sent and FORMERR is returned."""
+ result = dig(f"@{ns3.ip} +ednsopt=key-tag a.example +qr")
+ assert Re(r"; KEY-TAG: *$") in result.out
+ assert "status: FORMERR" in result.out
+
+
+def test_ednsopt_key_tag(dig, ns3):
+ """Check that a key-tag value list is sent and accepted."""
+ result = dig(f"@{ns3.ip} +ednsopt=key-tag:00010002 a.example +qr")
+ assert Re(r"; KEY-TAG: 1, 2$") in result.out
+ assert "status: FORMERR" not in result.out
+ assert check_ttl_range(result.out, "A", 300)
+
+
+@needs_pyyaml
+def test_ednsopt_key_tag_yaml(dig, ns3):
+ """Check that a key-tag value list prints as a list with +yaml."""
+ result = dig(f"@{ns3.ip} +yaml +ednsopt=key-tag:00010002 a.example +qr")
+ assert edns_yaml(result.out)["KEY-TAG"] == [1, 2]
+
+
+def test_ednsopt_key_tag_malformed(dig, ns3):
+ """Check that a malformed key-tag value list is sent as raw data and
+ FORMERR is returned."""
+ result = dig(f"@{ns3.ip} +ednsopt=key-tag:0001000201 a.example +qr")
+ assert "; KEY-TAG: 00 01 00 02 01" in result.out
+ assert "status: FORMERR" in result.out
+
+
+@pytest.mark.parametrize("tag", ["client-tag", "server-tag"])
+def test_ednsopt_tag(dig, ns3, tag):
+ """Check that a valid client/server-tag value is sent and accepted."""
+ result = dig(f"@{ns3.ip} +ednsopt={tag}:0001 a.example +qr")
+ assert Re(rf"; {tag.upper()}: 1$") in result.out
+ assert "status: FORMERR" not in result.out
+
+
+@needs_pyyaml
+@pytest.mark.parametrize("tag", ["client-tag", "server-tag"])
+def test_ednsopt_tag_yaml(dig, ns3, tag):
+ """Check that a client/server-tag value prints as expected with +yaml."""
+ result = dig(f"@{ns3.ip} +yaml +ednsopt={tag}:0001 a.example +qr")
+ assert edns_yaml(result.out)[tag.upper()] == 1
+
+
+@pytest.mark.parametrize(
+ "value",
+ [
+ param("01", id="too-short"),
+ param("000001", id="too-long"),
+ ],
+)
+@pytest.mark.parametrize("tag", ["client-tag", "server-tag"])
+def test_ednsopt_tag_bad_length(dig, ns3, tag, value):
+ """Check that FORMERR is returned for a client/server-tag value of the
+ wrong length."""
+ result = dig(f"@{ns3.ip} +ednsopt={tag}:{value} a.example +qr")
+ assert f"; {tag.upper()}" in result.out
+ assert "status: FORMERR" in result.out
+
+
+def test_ednsopt_chain(dig, ns3):
+ """Check that the CHAIN option prints special characters escaped."""
+ result = dig(rf'@{ns3.ip} +ednsopt=chain:02002200 a.\000" +qr')
+ assert r'; CHAIN: "\000\""' in result.out
+
+
+@needs_pyyaml
+def test_ednsopt_chain_yaml(dig, ns3):
+ """Check that the CHAIN option prints special characters escaped
+ with +yaml."""
+ result = dig(rf'@{ns3.ip} +yaml +ednsopt=chain:02002200 a.\000" +qr')
+ assert edns_yaml(result.out)["CHAIN"] == r"\000\""
+
+
+def test_expire(dig, ns1):
+ """Check that dig processes +expire."""
+ result = dig(f"@{ns1.ip} +expire . soa")
+ assert "; EXPIRE: 1200 (20 minutes)" in result.out
+
+
+@needs_pyyaml
+def test_expire_yaml(dig, ns1):
+ """Check that dig processes +expire with +yaml."""
+ result = dig(f"@{ns1.ip} +yaml +expire . soa")
+ assert edns_yaml(result.out, "response")["EXPIRE"] == 1200
+ assert "EXPIRE: 1200 # 20 minutes" in result.out
+
+
+def test_keepalive(dig, ns1):
+ """Check that dig processes +keepalive."""
+ result = dig(f"@{ns1.ip} +keepalive . soa +tcp")
+ assert "; TCP-KEEPALIVE: 30.0 secs" in result.out
+
+
+@needs_pyyaml
+def test_keepalive_yaml(dig, ns1):
+ """Check that dig processes +keepalive with +yaml."""
+ result = dig(f"@{ns1.ip} +yaml +keepalive . soa +tcp")
+ assert edns_yaml(result.out, "response")["TCP-KEEPALIVE"] == "30.0 secs"
+
+
+@pytest.mark.parametrize(
+ "payload,expected",
+ [
+ param("ede:0000666f6f", "; EDE: 0 (Other): (foo)", id="first-defined-code"),
+ param("ede:0018", "; EDE: 24 (Invalid Data)", id="last-defined-code"),
+ param("ede:0019666f6f", "; EDE: 25: (foo)", id="undefined-code"),
+ param("ede", "; EDE:", id="empty"),
+ param("ede:00", '; EDE: 00 (".")', id="too-short"),
+ ],
+)
+def test_ednsopt_ede(dig, ns3, payload, expected):
+ """Check that Extended DNS Error options, including invalid ones with
+ a too short payload, are printed correctly."""
+ result = dig(f"@{ns3.ip} +ednsopt={payload} a.example +qr")
+ assert Re("^" + re.escape(expected) + "$") in result.out
+
+
+@needs_pyyaml
+@pytest.mark.parametrize(
+ "payload,info_code,extra_text",
+ [
+ param("ede:0000666f6f", "0 (Other)", "foo", id="first-defined-code"),
+ param("ede:0018", "24 (Invalid Data)", None, id="last-defined-code"),
+ param("ede:0019666f6f", 25, "foo", id="undefined-code"),
+ ],
+)
+def test_ednsopt_ede_yaml(dig, ns3, payload, info_code, extra_text):
+ """Check that Extended DNS Error options are printed correctly
+ with +yaml."""
+ result = dig(f"@{ns3.ip} +yaml +ednsopt={payload} a.example +qr")
+ ede = edns_yaml(result.out)["EDE"]
+ assert ede["INFO-CODE"] == info_code
+ if extra_text is None:
+ assert "EXTRA-TEXT" not in ede
+ else:
+ assert ede["EXTRA-TEXT"] == extra_text
+
+
+@needs_pyyaml
+def test_ednsopt_ede_yaml_specials(dig, ns3):
+ """Check that EDE extra text with '"' and '\\' specials survives YAML
+ quoting."""
+ result = dig(f"@{ns3.ip} +yaml +ednsopt=ede:0000666f6f225c a.example +qr")
+ assert edns_yaml(result.out)["EDE"]["EXTRA-TEXT"] == 'foo"\\'
+
+
+@needs_pyyaml
+@pytest.mark.parametrize(
+ "payload,expected",
+ [
+ param("ede", None, id="empty"),
+ param("ede:00", '00 (".")', id="too-short"),
+ ],
+)
+def test_ednsopt_ede_yaml_invalid(dig, ns3, payload, expected):
+ """Check that invalid Extended DNS Error options with a too short
+ payload are printed correctly with +yaml."""
+ result = dig(f"@{ns3.ip} +yaml +ednsopt={payload} a.example +qr")
+ assert edns_yaml(result.out)["EDE"] == expected
+
+
+def test_ednsopt_malformed(dig, ns3):
+ """Check that dig handles the malformed option '+ednsopt=:'
+ gracefully."""
+ result = dig(f"@{ns3.ip} +ednsopt=: a.example", raise_on_exception=False)
+ assert result.rc != 0
+ assert "ednsopt no code point specified" in result.err
+
+
+def test_zoneversion(dig, ns2):
+ """Check +zoneversion against an authoritative server."""
+ result = dig(f"@{ns2.ip} +zoneversion a.example")
+ assert "; ZONEVERSION: ZONE: example, SOA-SERIAL: 2000042407" in result.out
+
+
+def test_zoneversion_disabled(dig, ns2):
+ """Check +zoneversion against an authoritative server with zoneversion
+ disabled."""
+ result = dig(f"@{ns2.ip} +zoneversion a.example.tld")
+ assert "status: NOERROR" in result.out
+ assert "; ZONEVERSION:" not in result.out
+
+
+@needs_pyyaml
+def test_zoneversion_yaml(dig, ns2):
+ """Check +yaml +zoneversion against an authoritative server."""
+ result = dig(f"@{ns2.ip} +yaml +zoneversion a.example")
+ assert edns_yaml(result.out, "response")["ZONEVERSION"] == {
+ "ZONE": "example",
+ "SOA-SERIAL": 2000042407,
+ }
+
+
+def test_ednsopt_zoneversion(dig, ns2):
+ """Check that a ZONEVERSION option sent in a query returns FORMERR."""
+ result = dig(f"@{ns2.ip} +ednsopt=ZONEVERSION:0100000007DA a.example")
+ assert "status: FORMERR" in result.out
+ assert "; ZONEVERSION:" not in result.out
+
+
+def test_zoneversion_recursive(dig, ns3):
+ """Check that +zoneversion via a recursive server returns no
+ ZONEVERSION."""
+ result = dig(f"@{ns3.ip} +zoneversion a.example")
+ assert "; ZONEVERSION:" not in result.out
+
+
+def test_zoneversion_non_serial(dig, ns2):
+ """Check the display of a non SOA-SERIAL type zoneversion."""
+ result = dig(f"@{ns2.ip} +qr +ednsopt=ZONEVERSION:0100000007DA a.example")
+ assert (
+ '; ZONEVERSION: LABELS: 1, TYPE: 0, VALUE: 000007da ("....")' not in result.out
+ )
+
+
+@needs_pyyaml
+def test_zoneversion_non_serial_yaml(dig, ns2):
+ """Check the display of a non SOA-SERIAL type zoneversion with +yaml."""
+ result = dig(f"@{ns2.ip} +qr +ednsopt=ZONEVERSION:0100000007DA a.example +yaml")
+ assert "ZONEVERSION" in edns_yaml(result.out)
+
+
+def test_ednsflags_reenables_edns(dig, ns3):
+ """Check that +noedns +ednsflags=<nonzero> re-enables EDNS."""
+ result = dig(f"@{ns3.ip} +qr +noedns +ednsflags=0x70 a.example")
+ assert "; EDNS: version: 0, flags:; MBZ: 0x0070, udp: 1232" in result.out
+ assert "; EDNS: version: 0, flags:; udp: 1232" in result.out
+
+
+def test_showbadvers(dig, ns3):
+ """Check that +showbadvers displays the BADVERS response as well as
+ the retry without EDNS version 1."""
+ result = dig(f"@{ns3.ip} +edns=1 +qr +showbadvers a.example")
+ assert "; EDNS: version: 1, flags:; udp: 1232" in result.out
+ assert "; EDNS: version: 0, flags:; udp: 1232" in result.out
+ assert "status: BADVERS" in result.out
+ assert "status: NOERROR" in result.out
+
+
+def test_showtruncated(dig, ns2):
+ """Check that +showtruncated displays the truncated response as well
+ as the TCP retry."""
+ result = dig(f"@{ns2.ip} +qr +showtruncated truncated.example TXT")
+ assert Re(r"flags:[^;]* tc[ ;].*ANSWER: 0") in result.out
+ assert "ANSWER: 100," in result.out