|
Packit |
8bbd3c |
#!/usr/bin/perl
|
|
Packit |
8bbd3c |
|
|
Packit |
8bbd3c |
use strict;
|
|
Packit |
8bbd3c |
use warnings;
|
|
Packit |
8bbd3c |
|
|
Packit |
8bbd3c |
use Test::More;
|
|
Packit |
8bbd3c |
|
|
Packit |
8bbd3c |
use Socket qw(PF_INET6 PF_INET IPPROTO_IPV6 IPV6_V6ONLY);
|
|
Packit |
8bbd3c |
use IO::Socket::IP;
|
|
Packit |
8bbd3c |
|
|
Packit |
8bbd3c |
eval { IO::Socket::IP->new( LocalHost => "::1" ) } or
|
|
Packit |
8bbd3c |
plan skip_all => "Unable to bind to ::1";
|
|
Packit |
8bbd3c |
|
|
Packit |
8bbd3c |
eval { defined IPV6_V6ONLY } or
|
|
Packit |
8bbd3c |
plan skip_all => "IPV6_V6ONLY not available";
|
|
Packit |
8bbd3c |
|
|
Packit |
8bbd3c |
# https://rt.cpan.org/Ticket/Display.html?id=102662
|
|
Packit |
8bbd3c |
$^O eq "irix" and
|
|
Packit |
8bbd3c |
plan skip_all => "$^O: IPV6_V6ONLY exists but getnameinfo() fails with EAI_NONAME";
|
|
Packit |
8bbd3c |
|
|
Packit |
8bbd3c |
# Don't be locale-sensitive
|
|
Packit |
8bbd3c |
$! = Errno::ECONNREFUSED;
|
|
Packit |
8bbd3c |
my $ECONNREFUSED_STR = "$!";
|
|
Packit |
8bbd3c |
|
|
Packit |
8bbd3c |
{
|
|
Packit |
8bbd3c |
my $listensock = IO::Socket::IP->new(
|
|
Packit |
8bbd3c |
Listen => 1,
|
|
Packit |
8bbd3c |
Family => PF_INET6,
|
|
Packit |
8bbd3c |
LocalPort => 0,
|
|
Packit |
8bbd3c |
Type => SOCK_STREAM,
|
|
Packit |
8bbd3c |
V6Only => 1,
|
|
Packit |
8bbd3c |
GetAddrInfoFlags => 0, # disable AI_ADDRCONFIG
|
|
Packit |
8bbd3c |
) or die "Cannot listen on PF_INET6 - $@";
|
|
Packit |
8bbd3c |
|
|
Packit |
8bbd3c |
is( $listensock->getsockopt( IPPROTO_IPV6, IPV6_V6ONLY ), 1, 'IPV6_V6ONLY is 1 on $listensock' );
|
|
Packit |
8bbd3c |
|
|
Packit |
8bbd3c |
my $testsock = IO::Socket::IP->new(
|
|
Packit |
8bbd3c |
Family => PF_INET,
|
|
Packit |
8bbd3c |
PeerHost => "127.0.0.1",
|
|
Packit |
8bbd3c |
PeerPort => $listensock->sockport,
|
|
Packit |
8bbd3c |
Type => SOCK_STREAM,
|
|
Packit |
8bbd3c |
GetAddrInfoFlags => 0, # disable AI_ADDRCONFIG
|
|
Packit |
8bbd3c |
);
|
|
Packit |
8bbd3c |
my $err = "$@";
|
|
Packit |
8bbd3c |
|
|
Packit |
8bbd3c |
ok( !defined $testsock, 'Unable to connect PF_INET socket to PF_INET6 socket with V6Only true' );
|
|
Packit |
8bbd3c |
like( $err, qr/\Q$ECONNREFUSED_STR/, 'Socket creation fails with connection refused' );
|
|
Packit |
8bbd3c |
}
|
|
Packit |
8bbd3c |
|
|
Packit |
8bbd3c |
SKIP: {
|
|
Packit |
8bbd3c |
skip "This platform does not allow turning IPV6_V6ONLY off", 3 unless IO::Socket::IP->CAN_DISABLE_V6ONLY;
|
|
Packit |
8bbd3c |
|
|
Packit |
8bbd3c |
local $ENV{LANG} = "C"; # avoid locale-dependent error messages
|
|
Packit |
8bbd3c |
|
|
Packit |
8bbd3c |
my $listensock = IO::Socket::IP->new(
|
|
Packit |
8bbd3c |
Listen => 1,
|
|
Packit |
8bbd3c |
Family => PF_INET6,
|
|
Packit |
8bbd3c |
LocalPort => 0,
|
|
Packit |
8bbd3c |
Type => SOCK_STREAM,
|
|
Packit |
8bbd3c |
V6Only => 0,
|
|
Packit |
8bbd3c |
GetAddrInfoFlags => 0, # disable AI_ADDRCONFIG
|
|
Packit |
8bbd3c |
) or die "Cannot listen on PF_INET6 - $@";
|
|
Packit |
8bbd3c |
|
|
Packit |
8bbd3c |
is( $listensock->getsockopt( IPPROTO_IPV6, IPV6_V6ONLY ), 0, 'IPV6_V6ONLY is 0 on $listensock' );
|
|
Packit |
8bbd3c |
|
|
Packit |
8bbd3c |
my $testsock = IO::Socket::IP->new(
|
|
Packit |
8bbd3c |
Family => PF_INET,
|
|
Packit |
8bbd3c |
PeerHost => "127.0.0.1",
|
|
Packit |
8bbd3c |
PeerPort => $listensock->sockport,
|
|
Packit |
8bbd3c |
Type => SOCK_STREAM,
|
|
Packit |
8bbd3c |
GetAddrInfoFlags => 0, # disable AI_ADDRCONFIG
|
|
Packit |
8bbd3c |
);
|
|
Packit |
8bbd3c |
my $err = "$@";
|
|
Packit |
8bbd3c |
|
|
Packit |
8bbd3c |
ok( defined $testsock, 'Connected PF_INET socket to PF_INET6 socket with V6Only false' ) or
|
|
Packit |
8bbd3c |
diag( "IO::Socket::IP->new failed - $err" );
|
|
Packit |
8bbd3c |
is( $testsock->peerport, $listensock->sockport, 'Test socket connected to correct peer port' );
|
|
Packit |
8bbd3c |
}
|
|
Packit |
8bbd3c |
|
|
Packit |
8bbd3c |
done_testing;
|