diff --git a/bin/tests/system/class/tests_class_update.py b/bin/tests/system/class/tests_class_update.py index e53bbc77ea..30e3ba6d2a 100644 --- a/bin/tests/system/class/tests_class_update.py +++ b/bin/tests/system/class/tests_class_update.py @@ -12,7 +12,7 @@ import socket import struct -from dns import rdataclass, rdatatype, update +from dns import message, rdataclass, rdatatype, update import pytest @@ -35,6 +35,7 @@ def encode_name(name: str) -> bytes: @pytest.mark.parametrize( "rdtype,rdclass,ttl,rdata", [ + (rdatatype.SRV, rdataclass.NONE, 0, b"\x00\x00\x00\x00\x00\x00\x01"), (rdatatype.SRV, rdataclass.NONE, 0, b"\x00"), (rdatatype.KX, rdataclass.NONE, 0, b""), (rdatatype.PX, rdataclass.NONE, 0, b""), @@ -69,7 +70,7 @@ def test_class_invalid(rdtype, rdclass, ttl, rdata, named_port): s.sendall(packet) try: rwire = s.recv(4096) - res = dns.message.from_wire(rwire) + res = message.from_wire(rwire) isctest.check.formerr(res) except Exception: # pylint: disable=broad-except pass @@ -94,3 +95,43 @@ def test_class_chaosupdate(rdtype, rdata): up.add("foo.example.", 300, rdtype, rdata) res = isctest.query.tcp(up, "10.53.0.2") isctest.check.notimp(res) + + +def test_class_undefined(ns2): + up = update.UpdateMessage(".", rdclass=257) + up.present(".", 0) + up.answer[0].rdclass = rdataclass.NONE + with ns2.watch_log_from_here() as watcher: + res = isctest.query.tcp(up, "10.53.0.2") + isctest.check.notimp(res) + watcher.wait_for_line("invalid message class: CLASS257") + + +def test_class_zero(ns2): + up = update.UpdateMessage(".", rdclass=0) + up.present(".", 0) + up.answer[0].rdclass = rdataclass.NONE + with ns2.watch_log_from_here() as watcher: + res = isctest.query.tcp(up, "10.53.0.2") + isctest.check.formerr(res) + watcher.wait_for_line("message class could not be determined") + + +def test_class_any(ns2): + up = update.UpdateMessage(".", rdclass=rdataclass.ANY) + up.present(".", 0) + up.answer[0].rdclass = rdataclass.NONE + with ns2.watch_log_from_here() as watcher: + res = isctest.query.tcp(up, "10.53.0.2") + isctest.check.formerr(res) + watcher.wait_for_line("message parsing failed: FORMERR") + + +def test_class_none(ns2): + up = update.UpdateMessage(".", rdclass=rdataclass.NONE) + up.present(".", 0) + up.answer[0].rdclass = rdataclass.NONE + with ns2.watch_log_from_here() as watcher: + res = isctest.query.tcp(up, "10.53.0.2") + isctest.check.formerr(res) + watcher.wait_for_line("message parsing failed: FORMERR") diff --git a/bin/tests/system/nsupdate/setup.sh b/bin/tests/system/nsupdate/setup.sh index 299330773a..9d27b20a76 100644 --- a/bin/tests/system/nsupdate/setup.sh +++ b/bin/tests/system/nsupdate/setup.sh @@ -35,6 +35,7 @@ update.nil IN SOA ns1.example.nil. hostmaster.example.nil. ( 3600 ; minimum (1 hour) ) update.nil. NS ns1.update.nil. +update.nil. KX 0 . ns1.update.nil. A 10.53.0.2 ns2.update.nil. AAAA ::1 EOF diff --git a/bin/tests/system/nsupdate/tests.sh b/bin/tests/system/nsupdate/tests.sh index 7a77faea6b..d71136c563 100755 --- a/bin/tests/system/nsupdate/tests.sh +++ b/bin/tests/system/nsupdate/tests.sh @@ -485,8 +485,10 @@ grep "status: NOERROR" dig.out.ns1.$n >/dev/null || ret=1 n=$((n + 1)) ret=0 echo_i "check that TYPE=0 update is handled ($n)" +nextpart ns1/named.run >/dev/null echo "a0e4280000010000000100000000060001c00c000000fe000000000000" \ - | $PERL ../packet.pl -a 10.53.0.1 -p ${PORT} -t tcp >/dev/null || ret=1 + | $PERL ../packet.pl -a 10.53.0.1 -p ${PORT} -t tcp -b >/dev/null || ret=1 +wait_for_log 2 "message parsing failed: FORMERR" ns1/named.run || ret=1 $DIG $DIGOPTS +tcp version.bind txt ch @10.53.0.1 >dig.out.ns1.$n || ret=1 grep "status: NOERROR" dig.out.ns1.$n >/dev/null || ret=1 [ $ret = 0 ] || { @@ -497,20 +499,10 @@ grep "status: NOERROR" dig.out.ns1.$n >/dev/null || ret=1 n=$((n + 1)) ret=0 echo_i "check that TYPE=0 additional data is handled ($n)" +nextpart ns1/named.run >/dev/null echo "a0e4280000010000000000010000060001c00c000000fe000000000000" \ - | $PERL ../packet.pl -a 10.53.0.1 -p ${PORT} -t tcp >/dev/null || ret=1 -$DIG $DIGOPTS +tcp version.bind txt ch @10.53.0.1 >dig.out.ns1.$n || ret=1 -grep "status: NOERROR" dig.out.ns1.$n >/dev/null || ret=1 -[ $ret = 0 ] || { - echo_i "failed" - status=1 -} - -n=$((n + 1)) -ret=0 -echo_i "check that update to undefined class is handled ($n)" -echo "a0e4280000010001000000000000060101c00c000000fe000000000000" \ - | $PERL ../packet.pl -a 10.53.0.1 -p ${PORT} -t tcp >/dev/null || ret=1 + | $PERL ../packet.pl -a 10.53.0.1 -p ${PORT} -t tcp -b >/dev/null || ret=1 +wait_for_log 2 "message parsing failed: FORMERR" ns1/named.run || ret=1 $DIG $DIGOPTS +tcp version.bind txt ch @10.53.0.1 >dig.out.ns1.$n || ret=1 grep "status: NOERROR" dig.out.ns1.$n >/dev/null || ret=1 [ $ret = 0 ] || { diff --git a/bin/tests/system/packet.pl b/bin/tests/system/packet.pl index 900a0c071e..afb9f4784d 100644 --- a/bin/tests/system/packet.pl +++ b/bin/tests/system/packet.pl @@ -40,6 +40,7 @@ # -p : specify port # -t : specify UDP or TCP # -r : send packet times +# -b: blocking io # -d: dump response packets # # If not specified, address defaults to 127.0.0.1, port to 53, protocol @@ -51,6 +52,8 @@ use strict; use Getopt::Std; use IO::File; use IO::Socket; +use Net::DNS; +use Net::DNS::Packet; sub usage { print ("Usage: packet.pl [-a address] [-d] [-p port] [-t (tcp|udp)] [-r ] [file]\n"); @@ -61,8 +64,6 @@ my $sock; my $proto; sub dumppacket { - use Net::DNS; - use Net::DNS::Packet; my $rin; my $rout; @@ -96,7 +97,7 @@ sub dumppacket { } my %options={}; -getopts("a:dp:t:r:", \%options); +getopts("a:bdp:t:r:", \%options); my $addr = "127.0.0.1"; $addr = $options{a} if defined $options{a}; @@ -111,6 +112,8 @@ usage if ($proto !~ /^(udp|tcp)$/); my $repeats = 1; $repeats = $options{r} if defined $options{r}; +my $blocking = defined $options{b} ? 1 : 0; + my $file = "STDIN"; if (@ARGV >= 1) { my $filename = shift @ARGV; @@ -132,8 +135,22 @@ my $len = length $data; my $output = unpack("H*", $data); print ("sending $repeats time(s): $output\n"); + +if (defined $options{d}) { + my $request; + if ($Net::DNS::VERSION > 0.68) { + $request = new Net::DNS::Packet(\$data, 0); + $@ and die $@; + } else { + my $err; + ($request, $err) = new Net::DNS::Packet(\$data, 0); + $err and die $err; + } + $request->print; +} + $sock = IO::Socket::INET->new(PeerAddr => $addr, PeerPort => $port, - Blocking => 0, + Blocking => $blocking, Proto => $proto,) or die "$!"; STDOUT->autoflush(1);