Blame t/08-IPv4.t

Packit e6c8bb
# $Id: 08-IPv4.t 1628 2018-02-01 13:29:13Z willem $ -*-perl-*-
Packit e6c8bb
Packit e6c8bb
use strict;
Packit e6c8bb
use Test::More;
Packit e6c8bb
Packit e6c8bb
BEGIN {
Packit e6c8bb
	local @INC = ( @INC, qw(t) );
Packit e6c8bb
	require NonFatal;
Packit e6c8bb
}
Packit e6c8bb
Packit e6c8bb
use Net::DNS;
Packit e6c8bb
use IO::Select;
Packit e6c8bb
Packit e6c8bb
my $debug = 0;
Packit e6c8bb
Packit e6c8bb
my @hints = qw(
Packit e6c8bb
		198.41.0.4
Packit e6c8bb
		192.228.79.201
Packit e6c8bb
		192.33.4.12
Packit e6c8bb
		199.7.91.13
Packit e6c8bb
		192.203.230.10
Packit e6c8bb
		192.5.5.241
Packit e6c8bb
		192.112.36.4
Packit e6c8bb
		198.97.190.53
Packit e6c8bb
		192.36.148.17
Packit e6c8bb
		192.58.128.30
Packit e6c8bb
		193.0.14.129
Packit e6c8bb
		199.7.83.42
Packit e6c8bb
		202.12.27.33
Packit e6c8bb
		);
Packit e6c8bb
Packit e6c8bb
my $NOIP = qw(0.0.0.0);
Packit e6c8bb
Packit e6c8bb
my @nsdname = qw(
Packit e6c8bb
		ns.net-dns.org
Packit e6c8bb
		mcvax.nlnet.nl
Packit e6c8bb
		ns.nlnetlabs.nl
Packit e6c8bb
		);
Packit e6c8bb
Packit e6c8bb
Packit e6c8bb
exit( plan skip_all => 'Online tests disabled.' ) if -e 't/online.disabled';
Packit e6c8bb
exit( plan skip_all => 'Online tests disabled.' ) unless -e 't/online.enabled';
Packit e6c8bb
Packit e6c8bb
Packit e6c8bb
eval {
Packit e6c8bb
	my $resolver = new Net::DNS::Resolver( igntc => 1 );
Packit e6c8bb
	exit plan skip_all => 'No nameservers' unless $resolver->nameservers;
Packit e6c8bb
Packit e6c8bb
	my $reply = $resolver->send(qw(. NS IN)) || die;
Packit e6c8bb
Packit e6c8bb
	my @ns = grep $_->type eq 'NS', $reply->answer, $reply->authority;
Packit e6c8bb
	exit plan skip_all => 'Local nameserver broken' unless scalar @ns;
Packit e6c8bb
Packit e6c8bb
	1;
Packit e6c8bb
} || exit( plan skip_all => 'Non-responding local nameserver' );
Packit e6c8bb
Packit e6c8bb
Packit e6c8bb
eval {
Packit e6c8bb
	my $resolver = new Net::DNS::Resolver( nameservers => [@hints] );
Packit e6c8bb
	exit plan skip_all => 'No IPv4 transport' unless $resolver->nameservers;
Packit e6c8bb
Packit e6c8bb
	my $reply = $resolver->send(qw(. NS IN)) || die;
Packit e6c8bb
	my $from = $reply->answerfrom();
Packit e6c8bb
Packit e6c8bb
	my @ns = grep $_->type eq 'NS', $reply->answer, $reply->authority;
Packit e6c8bb
	exit plan skip_all => "Unexpected response from $from" unless scalar @ns;
Packit e6c8bb
Packit e6c8bb
	exit plan skip_all => "Non-authoritative response from $from" unless $reply->header->aa;
Packit e6c8bb
Packit e6c8bb
	1;
Packit e6c8bb
} || exit( plan skip_all => 'Unable to reach global root nameservers' );
Packit e6c8bb
Packit e6c8bb
Packit e6c8bb
my $IP = eval {
Packit e6c8bb
	my $resolver = new Net::DNS::Resolver();
Packit e6c8bb
	$resolver->nameservers(@nsdname);
Packit e6c8bb
	$resolver->force_v4(1);
Packit e6c8bb
	[$resolver->nameservers()];
Packit e6c8bb
};
Packit e6c8bb
exit( plan skip_all => 'Unable to resolve nameserver name' ) unless scalar @$IP;
Packit e6c8bb
Packit e6c8bb
diag join( "\n\t", 'will use nameservers', @$IP ) if $debug;
Packit e6c8bb
Packit e6c8bb
Net::DNS::Resolver->debug($debug);
Packit e6c8bb
Packit e6c8bb
Packit e6c8bb
plan tests => 94;
Packit e6c8bb
Packit e6c8bb
NonFatalBegin();
Packit e6c8bb
Packit e6c8bb
Packit e6c8bb
{
Packit e6c8bb
	my $resolver = Net::DNS::Resolver->new( nameservers => $IP );
Packit e6c8bb
Packit e6c8bb
	my $udp = $resolver->send(qw(net-dns.org SOA IN));
Packit e6c8bb
	ok( $udp, '$resolver->send(...)	UDP' );
Packit e6c8bb
Packit e6c8bb
	$resolver->usevc(1);
Packit e6c8bb
Packit e6c8bb
	my $tcp = $resolver->send(qw(net-dns.org SOA IN));
Packit e6c8bb
	ok( $tcp, '$resolver->send(...)	TCP' );
Packit e6c8bb
}
Packit e6c8bb
Packit e6c8bb
Packit e6c8bb
{
Packit e6c8bb
	my $resolver = Net::DNS::Resolver->new( nameservers => $IP );
Packit e6c8bb
	$resolver->dnssec(1);
Packit e6c8bb
	$resolver->udppacketsize(513);
Packit e6c8bb
Packit e6c8bb
	$resolver->igntc(1);
Packit e6c8bb
	my $udp = $resolver->send(qw(net-dns.org DNSKEY IN));
Packit e6c8bb
	ok( $udp && $udp->header->tc, '$resolver->send(...)	truncated UDP reply' );
Packit e6c8bb
Packit e6c8bb
	$resolver->igntc(0);
Packit e6c8bb
	my $retry = $resolver->send(qw(net-dns.org DNSKEY IN));
Packit e6c8bb
	ok( $retry && !$retry->header->tc, '$resolver->send(...)	automatic TCP retry' );
Packit e6c8bb
}
Packit e6c8bb
Packit e6c8bb
Packit e6c8bb
{
Packit e6c8bb
	my $resolver = Net::DNS::Resolver->new( nameservers => $IP );
Packit e6c8bb
	$resolver->igntc(0);
Packit e6c8bb
Packit e6c8bb
	my $udp = $resolver->bgsend(qw(net-dns.org SOA IN));
Packit e6c8bb
	ok( $udp, '$resolver->bgsend(...)	UDP' );
Packit e6c8bb
	while ( $resolver->bgbusy($udp) ) { sleep 1; }
Packit e6c8bb
	ok( $resolver->bgisready($udp), '$resolver->bgisready($udp)' );
Packit e6c8bb
	ok( $resolver->bgread($udp),	'$resolver->bgread($udp)' );
Packit e6c8bb
Packit e6c8bb
	$resolver->usevc(1);
Packit e6c8bb
Packit e6c8bb
	my $tcp = $resolver->bgsend(qw(net-dns.org SOA IN));
Packit e6c8bb
	ok( $tcp, '$resolver->bgsend(...)	TCP' );
Packit e6c8bb
	while ( $resolver->bgbusy($tcp) ) { sleep 1; }
Packit e6c8bb
	ok( $resolver->bgread($tcp), '$resolver->bgread($tcp)' );
Packit e6c8bb
Packit e6c8bb
	ok( !$resolver->bgbusy(undef), '!$resolver->bgbusy(undef)' );
Packit e6c8bb
	ok( !$resolver->bgread(undef), '!$resolver->bgread(undef)' );
Packit e6c8bb
Packit e6c8bb
	$resolver->udp_timeout(0);
Packit e6c8bb
	ok( !$resolver->bgread( ref($udp)->new ), '!$resolver->bgread(Socket->new)' );
Packit e6c8bb
}
Packit e6c8bb
Packit e6c8bb
Packit e6c8bb
{
Packit e6c8bb
	my $resolver = Net::DNS::Resolver->new( nameservers => $IP );
Packit e6c8bb
	$resolver->dnssec(1);
Packit e6c8bb
	$resolver->udppacketsize(513);
Packit e6c8bb
	$resolver->igntc(1);
Packit e6c8bb
Packit e6c8bb
	my $handle = $resolver->bgsend(qw(net-dns.org DNSKEY IN));
Packit e6c8bb
	ok( $handle, '$resolver->bgsend(...)	truncated UDP' );
Packit e6c8bb
	my $packet = $resolver->bgread($handle);
Packit e6c8bb
	ok( $packet && $packet->header->tc, '$resolver->bgread($udp)	ignore UDP truncation' );
Packit e6c8bb
}
Packit e6c8bb
Packit e6c8bb
Packit e6c8bb
{
Packit e6c8bb
	my $resolver = Net::DNS::Resolver->new( nameservers => $IP );
Packit e6c8bb
	$resolver->dnssec(1);
Packit e6c8bb
	$resolver->udppacketsize(513);
Packit e6c8bb
	$resolver->igntc(0);
Packit e6c8bb
Packit e6c8bb
	my $handle = $resolver->bgsend(qw(net-dns.org DNSKEY IN));
Packit e6c8bb
	ok( $handle, '$resolver->bgsend(...)	truncated UDP' );
Packit e6c8bb
	my $packet = $resolver->bgread($handle);
Packit e6c8bb
	ok( $packet && !$packet->header->tc, '$resolver->bgread($tcp)	background TCP retry' );
Packit e6c8bb
}
Packit e6c8bb
Packit e6c8bb
Packit e6c8bb
{
Packit e6c8bb
	my $resolver = Net::DNS::Resolver->new( nameservers => $IP );
Packit e6c8bb
	$resolver->dnssec(1);
Packit e6c8bb
	$resolver->udppacketsize(513);
Packit e6c8bb
	$resolver->igntc(0);
Packit e6c8bb
Packit e6c8bb
	my $handle = $resolver->bgsend(qw(net-dns.org DNSKEY IN));
Packit e6c8bb
	$resolver->nameserver($NOIP);
Packit e6c8bb
	my $packet = $resolver->bgread($handle);
Packit e6c8bb
	ok( $packet && $packet->header->tc, '$resolver->bgread($udp)	background TCP fail' );
Packit e6c8bb
}
Packit e6c8bb
Packit e6c8bb
Packit e6c8bb
{
Packit e6c8bb
	my $resolver = Net::DNS::Resolver->new( nameservers => $IP );
Packit e6c8bb
Packit e6c8bb
	my $handle = $resolver->bgsend(qw(net-dns.org SOA IN));
Packit e6c8bb
	delete ${*$handle}{net_dns_bg};
Packit e6c8bb
	my $bgread = $resolver->bgread($handle);
Packit e6c8bb
	ok( $bgread, '$resolver->bgread($udp)	workaround for SpamAssassin' );
Packit e6c8bb
}
Packit e6c8bb
Packit e6c8bb
Packit e6c8bb
{
Packit e6c8bb
	my $resolver = Net::DNS::Resolver->new( nameservers => $IP );
Packit e6c8bb
	$resolver->persistent_udp(1);
Packit e6c8bb
Packit e6c8bb
	my $handle = $resolver->bgsend(qw(net-dns.org SOA IN));
Packit e6c8bb
	ok( $handle, '$resolver->bgsend(...)	persistent UDP' );
Packit e6c8bb
	my $bgread = $resolver->bgread($handle);
Packit e6c8bb
	ok( $bgread, '$resolver->bgread($udp)' );
Packit e6c8bb
	my $test = $resolver->bgsend(qw(net-dns.org SOA IN));
Packit e6c8bb
	ok( $test, '$resolver->bgsend(...)	persistent UDP' );
Packit e6c8bb
	is( $test, $handle, 'same UDP socket object used' );
Packit e6c8bb
}
Packit e6c8bb
Packit e6c8bb
Packit e6c8bb
{
Packit e6c8bb
	my $resolver = Net::DNS::Resolver->new( nameservers => $IP );
Packit e6c8bb
	$resolver->persistent_tcp(1);
Packit e6c8bb
	$resolver->usevc(1);
Packit e6c8bb
Packit e6c8bb
	my $handle = $resolver->bgsend(qw(net-dns.org SOA IN));
Packit e6c8bb
	ok( $handle, '$resolver->bgsend(...)	persistent TCP' );
Packit e6c8bb
	my $bgread = $resolver->bgread($handle);
Packit e6c8bb
	ok( $bgread, '$resolver->bgread($tcp)' );
Packit e6c8bb
	my $test = $resolver->bgsend(qw(net-dns.org SOA IN));
Packit e6c8bb
	ok( $test, '$resolver->bgsend(...)	persistent TCP' );
Packit e6c8bb
	is( $test, $handle, 'same TCP socket object used' );
Packit e6c8bb
	eval { close($handle) };
Packit e6c8bb
	my $recover = $resolver->bgsend(qw(net-dns.org SOA IN));
Packit e6c8bb
	ok( $recover, 'connection recovered after close' );
Packit e6c8bb
}
Packit e6c8bb
Packit e6c8bb
Packit e6c8bb
{
Packit e6c8bb
	my $resolver = Net::DNS::Resolver->new( nameservers => $IP );
Packit e6c8bb
	$resolver->srcaddr($NOIP);
Packit e6c8bb
Packit e6c8bb
	my $udp = $resolver->bgsend(qw(net-dns.org SOA IN));
Packit e6c8bb
	ok( $udp, '$resolver->bgsend(...)	specify UDP local address' );
Packit e6c8bb
Packit e6c8bb
	$resolver->usevc(1);
Packit e6c8bb
Packit e6c8bb
	my $tcp = $resolver->bgsend(qw(net-dns.org SOA IN));
Packit e6c8bb
	ok( $tcp, '$resolver->bgsend(...)	specify TCP local address' );
Packit e6c8bb
}
Packit e6c8bb
Packit e6c8bb
Packit e6c8bb
{
Packit e6c8bb
	my $resolver = Net::DNS::Resolver->new( nameservers => $IP );
Packit e6c8bb
	$resolver->srcport(2345);
Packit e6c8bb
Packit e6c8bb
	my $udp = $resolver->bgsend(qw(net-dns.org SOA IN));
Packit e6c8bb
	ok( $udp, '$resolver->bgsend(...)	specify UDP source port' );
Packit e6c8bb
Packit e6c8bb
	$resolver->usevc(1);
Packit e6c8bb
Packit e6c8bb
	my $tcp = $resolver->bgsend(qw(net-dns.org SOA IN));
Packit e6c8bb
	ok( $tcp, '$resolver->bgsend(...)	specify TCP source port' );
Packit e6c8bb
}
Packit e6c8bb
Packit e6c8bb
Packit e6c8bb
{
Packit e6c8bb
	my $resolver = Net::DNS::Resolver->new( nameservers => $IP );
Packit e6c8bb
	my $badport = -1;
Packit e6c8bb
	$resolver->srcport($badport);
Packit e6c8bb
Packit e6c8bb
	my $udp = $resolver->send(qw(net-dns.org SOA IN));
Packit e6c8bb
	ok( !$udp, "\$resolver->send(...)	reject UDP source port $badport" );
Packit e6c8bb
Packit e6c8bb
	$resolver->usevc(1);
Packit e6c8bb
Packit e6c8bb
	my $tcp = $resolver->send(qw(net-dns.org SOA IN));
Packit e6c8bb
	ok( !$tcp, "\$resolver->send(...)	reject TCP source port $badport" );
Packit e6c8bb
}
Packit e6c8bb
Packit e6c8bb
Packit e6c8bb
{
Packit e6c8bb
	my $resolver = Net::DNS::Resolver->new( nameservers => $IP );
Packit e6c8bb
	my $badport = -1;
Packit e6c8bb
	$resolver->srcport($badport);
Packit e6c8bb
Packit e6c8bb
	my $udp = $resolver->bgsend(qw(net-dns.org SOA IN));
Packit e6c8bb
	ok( !$udp, "\$resolver->bgsend(...)	reject UDP source port $badport" );
Packit e6c8bb
Packit e6c8bb
	$resolver->usevc(1);
Packit e6c8bb
Packit e6c8bb
	my $tcp = $resolver->bgsend(qw(net-dns.org SOA IN));
Packit e6c8bb
	ok( !$tcp, "\$resolver->bgsend(...)	reject TCP source port $badport" );
Packit e6c8bb
}
Packit e6c8bb
Packit e6c8bb
Packit e6c8bb
SKIP: {
Packit e6c8bb
	my $resolver = Net::DNS::Resolver->new( nameservers => $IP );
Packit e6c8bb
	$resolver->domain('net-dns.org');
Packit e6c8bb
	eval { $resolver->tsig( $resolver->query(qw(tsig-md5 KEY))->answer ) };
Packit e6c8bb
	skip( 'automatic TSIG tests', 3 ) if $@;
Packit e6c8bb
Packit e6c8bb
	$resolver->igntc(1);
Packit e6c8bb
Packit e6c8bb
	my $udp = $resolver->send(qw(net-dns.org SOA IN));
Packit e6c8bb
	ok( $udp, '$resolver->send(...)	UDP + automatic TSIG' );
Packit e6c8bb
Packit e6c8bb
	$resolver->usevc(1);
Packit e6c8bb
Packit e6c8bb
	my $tcp = $resolver->send(qw(net-dns.org SOA IN));
Packit e6c8bb
	ok( $tcp, '$resolver->send(...)	TCP + automatic TSIG' );
Packit e6c8bb
Packit e6c8bb
	my $bgread;
Packit e6c8bb
	foreach my $ip (@$IP) {
Packit e6c8bb
		$resolver->nameserver($ip);
Packit e6c8bb
		my $handle = $resolver->bgsend(qw(net-dns.org SOA IN));
Packit e6c8bb
		last if $bgread = $resolver->bgread($handle);
Packit e6c8bb
	}
Packit e6c8bb
	ok( $bgread, '$resolver->bgsend/read	TCP + automatic TSIG' );
Packit e6c8bb
}
Packit e6c8bb
Packit e6c8bb
Packit e6c8bb
SKIP: {
Packit e6c8bb
	my $resolver = Net::DNS::Resolver->new( nameservers => $IP );
Packit e6c8bb
	$resolver->igntc(1);
Packit e6c8bb
Packit e6c8bb
	eval { $resolver->tsig( 'MD5.example', 'MD5keyMD5keyMD5keyMD5keyMD5=' ) };
Packit e6c8bb
	skip( 'failed TSIG tests', 3 ) if $@;
Packit e6c8bb
Packit e6c8bb
	my $udp = $resolver->send(qw(net-dns.org SOA IN));
Packit e6c8bb
	ok( !$udp, '$resolver->send(...)	UDP + failed TSIG' );
Packit e6c8bb
Packit e6c8bb
	$resolver->usevc(1);
Packit e6c8bb
Packit e6c8bb
	my $tcp = $resolver->send(qw(net-dns.org SOA IN));
Packit e6c8bb
	ok( !$tcp, '$resolver->send(...)	TCP + failed TSIG' );
Packit e6c8bb
Packit e6c8bb
	my $handle = $resolver->bgsend(qw(net-dns.org SOA IN));
Packit e6c8bb
	my $bgread = $resolver->bgread($handle);
Packit e6c8bb
	ok( !$bgread, '$resolver->bgsend/read	TCP + failed TSIG' );
Packit e6c8bb
}
Packit e6c8bb
Packit e6c8bb
Packit e6c8bb
{
Packit e6c8bb
	my $resolver = Net::DNS::Resolver->new();
Packit e6c8bb
	$resolver->retrans(0);
Packit e6c8bb
	$resolver->retry(0);
Packit e6c8bb
Packit e6c8bb
	my @query = ( undef, qw(SOA IN) );
Packit e6c8bb
	ok( $resolver->query(@query),  '$resolver->query( undef, ... ) defaults to "." ' );
Packit e6c8bb
	ok( $resolver->search(@query), '$resolver->search( undef, ... ) defaults to "." ' );
Packit e6c8bb
Packit e6c8bb
	$resolver->defnames(0);
Packit e6c8bb
	$resolver->dnsrch(0);
Packit e6c8bb
	ok( $resolver->search(@query), '$resolver->search() without dnsrch & defnames' );
Packit e6c8bb
}
Packit e6c8bb
Packit e6c8bb
Packit e6c8bb
{
Packit e6c8bb
	my $resolver = Net::DNS::Resolver->new();
Packit e6c8bb
	$resolver->searchlist('net');
Packit e6c8bb
Packit e6c8bb
	my @query = (qw(us SOA IN));
Packit e6c8bb
	ok( $resolver->query(@query),  '$resolver->query( name, ... )' );
Packit e6c8bb
	ok( $resolver->search(@query), '$resolver->search( name, ... )' );
Packit e6c8bb
Packit e6c8bb
	$resolver->defnames(0);
Packit e6c8bb
	$resolver->dnsrch(0);
Packit e6c8bb
	ok( $resolver->query(@query),  '$resolver->query() without defnames' );
Packit e6c8bb
	ok( $resolver->search(@query), '$resolver->search() without dnsrch' );
Packit e6c8bb
}
Packit e6c8bb
Packit e6c8bb
Packit e6c8bb
{
Packit e6c8bb
	my $resolver = Net::DNS::Resolver->new( nameservers => $IP );
Packit e6c8bb
Packit e6c8bb
	my $udp = $resolver->query(qw(bogus.net-dns.org A IN));
Packit e6c8bb
	ok( !$udp, '$resolver->query() nonexistent name	UDP' );
Packit e6c8bb
Packit e6c8bb
	$resolver->usevc(1);
Packit e6c8bb
Packit e6c8bb
	my $tcp = $resolver->query(qw(bogus.net-dns.org A IN));
Packit e6c8bb
	ok( !$tcp, '$resolver->query() nonexistent name	TCP' );
Packit e6c8bb
}
Packit e6c8bb
Packit e6c8bb
Packit e6c8bb
{
Packit e6c8bb
	my $resolver = Net::DNS::Resolver->new( nameservers => $IP );
Packit e6c8bb
	my $update = new Net::DNS::Update(qw(example.com));
Packit e6c8bb
	ok( $resolver->send($update), '$resolver->send($update) UDP' );
Packit e6c8bb
	$resolver->usevc(1);
Packit e6c8bb
	ok( $resolver->send($update), '$resolver->send($update) TCP' );
Packit e6c8bb
}
Packit e6c8bb
Packit e6c8bb
Packit e6c8bb
{
Packit e6c8bb
	my $resolver = Net::DNS::Resolver->new( nameservers => $NOIP );
Packit e6c8bb
	$resolver->retrans(0);
Packit e6c8bb
	$resolver->retry(0);
Packit e6c8bb
	$resolver->tcp_timeout(0);
Packit e6c8bb
Packit e6c8bb
	my @query = (qw(:: SOA IN));
Packit e6c8bb
	my $query = new Net::DNS::Packet(@query);
Packit e6c8bb
	ok( !$resolver->query(@query),	'$resolver->query() failure' );
Packit e6c8bb
	ok( !$resolver->search(@query), '$resolver->search() failure' );
Packit e6c8bb
Packit e6c8bb
	$query->edns->option( 65001, pack 'x500' );		# pad to force TCP
Packit e6c8bb
	ok( !$resolver->send($query),	'$resolver->send() failure' );
Packit e6c8bb
	ok( !$resolver->bgsend($query), '$resolver->bgsend() failure' );
Packit e6c8bb
}
Packit e6c8bb
Packit e6c8bb
Packit e6c8bb
{
Packit e6c8bb
	my $resolver = Net::DNS::Resolver->new( nameservers => $IP );
Packit e6c8bb
Packit e6c8bb
	my $mx = 'mx2.t.net-dns.org';
Packit e6c8bb
	my @rr = rr( $resolver, $mx, 'MX' );
Packit e6c8bb
Packit e6c8bb
	is( scalar(@rr), 2, 'Net::DNS::rr() works with specified resolver' );
Packit e6c8bb
	is( scalar rr( $resolver, $mx, 'MX' ), 2, 'Net::DNS::rr() works in scalar context' );
Packit e6c8bb
	is( scalar rr( $mx, 'MX' ), 2, 'Net::DNS::rr() works with default resolver' );
Packit e6c8bb
}
Packit e6c8bb
Packit e6c8bb
Packit e6c8bb
{
Packit e6c8bb
	my $resolver = Net::DNS::Resolver->new( nameservers => $IP );
Packit e6c8bb
Packit e6c8bb
	my $mx = 'mx2.t.net-dns.org';
Packit e6c8bb
	my @mx = mx( $resolver, $mx );
Packit e6c8bb
Packit e6c8bb
	is( scalar(@mx), 2, 'Net::DNS::mx() works with specified resolver' );
Packit e6c8bb
Packit e6c8bb
	# some people seem to use mx() in scalar context
Packit e6c8bb
	is( scalar mx( $resolver, $mx ), 2, 'Net::DNS::mx() works in scalar context' );
Packit e6c8bb
Packit e6c8bb
	is( scalar mx($mx), 2, 'Net::DNS::mx() works with default resolver' );
Packit e6c8bb
Packit e6c8bb
	is( scalar mx('bogus.t.net-dns.org'), 0, "Net::DNS::mx() works for bogus name" );
Packit e6c8bb
}
Packit e6c8bb
Packit e6c8bb
Packit e6c8bb
{
Packit e6c8bb
	my $resolver = Net::DNS::Resolver->new( nameservers => $IP );
Packit e6c8bb
	$resolver->tcp_timeout(10);
Packit e6c8bb
Packit e6c8bb
	my @zone = $resolver->axfr('net-dns.org');
Packit e6c8bb
	ok( scalar(@zone), '$resolver->axfr() returns entire zone in list context' );
Packit e6c8bb
Packit e6c8bb
	my @notauth = $resolver->axfr('bogus.net-dns.org');
Packit e6c8bb
	my $notauth = $resolver->errorstring;
Packit e6c8bb
	ok( !scalar(@notauth), "mismatched zone\t[$notauth]" );
Packit e6c8bb
Packit e6c8bb
	my $iterator = $resolver->axfr('net-dns.org');
Packit e6c8bb
	ok( ref($iterator), '$resolver->axfr() returns iterator in scalar context' );
Packit e6c8bb
Packit e6c8bb
	my $soa = eval { $iterator->() };
Packit e6c8bb
	is( ref($soa), 'Net::DNS::RR::SOA', '$iterator->() returns initial SOA RR' );
Packit e6c8bb
Packit e6c8bb
	my $i;
Packit e6c8bb
	eval {
Packit e6c8bb
		return unless $soa;
Packit e6c8bb
		$soa->serial(undef);				# force SOA mismatch
Packit e6c8bb
		while ( $iterator->() ) { $i++; }
Packit e6c8bb
	};
Packit e6c8bb
	my ($exception) = split /\n/, "$@\n";
Packit e6c8bb
	ok( $i, '$iterator->() iterates through remaining RRs' );
Packit e6c8bb
	ok( !eval { $iterator->() }, '$iterator->() returns undef after last RR' );
Packit e6c8bb
	ok( $exception, "iterator exception\t[$exception]" );
Packit e6c8bb
Packit e6c8bb
	my $axfr_start = $resolver->axfr_start('net-dns.org');
Packit e6c8bb
	ok( $axfr_start, '$resolver->axfr_start()	(historical)' );
Packit e6c8bb
	ok( eval { $resolver->axfr_next() }, '$resolver->axfr_next()	(historical)' );
Packit e6c8bb
	ok( $resolver->answerfrom(), '$resolver->answerfrom() works' );
Packit e6c8bb
Packit e6c8bb
	$resolver->srcport(-1);
Packit e6c8bb
	my @badsocket = $resolver->axfr();
Packit e6c8bb
	my $badsocket = $resolver->errorstring;
Packit e6c8bb
	ok( !scalar(@badsocket), "bad AXFR socket\t[$badsocket]" );
Packit e6c8bb
}
Packit e6c8bb
Packit e6c8bb
Packit e6c8bb
SKIP: {
Packit e6c8bb
	my $resolver = Net::DNS::Resolver->new( nameservers => $IP );
Packit e6c8bb
	$resolver->domain('net-dns.org');
Packit e6c8bb
	eval { $resolver->tsig( $resolver->query(qw(tsig-md5 KEY))->answer ) };
Packit e6c8bb
	skip( 'TSIG AXFR tests', 4 ) if $@;
Packit e6c8bb
	$resolver->tcp_timeout(10);
Packit e6c8bb
Packit e6c8bb
	my @zone = $resolver->axfr();
Packit e6c8bb
	ok( scalar(@zone), '$resolver->axfr() with TSIG verify' );
Packit e6c8bb
Packit e6c8bb
	my @notauth = $resolver->axfr('bogus.net-dns.org');
Packit e6c8bb
	my $notauth = $resolver->errorstring;
Packit e6c8bb
	ok( !scalar(@notauth), "mismatched zone\t[$notauth]" );
Packit e6c8bb
Packit e6c8bb
	eval { $resolver->tsig( 'MD5.example', 'MD5keyMD5keyMD5keyMD5keyMD5=' ) };
Packit e6c8bb
	my @unverifiable = $resolver->axfr();
Packit e6c8bb
	my $errorstring	 = $resolver->errorstring;
Packit e6c8bb
	ok( !scalar(@unverifiable), "mismatched key\t[$errorstring]" );
Packit e6c8bb
Packit e6c8bb
	eval { $resolver->tsig(undef) };
Packit e6c8bb
	my ($exception) = split /\n/, "$@\n";
Packit e6c8bb
	ok( $exception, "undefined TSIG\t[$exception]" );
Packit e6c8bb
}
Packit e6c8bb
Packit e6c8bb
Packit e6c8bb
SKIP: {
Packit e6c8bb
	my $resolver = Net::DNS::Resolver->new( nameservers => $NOIP );
Packit e6c8bb
	eval { $resolver->tsig( 'MD5.example', 'MD5keyMD5keyMD5keyMD5keyMD5=' ) };
Packit e6c8bb
	skip( 'TSIG AXFR tests', 2 ) if $@;
Packit e6c8bb
Packit e6c8bb
	my $query = new Net::DNS::Packet(qw(. SOA IN));
Packit e6c8bb
	ok( $resolver->bgsend($query), '$resolver->bgsend() + automatic TSIG' );
Packit e6c8bb
	ok( $resolver->bgsend($query), '$resolver->bgsend() + existing TSIG' );
Packit e6c8bb
}
Packit e6c8bb
Packit e6c8bb
Packit e6c8bb
{
Packit e6c8bb
	my $resolver = Net::DNS::Resolver->new();
Packit e6c8bb
	$resolver->nameservers();
Packit e6c8bb
	ok( !$resolver->send(qw(. NS)), 'no nameservers' );
Packit e6c8bb
}
Packit e6c8bb
Packit e6c8bb
Packit e6c8bb
{
Packit e6c8bb
	my $resolver = Net::DNS::Resolver->new();
Packit e6c8bb
	$resolver->nameserver('cname.t.net-dns.org');
Packit e6c8bb
	ok( scalar( $resolver->nameservers ), 'resolve nameserver cname' );
Packit e6c8bb
}
Packit e6c8bb
Packit e6c8bb
Packit e6c8bb
{
Packit e6c8bb
	my $resolver = Net::DNS::Resolver->new();
Packit e6c8bb
	my @warnings;
Packit e6c8bb
	local $SIG{__WARN__} = sub { push( @warnings, "@_" ); };
Packit e6c8bb
	my $ns = 'bogus.example.com.';
Packit e6c8bb
	my @ip = $resolver->nameserver($ns);
Packit e6c8bb
Packit e6c8bb
	my ($warning) = split /\n/, "@warnings\n";
Packit e6c8bb
	ok( $warning, "unresolved nameserver warning\t[$warning]" )
Packit e6c8bb
			|| diag "\tnon-existent '$ns' resolved: @ip";
Packit e6c8bb
}
Packit e6c8bb
Packit e6c8bb
Packit e6c8bb
{					## exercise exceptions in _axfr_next()
Packit e6c8bb
	my $resolver = Net::DNS::Resolver->new( nameservers => $IP );
Packit e6c8bb
	$resolver->domain('net-dns.org');
Packit e6c8bb
	eval { $resolver->tsig( $resolver->query(qw(tsig-md5 KEY))->answer ) };
Packit e6c8bb
	$resolver->tcp_timeout(10);
Packit e6c8bb
Packit e6c8bb
	{
Packit e6c8bb
		my $select = new IO::Select();
Packit e6c8bb
		eval { $resolver->_axfr_next($select); };
Packit e6c8bb
		my $exception = $1 if $@ =~ /^(.+)\n/;
Packit e6c8bb
		ok( $exception ||= '', "TCP time out\t[$exception]" );
Packit e6c8bb
	}
Packit e6c8bb
Packit e6c8bb
	{
Packit e6c8bb
		my $packet = $resolver->_make_query_packet(qw(net-dns.org SOA));
Packit e6c8bb
		my $socket = $resolver->_bgsend_tcp( $packet, $packet->data );
Packit e6c8bb
		my $select = new IO::Select($socket);
Packit e6c8bb
		while ( $resolver->bgbusy($socket) ) { sleep 1 }
Packit e6c8bb
		my $discarded = '';	## [size][id][status]	[qdcount]...
Packit e6c8bb
		$socket->recv( $discarded, 6 ) if $socket;
Packit e6c8bb
		eval { $resolver->_axfr_next($select); };
Packit e6c8bb
		my $exception = $1 if $@ =~ /^(.+)\n/;
Packit e6c8bb
		ok( $exception ||= '', "corrupt data\t[$exception]" );
Packit e6c8bb
	}
Packit e6c8bb
Packit e6c8bb
SKIP: {
Packit e6c8bb
		my $packet = $resolver->_make_query_packet(qw(net-dns.org SOA));
Packit e6c8bb
		my $socket = $resolver->_bgsend_tcp( $packet, $packet->data );
Packit e6c8bb
		my $tsigrr = $packet->sigrr;
Packit e6c8bb
		skip( 'verify fail', 1 ) unless $tsigrr;
Packit e6c8bb
Packit e6c8bb
		my $select = new IO::Select($socket);
Packit e6c8bb
		eval { $resolver->_axfr_next( $select, $tsigrr ); };
Packit e6c8bb
		my $exception = $1 if $@ =~ /^(.+)\n/;
Packit e6c8bb
		ok( $exception ||= '', "verify fail\t[$exception]" );
Packit e6c8bb
	}
Packit e6c8bb
}
Packit e6c8bb
Packit e6c8bb
Packit e6c8bb
{					## exercise error paths in _send_???() and bgbusy()
Packit e6c8bb
	my $resolver = Net::DNS::Resolver->new( nameservers => $IP, retry => 1 );
Packit e6c8bb
	my $packet = $resolver->_make_query_packet(qw(net-dns.org SOA));
Packit e6c8bb
Packit e6c8bb
	my $mismatch = $resolver->_make_query_packet(qw(net-dns.org SOA));
Packit e6c8bb
	ok( !$resolver->_send_tcp( $mismatch, $packet->data ), '_send_tcp()	id mismatch' );
Packit e6c8bb
	ok( !$resolver->_send_udp( $mismatch, $packet->data ), '_send_udp()	id mismatch' );
Packit e6c8bb
	my $handle = $resolver->_bgsend_udp( $mismatch, $packet->data );
Packit e6c8bb
	ok( !$resolver->bgread($handle), 'bgbusy()	id mismatch' );
Packit e6c8bb
}
Packit e6c8bb
Packit e6c8bb
Packit e6c8bb
{					## exercise error paths in _accept_reply()
Packit e6c8bb
	my $resolver = Net::DNS::Resolver->new( nameservers => $NOIP );
Packit e6c8bb
Packit e6c8bb
	my $query = new Net::DNS::Packet(qw(net-dns.org SOA IN));
Packit e6c8bb
	my $reply = new Net::DNS::Packet(qw(net-dns.org SOA IN));
Packit e6c8bb
	$reply->header->qr(1);
Packit e6c8bb
Packit e6c8bb
	ok( !$resolver->_accept_reply(undef), '_accept_reply()	corrupt reply' );
Packit e6c8bb
Packit e6c8bb
	ok( !$resolver->_accept_reply($query), '_accept_reply()	qr not set' );
Packit e6c8bb
Packit e6c8bb
	ok( !$resolver->_accept_reply( $reply, $query ), '_accept_reply()	id mismatch' );
Packit e6c8bb
}
Packit e6c8bb
Packit e6c8bb
Packit e6c8bb
{					## exercise error path in _read_tcp()
Packit e6c8bb
	my $resolver = Net::DNS::Resolver->new( nameservers => $IP );
Packit e6c8bb
	$resolver->tcp_timeout(10);
Packit e6c8bb
Packit e6c8bb
	my $packet = $resolver->_make_query_packet(qw(net-dns.org SOA));
Packit e6c8bb
	my $socket = $resolver->_bgsend_tcp( $packet, $packet->data );
Packit e6c8bb
	while ( $resolver->bgbusy($socket) ) { sleep 1 }
Packit e6c8bb
Packit e6c8bb
	my $size_buf = '';
Packit e6c8bb
	$socket->recv( $size_buf, 2 ) if $socket;
Packit e6c8bb
	my ($size) = unpack 'n*', $size_buf;
Packit e6c8bb
	my $discarded = '';		## data dependent: last 16 bits must not all be zero
Packit e6c8bb
	$socket->recv( $discarded, $size - 2 ) if $size;
Packit e6c8bb
Packit e6c8bb
	ok( !$resolver->_bgread($socket), '_read_tcp()	corrupt data' );
Packit e6c8bb
}
Packit e6c8bb
Packit e6c8bb
Packit e6c8bb
{					## exercise Net::DNS::Extlang query
Packit e6c8bb
	ok( Net::DNS::RR->new('. MD'), 'Net::DNS::Extlang query' );
Packit e6c8bb
}
Packit e6c8bb
Packit e6c8bb
Packit e6c8bb
NonFatalEnd();
Packit e6c8bb
Packit e6c8bb
exit;
Packit e6c8bb
Packit e6c8bb
__END__
Packit e6c8bb