Hello community, here is the log from the commit of package perl-Net-DNS for openSUSE:Factory checked in at 2020-08-12 10:55:31 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/perl-Net-DNS (Old) and /work/SRC/openSUSE:Factory/.perl-Net-DNS.new.3399 (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "perl-Net-DNS" Wed Aug 12 10:55:31 2020 rev:61 rq:824986 version:1.26 Changes: -------- --- /work/SRC/openSUSE:Factory/perl-Net-DNS/perl-Net-DNS.changes 2020-07-01 18:22:22.585891109 +0200 +++ /work/SRC/openSUSE:Factory/.perl-Net-DNS.new.3399/perl-Net-DNS.changes 2020-08-12 10:55:33.520715325 +0200 @@ -1,0 +2,6 @@ +Fri Aug 7 03:12:16 UTC 2020 - Tina Müller <[email protected]> + +- updated to 1.26 + see /usr/share/doc/packages/perl-Net-DNS/Changes + +------------------------------------------------------------------- Old: ---- Net-DNS-1.25.tar.gz New: ---- Net-DNS-1.26.tar.gz ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ perl-Net-DNS.spec ++++++ --- /var/tmp/diff_new_pack.gw1p5l/_old 2020-08-12 10:55:34.244715685 +0200 +++ /var/tmp/diff_new_pack.gw1p5l/_new 2020-08-12 10:55:34.248715687 +0200 @@ -17,7 +17,7 @@ Name: perl-Net-DNS -Version: 1.25 +Version: 1.26 Release: 0 %define cpan_name Net-DNS Summary: Perl Interface to the Domain Name System @@ -30,14 +30,18 @@ BuildRoot: %{_tmppath}/%{name}-%{version}-build BuildRequires: perl BuildRequires: perl-macros +BuildRequires: perl(Carp) >= 1.1 BuildRequires: perl(Digest::HMAC) >= 1.03 BuildRequires: perl(Digest::SHA) >= 5.23 +BuildRequires: perl(Encode) >= 2.26 BuildRequires: perl(IO::Socket::IP) >= 0.38 BuildRequires: perl(PerlIO) >= 1.05 BuildRequires: perl(Scalar::Util) >= 1.25 BuildRequires: perl(Time::Local) >= 1.19 +Requires: perl(Carp) >= 1.1 Requires: perl(Digest::HMAC) >= 1.03 Requires: perl(Digest::SHA) >= 5.23 +Requires: perl(Encode) >= 2.26 Requires: perl(IO::Socket::IP) >= 0.38 Requires: perl(PerlIO) >= 1.05 Requires: perl(Scalar::Util) >= 1.25 ++++++ Net-DNS-1.25.tar.gz -> Net-DNS-1.26.tar.gz ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/Net-DNS-1.25/Changes new/Net-DNS-1.26/Changes --- old/Net-DNS-1.25/Changes 2020-06-26 17:14:19.000000000 +0200 +++ new/Net-DNS-1.26/Changes 2020-08-05 23:32:22.000000000 +0200 @@ -1,4 +1,13 @@ -$Id: Changes 1792 2020-06-26 14:43:25Z willem $ -*-text-*- +$Id: Changes 1801 2020-08-05 15:49:06Z willem $ -*-text-*- + + +**** 1.26 Aug, 6, 2020 + + Add HTTPS/SVCB packages. + +Fix rt.cpan.org #132921 + + EDNS OPT handling **** 1.25 Jun 26, 2020 diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/Net-DNS-1.25/MANIFEST new/Net-DNS-1.26/MANIFEST --- old/Net-DNS-1.25/MANIFEST 2020-06-26 17:14:24.000000000 +0200 +++ new/Net-DNS-1.26/MANIFEST 2020-08-05 23:32:28.000000000 +0200 @@ -53,6 +53,7 @@ lib/Net/DNS/RR/GPOS.pm lib/Net/DNS/RR/HINFO.pm lib/Net/DNS/RR/HIP.pm +lib/Net/DNS/RR/HTTPS.pm lib/Net/DNS/RR/IPSECKEY.pm lib/Net/DNS/RR/ISDN.pm lib/Net/DNS/RR/KEY.pm @@ -86,6 +87,7 @@ lib/Net/DNS/RR/SPF.pm lib/Net/DNS/RR/SRV.pm lib/Net/DNS/RR/SSHFP.pm +lib/Net/DNS/RR/SVCB.pm lib/Net/DNS/RR/TKEY.pm lib/Net/DNS/RR/TLSA.pm lib/Net/DNS/RR/TSIG.pm diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/Net-DNS-1.25/META.json new/Net-DNS-1.26/META.json --- old/Net-DNS-1.25/META.json 2020-06-26 17:14:24.000000000 +0200 +++ new/Net-DNS-1.26/META.json 2020-08-05 23:32:28.000000000 +0200 @@ -38,9 +38,13 @@ "Net::LibIDN2" : "1" }, "requires" : { + "Carp" : "1.1", "Digest::HMAC" : "1.03", "Digest::MD5" : "2.13", "Digest::SHA" : "5.23", + "Encode" : "2.26", + "Exporter" : "5.56", + "File::Find" : "1.05", "File::Spec" : "0.86", "IO::File" : "1.08", "IO::Select" : "1.14", @@ -49,13 +53,14 @@ "MIME::Base64" : "2.13", "PerlIO" : "1.05", "Scalar::Util" : "1.25", - "Test::More" : "0.52", + "Test::Builder" : "0", + "Test::More" : "0", "Time::Local" : "1.19", "perl" : "5.006" } } }, "release_status" : "stable", - "version" : "1.25", + "version" : "1.26", "x_serialization_backend" : "JSON::PP version 4.04" } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/Net-DNS-1.25/META.yml new/Net-DNS-1.26/META.yml --- old/Net-DNS-1.25/META.yml 2020-06-26 17:14:24.000000000 +0200 +++ new/Net-DNS-1.26/META.yml 2020-08-05 23:32:28.000000000 +0200 @@ -23,9 +23,13 @@ Digest::BubbleBabble: '0.01' Net::LibIDN2: '1' requires: + Carp: '1.1' Digest::HMAC: '1.03' Digest::MD5: '2.13' Digest::SHA: '5.23' + Encode: '2.26' + Exporter: '5.56' + File::Find: '1.05' File::Spec: '0.86' IO::File: '1.08' IO::Select: '1.14' @@ -34,8 +38,9 @@ MIME::Base64: '2.13' PerlIO: '1.05' Scalar::Util: '1.25' - Test::More: '0.52' + Test::Builder: '0' + Test::More: '0' Time::Local: '1.19' perl: '5.006' -version: '1.25' +version: '1.26' x_serialization_backend: 'CPAN::Meta::YAML version 0.018' diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/Net-DNS-1.25/Makefile.PL new/Net-DNS-1.26/Makefile.PL --- old/Net-DNS-1.25/Makefile.PL 2020-06-26 17:14:19.000000000 +0200 +++ new/Net-DNS-1.26/Makefile.PL 2020-08-05 23:32:22.000000000 +0200 @@ -1,10 +1,9 @@ # -# $Id: Makefile.PL 1791 2020-06-26 14:34:36Z willem $ -*-perl-*- +# $Id: Makefile.PL 1795 2020-07-27 11:00:29Z willem $ -*-perl-*- # use strict; use warnings; -use Getopt::Long; use ExtUtils::MakeMaker; use constant MM => eval $ExtUtils::MakeMaker::VERSION; @@ -35,9 +34,13 @@ my %prerequisite = ( + 'Carp' => 1.10, 'Digest::HMAC' => 1.03, 'Digest::MD5' => 2.13, 'Digest::SHA' => 5.23, + 'Encode' => 2.26, + 'Exporter' => 5.56, + 'File::Find' => 1.05, 'File::Spec' => 0.86, 'IO::File' => 1.08, 'IO::Select' => 1.14, @@ -47,7 +50,8 @@ 'PerlIO' => 1.05, 'Scalar::Util' => 1.25, 'Time::Local' => 1.19, - 'Test::More' => 0.52, + 'Test::Builder' => 0, + 'Test::More' => 0, %$platform ); @@ -64,40 +68,13 @@ delete $optional{'Net::DNS::SEC'}; ## Require explicit user action to install Net::DNS::SEC. -my @debris = qw( - .resolv.conf *.lock - t/IPv6.enabled - t/online.enabled t/online.nonfatal - ); - - -use constant USE_SOCKET_IP => defined eval 'use IO::Socket::IP 0.38; 1'; -use constant INET_FALLBACK => !USE_SOCKET_IP && eval 'require IO::Socket::INET'; - - -# clean up existing makefile -unlink('Makefile'); - -WriteMakefile( ## Makefile & distribution metadata - %metadata, - PREREQ_PM => {%prerequisite}, - META_MERGE => {recommends => {%optional}}, - clean => {FILES => "@debris"}, - ); - - -# clean up the online testing flag file. -unlink("t/online.enabled"); -unlink("t/online.disabled"); - -# clean up the IPv6 testing flag file. -unlink("t/IPv6.enabled"); -unlink("t/IPv6.disabled"); +my @debris = qw(.resolv.conf *.lock); # # Get the command line args # +use constant USE_GETOPT => defined eval 'use Getopt::Long; 1'; my $help = 0; my $IPv6_tests; @@ -111,7 +88,7 @@ ); -unless ( GetOptions(@options) ) { +if ( USE_GETOPT && !GetOptions(@options) ) { print "Error: Unrecognized option.\n"; print "Try perl Makefile.PL --help for more information\n"; exit 1; @@ -146,8 +123,11 @@ # -# Check if we have internet connection (code lifted from LWP) +# Enable tests if we have internet connection (code lifted from LWP) # +use constant USE_SOCKET_IP => defined eval 'use IO::Socket::IP 0.38; 1'; +use constant INET_FALLBACK => !USE_SOCKET_IP && eval 'require IO::Socket::INET'; + if ($online_tests) { my $class = USE_SOCKET_IP ? 'IO::Socket::IP' : 'IO::Socket::INET'; @@ -171,15 +151,19 @@ } +# set up online testing configuration files. +my $enable = 't/online.enabled'; +my $IPv6 = 't/IPv6.enabled'; +my $nonfatal = 't/online.nonfatal'; +push @debris, $enable, $IPv6, $nonfatal; + if ($online_tests) { - my $enable = 't/online.enabled'; - open( ENABLED, ">$enable" ) || die "Can't touch $enable $!"; - close(ENABLED) || die "Can't touch $enable $!"; + open( ENABLED, '>', $enable ) or die "Can't touch $enable $!"; + close(ENABLED); if ( $online_tests == 2 ) { - my $nonfatal = 't/online.nonfatal'; - open( NONFATAL, ">$nonfatal" ) || die "Can't touch $nonfatal $!"; - close(NONFATAL) || die "Can't touch $nonfatal $!"; + open( NONFATAL, '>', $nonfatal ) or die "Can't touch $nonfatal $!"; + close(NONFATAL); print "\nActivating Non Fatal Online Tests...\n"; } else { print "\nActivating Online Tests...\n"; @@ -187,10 +171,9 @@ $IPv6_tests = 1 unless defined $IPv6_tests; if ( USE_SOCKET_IP && $IPv6_tests ) { - my $enable = 't/IPv6.enabled'; print "\nActivating IPv6 Tests...\n"; - open( ENABLED, ">$enable" ) || die "Can't touch $enable $!"; - close(ENABLED) || die "Can't touch $enable $!"; + open( ENABLED, '>', $IPv6 ) or die "Can't touch $IPv6 $!"; + close(ENABLED); } print <<EOT; @@ -206,6 +189,14 @@ } +WriteMakefile( ## Makefile & distribution metadata + %metadata, + PREREQ_PM => {%prerequisite}, + META_MERGE => {recommends => {%optional}}, + clean => {FILES => "@debris"}, + ); + + package MY; ## customise generated Makefile sub test { diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/Net-DNS-1.25/lib/Net/DNS/Parameters.pm new/Net-DNS-1.26/lib/Net/DNS/Parameters.pm --- old/Net-DNS-1.25/lib/Net/DNS/Parameters.pm 2020-06-26 17:14:19.000000000 +0200 +++ new/Net-DNS-1.26/lib/Net/DNS/Parameters.pm 2020-08-05 23:32:22.000000000 +0200 @@ -1,15 +1,15 @@ package Net::DNS::Parameters; # -# $Id: Parameters.pm 1779 2020-05-11 09:11:17Z willem $ +# $Id: Parameters.pm 1795 2020-07-27 11:00:29Z willem $ # -our $VERSION = (qw$LastChangedRevision: 1779 $)[1]; +our $VERSION = (qw$LastChangedRevision: 1795 $)[1]; ################################################ ## ## Domain Name System (DNS) Parameters -## (last updated 2020-05-07) +## (last updated 2020-06-30) ## ################################################ @@ -107,6 +107,8 @@ OPENPGPKEY => 61, # RFC7929 CSYNC => 62, # RFC7477 ZONEMD => 63, # draft-wessels-dns-zone-digest + SVCB => 64, # draft-ietf-dnsop-svcb-https-00 + HTTPS => 65, # draft-ietf-dnsop-svcb-https-00 SPF => 99, # RFC7208 UINFO => 100, # IANA-Reserved UID => 101, # IANA-Reserved @@ -184,7 +186,7 @@ # Registry: DNS EDNS0 Option Codes (OPT) my @ednsoptionbyname = ( - LLQ => 1, # RFC-sekar-dns-llq-06 + LLQ => 1, # RFC8764 UL => 2, # http://files.dns-sd.org/draft-sekar-dns-ul.txt NSID => 3, # RFC5001 DAU => 5, # RFC6975 @@ -233,10 +235,10 @@ KEEPALIVE => 0x0001, # RFC8490 RETRYDELAY => 0x0002, # RFC8490 ENCRYPTIONPADDING => 0x0003, # RFC8490 - SUBSCRIBE => 0x0040, # RFC-ietf-dnssd-push-25 - PUSH => 0x0041, # RFC-ietf-dnssd-push-25 - UNSUBSCRIBE => 0x0042, # RFC-ietf-dnssd-push-25 - RECONFIRM => 0x0043, # RFC-ietf-dnssd-push-25 + SUBSCRIBE => 0x0040, # RFC8765 + PUSH => 0x0041, # RFC8765 + UNSUBSCRIBE => 0x0042, # RFC8765 + RECONFIRM => 0x0043, # RFC8765 ); our %dsotypebyval = reverse @dsotypebyname; push @dsotypebyname, map /^\d/ ? $_ : lc($_), @dsotypebyname; @@ -298,62 +300,66 @@ sub opcodebyname { my $arg = shift; - return $opcodebyname{$arg} if defined $opcodebyname{$arg}; - return 0 + $arg if $arg =~ /^\d/; + my $val = $opcodebyname{$arg}; + return $val if defined $val; + return $arg if $arg =~ /^\d/; croak qq[unknown opcode "$arg"]; } sub opcodebyval { my $val = shift; - $opcodebyval{$val} || return $val; + $opcodebyval{$val} || return "$val"; } sub rcodebyname { my $arg = shift; - return $rcodebyname{$arg} if defined $rcodebyname{$arg}; - return 0 + $arg if $arg =~ /^\d/; + my $val = $rcodebyname{$arg}; + return $val if defined $val; + return $arg if $arg =~ /^\d/; croak qq[unknown rcode "$arg"]; } sub rcodebyval { my $val = shift; - $rcodebyval{$val} || return $val; + $rcodebyval{$val} || return "$val"; } sub ednsoptionbyname { my $arg = shift; - return $ednsoptionbyname{$arg} if defined $ednsoptionbyname{$arg}; - return 0 + $arg if $arg =~ /^\d/; + my $val = $ednsoptionbyname{$arg}; + return $val if defined $val; + return $arg if $arg =~ /^\d/; croak qq[unknown option "$arg"]; } sub ednsoptionbyval { my $val = shift; - $ednsoptionbyval{$val} || return $val; + $ednsoptionbyval{$val} || return "$val"; } sub dsotypebyname { my $arg = shift; - return $dsotypebyname{$arg} if defined $dsotypebyname{$arg}; - return 0 + $arg if $arg =~ /^\d/; + my $val = $dsotypebyname{$arg}; + return $val if defined $val; + return $arg if $arg =~ /^\d/; croak qq[unknown DSO type "$arg"]; } sub dsotypebyval { my $val = shift; - $dsotypebyval{$val} || return $val; + $dsotypebyval{$val} || return "$val"; } sub register { ## register( 'TOY', 1234 ) (NOT part of published API) my ( $mnemonic, $rrtype ) = map uc($_), @_; # uncoverable pod $rrtype = rand(255) + 65280 unless $rrtype; + croak qq["$mnemonic" is a CLASS identifier] if defined $classbyname{$mnemonic}; for ( typebyval( $rrtype = int $rrtype ) ) { - croak qq["$mnemonic" is a CLASS identifier] if $classbyname{$mnemonic}; - return $rrtype if /^$mnemonic$/; # duplicate registration + return $rrtype if /^$mnemonic$/; # duplicate registration croak qq["$mnemonic" conflicts with TYPE$rrtype ($_)] unless /^TYPE\d+$/; my $known = $typebyname{$mnemonic}; croak qq["$mnemonic" conflicts with TYPE$known] if $known; diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/Net-DNS-1.25/lib/Net/DNS/RR/HTTPS.pm new/Net-DNS-1.26/lib/Net/DNS/RR/HTTPS.pm --- old/Net-DNS-1.25/lib/Net/DNS/RR/HTTPS.pm 1970-01-01 01:00:00.000000000 +0100 +++ new/Net-DNS-1.26/lib/Net/DNS/RR/HTTPS.pm 2020-08-05 23:32:22.000000000 +0200 @@ -0,0 +1,81 @@ +package Net::DNS::RR::HTTPS; + +# +# $Id: HTTPS.pm 1795 2020-07-27 11:00:29Z willem $ +# +our $VERSION = (qw$LastChangedRevision: 1795 $)[1]; + + +use strict; +use warnings; +use base qw(Net::DNS::RR::SVCB); + +=head1 NAME + +Net::DNS::RR::HTTPS - DNS HTTPS resource record + +=cut + + +1; +__END__ + + +=head1 SYNOPSIS + + use Net::DNS; + $rr = new Net::DNS::RR('name HTTPS SvcPriority TargetName alpn=h3-29,h3-28,h3-27,h2 ...'); + +=head1 DESCRIPTION + +DNS HTTPS resource record + +The HTTPS class is derived from, and inherits all properties of, +the Net::DNS::RR::SVCB class. + +Please see the L<Net::DNS::RR::SVCB> documentation for details. + +=head1 METHODS + +The available methods are those inherited from the base class augmented +by the type-specific methods defined in this package. + +Use of undocumented package features or direct access to internal data +structures is discouraged and could result in program termination or +other unpredictable behaviour. + + + +=head1 COPYRIGHT + +Copyright (c)2020 Dick Franks. + +All rights reserved. + +Package template (c)2009,2012 O.M.Kolkman and R.W.Franks. + + +=head1 LICENSE + +Permission to use, copy, modify, and distribute this software and its +documentation for any purpose and without fee is hereby granted, provided +that the above copyright notice appear in all copies and that both that +copyright notice and this permission notice appear in supporting +documentation, and that the name of the author not be used in advertising +or publicity pertaining to distribution of the software without specific +prior written permission. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +DEALINGS IN THE SOFTWARE. + + +=head1 SEE ALSO + +L<perl>, L<Net::DNS>, L<Net::DNS::RR>, L<Net::DNS::RR::SVCB> + +=cut diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/Net-DNS-1.25/lib/Net/DNS/RR/SVCB.pm new/Net-DNS-1.26/lib/Net/DNS/RR/SVCB.pm --- old/Net-DNS-1.25/lib/Net/DNS/RR/SVCB.pm 1970-01-01 01:00:00.000000000 +0100 +++ new/Net-DNS-1.26/lib/Net/DNS/RR/SVCB.pm 2020-08-05 23:32:22.000000000 +0200 @@ -0,0 +1,387 @@ +package Net::DNS::RR::SVCB; + +# +# $Id: SVCB.pm 1800 2020-08-05 15:47:24Z willem $ +# +our $VERSION = (qw$LastChangedRevision: 1800 $)[1]; + + +use strict; +use warnings; +use base qw(Net::DNS::RR); + +=head1 NAME + +Net::DNS::RR::SVCB - DNS SVCB resource record + +=cut + + +use integer; + +use Carp; +use MIME::Base64; +use Net::DNS::DomainName; +use Net::DNS::RR::A; +use Net::DNS::RR::AAAA; +use Net::DNS::Text; + + +sub _decode_rdata { ## decode rdata from wire-format octet string + my $self = shift; + my ( $data, $offset ) = @_; + + my $rdata = substr $$data, $offset, $self->{rdlength}; + $self->{SvcPriority} = unpack( 'n', $rdata ); + + my $index; + ( $self->{TargetName}, $index ) = decode Net::DNS::DomainName( \$rdata, 2 ); + + my $params = $self->{SvcParams} = {}; + my $limit = length($rdata) - 4; + while ( $index < $limit ) { + my ( $key, $size ) = unpack( "\@$index n2", $rdata ); + $params->{$key} = substr $rdata, $index + 4, $size; + $index += ( $size + 4 ); + } + die 'corrupt RDATA in ' . $self->type unless $index == $self->{rdlength}; + $self->_post_parse; +} + + +sub _encode_rdata { ## encode rdata as wire-format octet string + my $self = shift; + + my ($params) = grep defined, $self->{SvcParams}, {}; + my @params; + foreach ( sort { $a <=> $b } keys %$params ) { + my $value = $params->{$_}; + next unless defined $value; + push @params, pack( 'n2a*', $_, length($value), $value ); + } + pack 'n a* a*', $self->{SvcPriority}, $self->{TargetName}->encode, join '', @params; +} + + +sub _format_rdata { ## format rdata portion of RR string. + my $self = shift; + + my ($params) = grep defined, $self->{SvcParams}, {}; + my @keys = keys %$params; + return ( $self->{SvcPriority}, $self->{TargetName}->string ) unless scalar @keys; + + my @rdata = unpack 'H4', pack 'n', $self->{SvcPriority}; + my $target = $self->{TargetName}->encode(); + my $length = 2 + length $target; + my @target = split /(\S{32})/, unpack 'H*', $target; + $target[$#target] .= join ' ', "\t;", $self->{TargetName}->string if $length > 3; + push @rdata, $length > 18 ? "\n" : (), @target, "\n"; + + foreach ( sort { $a <=> $b } @keys ) { + my $value = $params->{$_}; + next unless defined $value; + push @rdata, "; key$_=...\n" if $_ > 15; + push @rdata, unpack 'H4H4', pack( 'n2', $_, length $value ); + push @rdata, split /(\S{32})/, unpack 'H*', $value; + push @rdata, "\n"; + $length += 4 + length $value; + } + return ( '\\#', $length, @rdata ); +} + + +sub _parse_rdata { ## populate RR from rdata in argument list + my $self = shift; + + $self->svcpriority(shift); + $self->targetname(shift); + + while ( my $attribute = shift ) { + for ($attribute) { + my @argument = ''; + if (/=(.*)$/) { + for ( my $rhs = length($1) ? $1 : shift ) { + s/^(["'])(.*)\1$/$2/; # strip paired quotes + s/\\,/\\044/g; # disguise escaped comma + @argument = split /,/; # potentially multi-valued + } + } + + s/[-]/_/g; # extract attribute identifier + m/^([^=]+)/; + $self->$1(@argument); + } + } +} + + +sub _post_parse { ## parser post processing + my $self = shift; + + my $params = $self->{SvcParams} || return; + my %unique; + my @unique = grep !$unique{$_}++, unpack 'n*', $params->{0} || return; + croak( $self->type . qq(: mandatory "key0" not permitted) ) if $unique{0}; + map croak( $self->type . qq(: duplicate "key$_" in mandatory list) ), grep --$unique{$_}, @unique; + map croak( $self->type . qq(: mandatory "key$_" not defined) ), grep !defined( $params->{$_} ), @unique; +} + + +sub _defaults { ## specify RR attribute default values + my $self = shift; + + $self->_parse_rdata(qw(0 .)); +} + + +sub svcpriority { + my $self = shift; # uncoverable pod + + $self->{SvcPriority} = 0 + shift if scalar @_; + $self->{SvcPriority} || 0; +} + + +sub targetname { + my $self = shift; # uncoverable pod + + $self->{TargetName} = new Net::DNS::DomainName(shift) if scalar @_; + + my $target = $self->{TargetName} ? $self->{TargetName}->name : return; + return $target unless $self->{SvcPriority}; + return ( $target eq '.' ) ? $self->owner : $target; +} + + +######################################## + +use constant ASCII => chr(65) eq 'A'; + +my %escape = do { ## precalculated ASCII escape table + my @escape = ( 0 .. 32, 34, 92, 127 .. 255 ); # numerical escape + + my %table = map( ( $_ => $_ ), map pack( 'C', $_ ), ( 0 .. 255 ) ); + + foreach my $codepoint (@escape) { + my $ddd = sprintf( '%03u', $codepoint ); + $ddd =~ tr [0-9] [\060-\071]; # transliterate non-ASCII + $table{pack( 'C', $codepoint )} = pack 'C a3', 92, $ddd; + } + + %table; +}; + + +sub _raw { ## concatenate @_ and escape non-printable + return @_ unless scalar @_; + for ( join '', map $escape{$_}, map split(//), @_ ) { + + # partial transliteration for non-ASCII character encodings + tr + [\040-\176\000-\377] + [ !"#$%&'()*+,\-./0-9:;<=>?@A-Z\[\\\]^_`a-z{|}~?] unless ASCII; + + return $_; + } +} + +sub _base64 { + _raw( map MIME::Base64::decode($_), @_ ); +} + +sub _integer16 { + _raw( map pack( 'n', $_ ), @_ ); +} + +sub _ipv4 { + _raw( map bless( {}, 'Net::DNS::RR::A' )->address($_), @_ ); +} + +sub _ipv6 { + _raw( map bless( {}, 'Net::DNS::RR::AAAA' )->address($_), @_ ); +} + +sub _string { + _raw( map Net::DNS::Text->new($_)->encode(), @_ ); +} + + +my %keybyname = ( + mandatory => 0, + alpn => 1, + 'no-default-alpn' => 2, + port => 3, + ipv4hint => 4, + echconfig => 5, + ipv6hint => 6, + ); + + +sub mandatory { ## mandatory=key1,port,... + my ( $self, @arg ) = grep defined, @_; + my @keys = map $keybyname{lc $_} || ( /^key(\d+)$/ ? $1 : croak qq["$_" unknown] ), @arg; + $self->key0( _integer16( sort { $a <=> $b } @keys ) ); +} + +sub alpn { ## alpn=h3,h2,... + my $self = shift; + $self->key1( _string(@_) ); +} + +sub no_default_alpn { ## no-default-alpn + shift->key2( map '', @_ ); # uncoverable pod +} + +sub port { ## port=1234 + my $self = shift; + $self->key3( map _integer16($_), @_ ); +} + +sub ipv4hint { ## ipv4hint=192.0.2.1,... + my $self = shift; + $self->key4( _ipv4(@_) ); +} + +sub echconfig { ## echconfig=base64string + my $self = shift; + $self->key5( map _base64($_), @_ ); +} + +sub ipv6hint { ## ipv6hint=2001:DB8::1,... + my $self = shift; + $self->key6( _ipv6(@_) ); +} + + +our $AUTOLOAD; + +sub AUTOLOAD { ## Dynamic constructor/accessor methods + my $self = shift; + my ($method) = reverse split /::/, $AUTOLOAD; + + my $default = join '::', 'SUPER', $method; + return $self->$default(@_) unless $method =~ /^key(\d+)$/i; + my $key = $1; + + my ($params) = grep defined, $self->{SvcParams}, {}; + + if ( scalar @_ ) { + my $arg = shift; # keyNN($value); + croak 'unexpected number of arguments' if scalar @_; + + $params->{$key} = defined($arg) ? Net::DNS::Text->new($arg)->raw : undef; + $self->{SvcParams} = $params; + } + + my $value = $params->{$key}; + return defined($value) ? _raw($value) : $value if defined wantarray; +} + + +1; +__END__ + + +=head1 SYNOPSIS + + use Net::DNS; + $rr = new Net::DNS::RR('name HTTPS SvcPriority TargetName alpn=h3,...'); + +=head1 DESCRIPTION + +DNS Service Binding (SVCB) resource record + +Service binding and parameter specification +via the DNS (SVCB and HTTPS RRs) + +=head1 METHODS + +The available methods are those inherited from the base class augmented +by the type-specific methods defined in this package. + +Use of undocumented package features or direct access to internal data +structures is discouraged and could result in program termination or +other unpredictable behaviour. + + +=head2 SvcPriority + + $svcpriority = $rr->svcpriority; + $rr->svcpriority( $svcpriority ); + +The priority of this record +(relative to others, with lower values preferred). +A value of 0 indicates AliasMode. + +=head2 TargetName + + $rr->targetname( $targetname ); + $effecivetarget = $rr->targetname; + +The domain name of either the alias target (for AliasMode) +or the alternative endpoint (for ServiceMode). + +For AliasMode SVCB RRs, a TargetName of "." indicates that the +service is not available or does not exist. + +For ServiceMode SVCB RRs, a TargetName of "." indicates that the +owner name of this record must be used as the effective TargetName. + +=head2 mandatory, alpn, no-default-alpn, port, ipv4hint, echconfig, ipv6hint + + $rr = new Net::DNS::RR( 'svc.example. SVCB 1 svc.example. port=1234' ); + + $rr->port(1234); + $string = $rr->port(); # \004\210 + $rr->key3($string); + +Constructor methods for mnemonic SvcParams defined in draft-ietf-dnsop-svcb-https-01. +When invoked without arguments, the methods return the presentation format +value for the underlying key. +The behaviour with undefined arguments is not specified. + +=head2 keyNN + + $keyNN = $rr->keyNN; + $rr->keyNN( $keyNN ); + +Generic constructor and accessor methods for SvcParams. +The key index NN is a decimal integer in the range 0 .. 65534. +The method argument and returned value are both presentation format strings. +The method returns the undefined value if the key is not present. +A (key,value) pair will be ignored if the value is undefined. + + +=head1 COPYRIGHT + +Copyright (c)2020 Dick Franks. + +All rights reserved. + +Package template (c)2009,2012 O.M.Kolkman and R.W.Franks. + + +=head1 LICENSE + +Permission to use, copy, modify, and distribute this software and its +documentation for any purpose and without fee is hereby granted, provided +that the above copyright notice appear in all copies and that both that +copyright notice and this permission notice appear in supporting +documentation, and that the name of the author not be used in advertising +or publicity pertaining to distribution of the software without specific +prior written permission. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +DEALINGS IN THE SOFTWARE. + + +=head1 SEE ALSO + +L<perl>, L<Net::DNS>, L<Net::DNS::RR>, draft-ietf-dnsop-svcb-https-01 + +=cut diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/Net-DNS-1.25/lib/Net/DNS/RR.pm new/Net-DNS-1.26/lib/Net/DNS/RR.pm --- old/Net-DNS-1.25/lib/Net/DNS/RR.pm 2020-06-26 17:14:19.000000000 +0200 +++ new/Net-DNS-1.26/lib/Net/DNS/RR.pm 2020-08-05 23:32:22.000000000 +0200 @@ -1,9 +1,9 @@ package Net::DNS::RR; # -# $Id: RR.pm 1762 2020-02-02 21:39:02Z willem $ +# $Id: RR.pm 1796 2020-07-28 08:22:47Z willem $ # -our $VERSION = (qw$LastChangedRevision: 1762 $)[1]; +our $VERSION = (qw$LastChangedRevision: 1796 $)[1]; =head1 NAME @@ -139,6 +139,7 @@ } $self->_parse_rdata(@token); # parse arguments + $self->_post_parse(); return $self; } @@ -195,6 +196,7 @@ }; die ref($self) eq __PACKAGE__ ? "type $type not implemented" : () if $@; + $self->_post_parse(); return $self; } @@ -502,9 +504,8 @@ sub _format_rdata { ## format rdata portion of RR string - my $data = shift->rdata; - my $size = length($data); # RFC3597 unknown RR format - my @data = ( '\\#', $size, split /(\S{32})/, unpack 'H*', $data ); + my $rdata = shift->rdata; # RFC3597 unknown RR format + my @rdata = ( '\\#', length($rdata), split /(\S{32})/, unpack 'H*', $rdata ); } @@ -515,6 +516,9 @@ } +sub _post_parse { } ## parser post processing + + sub _defaults { } ## set attribute default values @@ -724,7 +728,8 @@ my %ignore = map( ( $_ => 1 ), @core, 'annotation', '#' ); sub _empty { - not( $_[0]->{'#'} ||= scalar grep !$ignore{$_}, keys %{$_[0]} ); + my $self = shift; + not( $self->{'#'} ||= scalar grep !$ignore{$_}, keys %$self ); } @@ -737,13 +742,14 @@ foreach (@text) { s/\\034/\\"/g; # unescape " s/\\092/\\\\/g; # unescape escape - if ( ( $coln += 1 + length ) > $cols ) { # start new line - push @line, join ' ', @fill if scalar @fill; + $coln += ( length || next ) + 1; + if ( $coln > $cols ) { # start new line + push( @line, join ' ', @fill ) if @fill; $coln = length; @fill = (); } - $coln = $cols if chomp; # force line break - push( @fill, $_ ); + $coln = $cols if chomp; # force line break + push( @fill, $_ ) if length; } push @line, join ' ', @fill; return @line; @@ -758,11 +764,15 @@ sub AUTOLOAD { ## Default method my $self = shift; - my $oref = ref($self); + my ($method) = reverse split /::/, $AUTOLOAD; + + for ($method) { ## tolerate mixed-case attribute name + return $self->$_(@_) if tr [A-Z-] [a-z_]; + } no strict q/refs/; - my ($method) = reverse split /::/, $AUTOLOAD; *{$AUTOLOAD} = sub {undef}; ## suppress repetition and deep recursion + my $oref = ref($self); croak qq[$self has no class method "$method"] unless $oref; my $string = $self->string; diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/Net-DNS-1.25/lib/Net/DNS/Resolver/Base.pm new/Net-DNS-1.26/lib/Net/DNS/Resolver/Base.pm --- old/Net-DNS-1.25/lib/Net/DNS/Resolver/Base.pm 2020-06-26 17:14:19.000000000 +0200 +++ new/Net-DNS-1.26/lib/Net/DNS/Resolver/Base.pm 2020-08-05 23:32:22.000000000 +0200 @@ -1,9 +1,9 @@ package Net::DNS::Resolver::Base; # -# $Id: Base.pm 1786 2020-06-15 15:05:47Z willem $ +# $Id: Base.pm 1794 2020-07-03 13:36:51Z willem $ # -our $VERSION = (qw$LastChangedRevision: 1786 $)[1]; +our $VERSION = (qw$LastChangedRevision: 1794 $)[1]; # @@ -967,11 +967,15 @@ my ($packet) = @_; if ( ref($packet) ) { + my $edns = $packet->edns; # advertise UDPsize for local stack + $edns->size( $self->{udppacketsize} ) unless defined $edns->{size}; + my $header = $packet->header; $header->rd( $self->{recurse} ) if $header->opcode eq 'QUERY'; } else { $packet = Net::DNS::Packet->new(@_); + $packet->edns->size( $self->{udppacketsize} ); my $header = $packet->header; $header->ad( $self->{adflag} ); # RFC6840, 5.7 @@ -980,8 +984,6 @@ $header->rd( $self->{recurse} ); } - $packet->edns->size( $self->{udppacketsize} ); # advertise UDPsize for local stack - if ( $self->{tsig_rr} ) { $packet->sign_tsig( $self->{tsig_rr} ) unless $packet->sigrr; } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/Net-DNS-1.25/lib/Net/DNS/Resolver/os390.pm new/Net-DNS-1.26/lib/Net/DNS/Resolver/os390.pm --- old/Net-DNS-1.25/lib/Net/DNS/Resolver/os390.pm 2020-06-26 17:14:19.000000000 +0200 +++ new/Net-DNS-1.26/lib/Net/DNS/Resolver/os390.pm 2020-08-05 23:32:22.000000000 +0200 @@ -1,9 +1,9 @@ package Net::DNS::Resolver::os390; # -# $Id: os390.pm 1719 2018-11-04 05:01:43Z willem $ +# $Id: os390.pm 1795 2020-07-27 11:00:29Z willem $ # -our $VERSION = (qw$LastChangedRevision: 1719 $)[1]; +our $VERSION = (qw$LastChangedRevision: 1795 $)[1]; =head1 NAME @@ -17,8 +17,9 @@ use warnings; use base qw(Net::DNS::Resolver::Base); +use IO::File; -local $ENV{PATH} = '/bin:/usr/bin'; +local $ENV{PATH} = join ':', grep $_, qw(/bin /usr/bin), $ENV{PATH}; my $sysname = eval {`sysvar SYSNAME 2>/dev/null`} || ''; chomp $sysname; @@ -54,18 +55,18 @@ sub _init { my $defaults = shift->_defaults; my %stop; - local $ENV{PATH} = '/bin:/usr/bin'; + local $ENV{PATH} = join ':', grep $_, qw(/bin /usr/bin), $ENV{PATH}; foreach my $dataset ( Net::DNS::Resolver::Base::_untaint( grep defined, @dataset ) ) { eval { - my $filehandle; # "cat" able to read MVS dataset - open( $filehandle, '-|', qq[cat "$dataset" 2>/dev/null] ) or die "$dataset: $!"; - + local $_; my @nameserver; my @searchlist; - local $_; - while (<$filehandle>) { + my $handle = new IO::File( qq[cat "$dataset" 2>/dev/null], '-|' ) + or die "$dataset: $!"; # "cat" able to read MVS datasets + + while (<$handle>) { s/[;#].*$//; # strip comment s/^\s+//; # strip leading white space next unless $_; # skip empty line @@ -122,7 +123,7 @@ }; } - close($filehandle); + close($handle); $defaults->nameserver(@nameserver) if @nameserver && !$stop{nameserver}++; $defaults->searchlist(@searchlist) if @searchlist && !$stop{search}++; diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/Net-DNS-1.25/lib/Net/DNS.pm new/Net-DNS-1.26/lib/Net/DNS.pm --- old/Net-DNS-1.25/lib/Net/DNS.pm 2020-06-26 17:14:19.000000000 +0200 +++ new/Net-DNS-1.26/lib/Net/DNS.pm 2020-08-05 23:32:22.000000000 +0200 @@ -1,13 +1,13 @@ package Net::DNS; # -# $Id: DNS.pm 1792 2020-06-26 14:43:25Z willem $ +# $Id: DNS.pm 1801 2020-08-05 15:49:06Z willem $ # require 5.006; our $VERSION; -$VERSION = '1.25'; +$VERSION = '1.26'; $VERSION = eval $VERSION; -our $SVNVERSION = (qw$LastChangedRevision: 1792 $)[1]; +our $SVNVERSION = (qw$LastChangedRevision: 1801 $)[1]; =head1 NAME diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/Net-DNS-1.25/t/03-rr.t new/Net-DNS-1.26/t/03-rr.t --- old/Net-DNS-1.25/t/03-rr.t 2020-06-26 17:14:19.000000000 +0200 +++ new/Net-DNS-1.26/t/03-rr.t 2020-08-05 23:32:22.000000000 +0200 @@ -1,4 +1,4 @@ -# $Id: 03-rr.t 1749 2019-07-21 09:15:55Z willem $ -*-perl-*- +# $Id: 03-rr.t 1795 2020-07-27 11:00:29Z willem $ -*-perl-*- use strict; use Test::More tests => 108; @@ -144,7 +144,7 @@ { ## check for exception for nonexistent attribute - my $method = 'bogus'; + my $method = 'bogus-method'; foreach my $testcase ( [ type => 'A' ], [ type => 'ATMA' ], @@ -320,6 +320,8 @@ select( ( select(TEMP), $object->dump )[0] ); close(TEMP); unlink($filename); + + Net::DNS::RR::_wrap( 'exercise', '', "\n", "\n", "line\n", 'wrapping' ); }; diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/Net-DNS-1.25/t/05-OPT.t new/Net-DNS-1.26/t/05-OPT.t --- old/Net-DNS-1.25/t/05-OPT.t 2020-06-26 17:14:19.000000000 +0200 +++ new/Net-DNS-1.26/t/05-OPT.t 2020-08-05 23:32:22.000000000 +0200 @@ -1,4 +1,4 @@ -# $Id: 05-OPT.t 1784 2020-05-24 19:27:13Z willem $ -*-perl-*- +# $Id: 05-OPT.t 1796 2020-07-28 08:22:47Z willem $ -*-perl-*- use strict; use Test::More; @@ -81,7 +81,7 @@ { - my $rr = new Net::DNS::RR( name => '.', type => $type, version => 1, rcode => 16 ); + my $rr = new Net::DNS::RR( type => $type, version => 1, rcode => 16 ); $rr->{rdlength} = 0; # inbound OPT RR only like( $rr->string, '/BADVER/', 'opt->rcode(16)' ); } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/Net-DNS-1.25/t/05-TSIG.t new/Net-DNS-1.26/t/05-TSIG.t --- old/Net-DNS-1.25/t/05-TSIG.t 2020-06-26 17:14:19.000000000 +0200 +++ new/Net-DNS-1.26/t/05-TSIG.t 2020-08-05 23:32:22.000000000 +0200 @@ -1,4 +1,4 @@ -# $Id: 05-TSIG.t 1779 2020-05-11 09:11:17Z willem $ -*-perl-*- +# $Id: 05-TSIG.t 1796 2020-07-28 08:22:47Z willem $ -*-perl-*- # use strict; @@ -114,11 +114,13 @@ { # Check default signing function using test cases from RFC2202, section 2. + my $expected = new Net::DNS::RR( type => 'TSIG', algorithm => 'HMAC-MD5.SIG-ALG.REG.INT' ); + my $tsig = new Net::DNS::RR( type => 'TSIG', fudge => 300 ); my $function = $tsig->sig_function; # default signing function my $algorithm = $tsig->algorithm; # default algorithm - is( $algorithm, 'HMAC-MD5.SIG-ALG.REG.INT', 'Check algorithm correctly identified' ); + is( $algorithm, $expected->algorithm, 'Check algorithm correctly identified' ); { my $data = pack 'H*', '4869205468657265'; diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/Net-DNS-1.25/t/08-IPv4.t new/Net-DNS-1.26/t/08-IPv4.t --- old/Net-DNS-1.25/t/08-IPv4.t 2020-06-26 17:14:19.000000000 +0200 +++ new/Net-DNS-1.26/t/08-IPv4.t 2020-08-05 23:32:22.000000000 +0200 @@ -1,4 +1,4 @@ -# $Id: 08-IPv4.t 1784 2020-05-24 19:27:13Z willem $ -*-perl-*- +# $Id: 08-IPv4.t 1794 2020-07-03 13:36:51Z willem $ -*-perl-*- use strict; use Test::More; @@ -19,7 +19,6 @@ my @nsdname = qw( ns.net-dns.org - mcvax.nlnet.nl ns.nlnetlabs.nl ); @@ -312,7 +311,7 @@ } -{ +SKIP: { my $resolver = Net::DNS::Resolver->new( nameservers => $IP ); $resolver->tcp_timeout(10); @@ -325,6 +324,7 @@ my $iterator = $resolver->axfr('net-dns.org'); ok( ref($iterator), '$resolver->axfr() returns iterator in scalar context' ); + skip( 'AXFR iterator tests', 4 ) unless $iterator; my $soa = $iterator->(); is( ref($soa), 'Net::DNS::RR::SOA', '$iterator->() returns initial SOA RR' ); @@ -356,7 +356,7 @@ ok( !scalar(@notauth), "mismatched zone\t[$notauth]" ); eval { $resolver->tsig($bad_key) }; - skip( 'failed AXFR tests', 3 ) if $@; + skip( 'TSIG failure reporting', 2 ) if $@; my @unverifiable = $resolver->axfr(); my $errorstring = $resolver->errorstring; ok( !scalar(@unverifiable), "mismatched key\t[$errorstring]" ); diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/Net-DNS-1.25/t/08-IPv6.t new/Net-DNS-1.26/t/08-IPv6.t --- old/Net-DNS-1.25/t/08-IPv6.t 2020-06-26 17:14:19.000000000 +0200 +++ new/Net-DNS-1.26/t/08-IPv6.t 2020-08-05 23:32:22.000000000 +0200 @@ -1,4 +1,4 @@ -# $Id: 08-IPv6.t 1784 2020-05-24 19:27:13Z willem $ -*-perl-*- +# $Id: 08-IPv6.t 1794 2020-07-03 13:36:51Z willem $ -*-perl-*- use strict; use Test::More; @@ -19,7 +19,6 @@ my @nsdname = qw( ns.net-dns.org - mcvax.nlnet.nl ns.nlnetlabs.nl ); @@ -315,7 +314,7 @@ } -{ +SKIP: { my $resolver = Net::DNS::Resolver->new( nameservers => $IP ); $resolver->tcp_timeout(10); @@ -328,6 +327,7 @@ my $iterator = $resolver->axfr('net-dns.org'); ok( ref($iterator), '$resolver->axfr() returns iterator in scalar context' ); + skip( 'AXFR iterator tests', 4 ) unless $iterator; my $soa = $iterator->(); is( ref($soa), 'Net::DNS::RR::SOA', '$iterator->() returns initial SOA RR' ); @@ -359,7 +359,7 @@ ok( !scalar(@notauth), "mismatched zone\t[$notauth]" ); eval { $resolver->tsig($bad_key) }; - skip( 'failed AXFR tests', 3 ) if $@; + skip( 'AXFR failure reporting', 2 ) if $@; my @unverifiable = $resolver->axfr(); my $errorstring = $resolver->errorstring; ok( !scalar(@unverifiable), "mismatched key\t[$errorstring]" );
