Blame t/05-OPT.t

Packit Service f6e53a
# $Id: 05-OPT.t 1543 2017-02-28 19:27:23Z willem $	-*-perl-*-
Packit Service f6e53a
Packit Service f6e53a
use strict;
Packit Service f6e53a
use Test::More;
Packit Service f6e53a
Packit Service f6e53a
use Net::DNS;
Packit Service f6e53a
use Net::DNS::Parameters;
Packit Service f6e53a
Packit Service f6e53a
my @opt = keys %Net::DNS::Parameters::ednsoptionbyval;
Packit Service f6e53a
Packit Service f6e53a
plan tests => 42 + scalar(@opt);
Packit Service f6e53a
Packit Service f6e53a
Packit Service f6e53a
my $name = '.';
Packit Service f6e53a
my $type = 'OPT';
Packit Service f6e53a
my $code = 41;
Packit Service f6e53a
my @attr = qw( size rcode flags );
Packit Service f6e53a
my @data = qw( 1280 0 32768 );
Packit Service f6e53a
my @also = qw( version );
Packit Service f6e53a
Packit Service f6e53a
my $wire = '0000290500000080000000';
Packit Service f6e53a
Packit Service f6e53a
Packit Service f6e53a
{
Packit Service f6e53a
	my $typecode = unpack 'xn', new Net::DNS::RR( name => '.', type => $type )->encode;
Packit Service f6e53a
	is( $typecode, $code, "$type RR type code = $code" );
Packit Service f6e53a
Packit Service f6e53a
	my $hash = {};
Packit Service f6e53a
	@{$hash}{@attr} = @data;
Packit Service f6e53a
Packit Service f6e53a
	my $rr = new Net::DNS::RR(
Packit Service f6e53a
		name => $name,
Packit Service f6e53a
		type => $type,
Packit Service f6e53a
		%$hash
Packit Service f6e53a
		);
Packit Service f6e53a
Packit Service f6e53a
	my $string = $rr->string;
Packit Service f6e53a
	like( $string, '/EDNS/', 'string method works' );
Packit Service f6e53a
Packit Service f6e53a
	foreach (@attr) {
Packit Service f6e53a
		is( $rr->$_, $hash->{$_}, "expected result from rr->$_()" );
Packit Service f6e53a
	}
Packit Service f6e53a
Packit Service f6e53a
	foreach (@also) {
Packit Service f6e53a
		my $value = $rr->$_;
Packit Service f6e53a
		ok( defined $rr->$_, "additional attribute rr->$_()" );
Packit Service f6e53a
	}
Packit Service f6e53a
Packit Service f6e53a
	my $encoded = $rr->encode;
Packit Service f6e53a
	my $decoded = decode Net::DNS::RR( \$encoded );
Packit Service f6e53a
	my $hex1    = uc unpack 'H*', $encoded;
Packit Service f6e53a
	my $hex2    = uc unpack 'H*', $decoded->encode;
Packit Service f6e53a
	is( $hex1, $hex2, 'encode/decode transparent' );
Packit Service f6e53a
	is( $hex1, $wire, 'encoded RDATA matches example' );
Packit Service f6e53a
}
Packit Service f6e53a
Packit Service f6e53a
Packit Service f6e53a
{
Packit Service f6e53a
	my $rr = new Net::DNS::RR( name => '.', type => $type );
Packit Service f6e53a
	foreach (@attr) {
Packit Service f6e53a
		my $initial = 0x5A5;
Packit Service f6e53a
		my $changed = 0xA5A;
Packit Service f6e53a
		$rr->{$_} = $initial;
Packit Service f6e53a
		is( $rr->$_($changed), $changed, "rr->$_(x) returns function argument" );
Packit Service f6e53a
		is( $rr->$_(),	       $changed, "rr->$_(x) changes attribute value" );
Packit Service f6e53a
	}
Packit Service f6e53a
}
Packit Service f6e53a
Packit Service f6e53a
Packit Service f6e53a
foreach my $method (qw(class ttl)) {
Packit Service f6e53a
	my $rr = new Net::DNS::RR( name => '.', type => $type );
Packit Service f6e53a
	eval {
Packit Service f6e53a
		local $SIG{__WARN__} = sub { die @_ };
Packit Service f6e53a
		$rr->$method(1);
Packit Service f6e53a
	};
Packit Service f6e53a
	my $exception = $1 if $@ =~ /^(.+)\n/;
Packit Service f6e53a
	ok( $exception ||= '', "$method method:\t[$exception]" );
Packit Service f6e53a
Packit Service f6e53a
	eval {
Packit Service f6e53a
		local $SIG{__WARN__} = sub { die @_ };
Packit Service f6e53a
		$rr->$method(0);
Packit Service f6e53a
	};
Packit Service f6e53a
	my $repeated = $1 if $@ =~ /^(.+)\n/;
Packit Service f6e53a
	ok( !$repeated, "$method exception not repeated $@" );
Packit Service f6e53a
}
Packit Service f6e53a
Packit Service f6e53a
Packit Service f6e53a
{
Packit Service f6e53a
	my $rr = new Net::DNS::RR( name => '.', type => $type, rcode => 16 );
Packit Service f6e53a
	$rr->{rdlength} = 0;					# inbound OPT RR only
Packit Service f6e53a
	like( $rr->string, '/BADVER/', 'opt->rcode(16)' );
Packit Service f6e53a
}
Packit Service f6e53a
Packit Service f6e53a
Packit Service f6e53a
{
Packit Service f6e53a
	my $rr = new Net::DNS::RR( name => '.', type => $type, rcode => 1 );
Packit Service f6e53a
	like( $rr->string, '/NOERROR/', 'opt->rcode(1)' );
Packit Service f6e53a
}
Packit Service f6e53a
Packit Service f6e53a
Packit Service f6e53a
{
Packit Service f6e53a
	my $edns = new Net::DNS::RR( name => '.', type => $type );
Packit Service f6e53a
Packit Service f6e53a
	ok( ref($edns), 'new OPT RR created' );
Packit Service f6e53a
Packit Service f6e53a
	is( scalar( $edns->options ), 0, 'EDNS option list initially empty' );
Packit Service f6e53a
Packit Service f6e53a
	ok( !$edns->_format_option(0), 'format non-existent option(0)' );
Packit Service f6e53a
Packit Service f6e53a
	my $non_existent = $edns->option(0);
Packit Service f6e53a
	is( $non_existent, undef, '$undef = option(0)' );
Packit Service f6e53a
Packit Service f6e53a
	my @non_existent = $edns->option(0);
Packit Service f6e53a
	is( scalar(@non_existent), 0, '@empty = option(0)' );
Packit Service f6e53a
Packit Service f6e53a
	ok( !$edns->_specified, 'state unmodified by existence probes' );
Packit Service f6e53a
Packit Service f6e53a
	$edns->option( 0 => '' );
Packit Service f6e53a
	is( scalar( $edns->options ), 1, 'insert EDNS option' );
Packit Service f6e53a
Packit Service f6e53a
	$edns->option( 0 => undef );
Packit Service f6e53a
	is( scalar( $edns->options ), 0, 'delete EDNS option' );
Packit Service f6e53a
Packit Service f6e53a
Packit Service f6e53a
	foreach my $option ( sort { $a <=> $b } keys %Net::DNS::Parameters::ednsoptionbyval ) {
Packit Service f6e53a
		$edns->option( $option => 'rawbytes' );
Packit Service f6e53a
	}
Packit Service f6e53a
Packit Service f6e53a
Packit Service f6e53a
	$edns->option( 4 => '' );
Packit Service f6e53a
	is( length( $edns->option(4) ), 0, "option 4 => ''" );
Packit Service f6e53a
Packit Service f6e53a
Packit Service f6e53a
	$edns->option( DAU => [1, 2, 3, 4] );
Packit Service f6e53a
	is( length( $edns->option(5) ), 4, 'option DAU => (1, 2, 3, 4)' );
Packit Service f6e53a
Packit Service f6e53a
Packit Service f6e53a
	$edns->option( 8 => ( pack 'H*', '000120007b7b7b7b' ) );
Packit Service f6e53a
	my %option8 = $edns->option(8);
Packit Service f6e53a
	$edns->option( 'CLIENT-SUBNET' => (%option8) );
Packit Service f6e53a
	is( length( $edns->option(8) ), 8, "option CLIENT-SUBNET => (%option8)" );
Packit Service f6e53a
	$edns->option( 'CLIENT-SUBNET' => {%option8, 'SOURCE-PREFIX-LENGTH' => 15} );
Packit Service f6e53a
	is( length( $edns->option(8) ), 6, "option CLIENT-SUBNET => {'SOURCE-PREFIX-LENGTH' => 15, ...}" );
Packit Service f6e53a
Packit Service f6e53a
Packit Service f6e53a
	my $timer = 604800;
Packit Service f6e53a
	my $option9 = $edns->option( EXPIRE => ( 'EXPIRE-TIMER' => $timer ) );
Packit Service f6e53a
	is( scalar( $edns->option(9) ), $option9, "option EXPIRE => ('EXPIRE-TIMER' => $timer)" );
Packit Service f6e53a
Packit Service f6e53a
Packit Service f6e53a
	my $client = $edns->option( COOKIE => ( 'CLIENT-COOKIE' => 'rawbytes' ) );
Packit Service f6e53a
	is( length( $edns->option(10) ), 8, "option COOKIE => ('CLIENT-COOKIE' => ... )" );
Packit Service f6e53a
Packit Service f6e53a
	my %option10 = $edns->option(10);
Packit Service f6e53a
	$edns->option( COOKIE => {%option10, 'SERVER-COOKIE' => 'cookedbytes'} );
Packit Service f6e53a
	is( length( $edns->option(10) ), 19, "option COOKIE => {'SERVER-COOKIE' => ... }" );
Packit Service f6e53a
Packit Service f6e53a
Packit Service f6e53a
	my $t = 200;
Packit Service f6e53a
	my $option11 = $edns->option( 'TCP-KEEPALIVE' => ( TIMEOUT => $t ) );
Packit Service f6e53a
	is( scalar( $edns->option(11) ), $option11, "option TCP-KEEPALIVE => (TIMEOUT => $t)" );
Packit Service f6e53a
Packit Service f6e53a
Packit Service f6e53a
	$edns->option( PADDING => ( 'OPTION-LENGTH' => 100 ) );
Packit Service f6e53a
	is( length( $edns->option(12) ), 100, "option PADDING => ('OPTION-LENGTH' => 100)" );
Packit Service f6e53a
Packit Service f6e53a
Packit Service f6e53a
	$edns->option( CHAIN => ( 'TRUST-POINT' => '' ) );
Packit Service f6e53a
	is( length( $edns->option(13) ), 0, "option CHAIN => ''" );
Packit Service f6e53a
Packit Service f6e53a
	my $option13 = $edns->option( CHAIN => ( 'TRUST-POINT' => 'com.' ) );
Packit Service f6e53a
	is( scalar( $edns->option(13) ), $option13, "option CHAIN => ('TRUST-POINT' => 'com.')" );
Packit Service f6e53a
Packit Service f6e53a
Packit Service f6e53a
	foreach my $option ( sort { $a <=> $b } keys %Net::DNS::Parameters::ednsoptionbyval ) {
Packit Service f6e53a
		my $content = $edns->option($option);		# check option interpretation
Packit Service f6e53a
Packit Service f6e53a
		my @interpretation = $edns->option($option);
Packit Service f6e53a
		$edns->option( $option => (@interpretation) );
Packit Service f6e53a
Packit Service f6e53a
		my $uninterpreted = $edns->option($option);
Packit Service f6e53a
		is( $uninterpreted, $content, "compose/decompose option $option" );
Packit Service f6e53a
	}
Packit Service f6e53a
Packit Service f6e53a
Packit Service f6e53a
	eval { $edns->option( 65001 => ( '', '' ) ) };
Packit Service f6e53a
	chomp $@;
Packit Service f6e53a
	ok( $@, "unable to compose option:\t[$@]" );
Packit Service f6e53a
Packit Service f6e53a
Packit Service f6e53a
	my $bogus = 'BOGUS-OPTION';
Packit Service f6e53a
	eval { ednsoptionbyname($bogus) };
Packit Service f6e53a
	chomp $@;
Packit Service f6e53a
	ok( $@, "ednsoptionbyname($bogus)\t[$@]" );
Packit Service f6e53a
Packit Service f6e53a
Packit Service f6e53a
	my $options = $edns->options;
Packit Service f6e53a
	my $encoded = $edns->encode;
Packit Service f6e53a
	my $decoded = decode Net::DNS::RR( \$encoded );
Packit Service f6e53a
	my @result  = $decoded->options;
Packit Service f6e53a
	is( scalar(@result), $options, 'expected number of options' );
Packit Service f6e53a
Packit Service f6e53a
	$edns->print;
Packit Service f6e53a
}
Packit Service f6e53a
Packit Service f6e53a
Packit Service f6e53a
exit;
Packit Service f6e53a