16fb12b70Safresh1#!/usr/bin/perl 26fb12b70Safresh1 3*3d61058aSafresh1use v5.14; 46fb12b70Safresh1use warnings; 56fb12b70Safresh1 66fb12b70Safresh1use Test::More; 76fb12b70Safresh1 86fb12b70Safresh1use Socket qw(PF_INET6 PF_INET IPPROTO_IPV6 IPV6_V6ONLY); 96fb12b70Safresh1use IO::Socket::IP; 106fb12b70Safresh1 116fb12b70Safresh1eval { IO::Socket::IP->new( LocalHost => "::1" ) } or 126fb12b70Safresh1 plan skip_all => "Unable to bind to ::1"; 136fb12b70Safresh1 146fb12b70Safresh1eval { defined IPV6_V6ONLY } or 156fb12b70Safresh1 plan skip_all => "IPV6_V6ONLY not available"; 166fb12b70Safresh1 17b8851fccSafresh1# https://rt.cpan.org/Ticket/Display.html?id=102662 18b8851fccSafresh1$^O eq "irix" and 19b8851fccSafresh1 plan skip_all => "$^O: IPV6_V6ONLY exists but getnameinfo() fails with EAI_NONAME"; 20b8851fccSafresh1 216fb12b70Safresh1# Don't be locale-sensitive 226fb12b70Safresh1$! = Errno::ECONNREFUSED; 236fb12b70Safresh1my $ECONNREFUSED_STR = "$!"; 246fb12b70Safresh1 256fb12b70Safresh1{ 266fb12b70Safresh1 my $listensock = IO::Socket::IP->new( 276fb12b70Safresh1 Listen => 1, 286fb12b70Safresh1 Family => PF_INET6, 296fb12b70Safresh1 LocalPort => 0, 306fb12b70Safresh1 Type => SOCK_STREAM, 316fb12b70Safresh1 V6Only => 1, 32b8851fccSafresh1 GetAddrInfoFlags => 0, # disable AI_ADDRCONFIG 33*3d61058aSafresh1 ) or die "Cannot listen on PF_INET6 - $IO::Socket::errstr"; 346fb12b70Safresh1 356fb12b70Safresh1 is( $listensock->getsockopt( IPPROTO_IPV6, IPV6_V6ONLY ), 1, 'IPV6_V6ONLY is 1 on $listensock' ); 366fb12b70Safresh1 376fb12b70Safresh1 my $testsock = IO::Socket::IP->new( 386fb12b70Safresh1 Family => PF_INET, 396fb12b70Safresh1 PeerHost => "127.0.0.1", 406fb12b70Safresh1 PeerPort => $listensock->sockport, 416fb12b70Safresh1 Type => SOCK_STREAM, 42b8851fccSafresh1 GetAddrInfoFlags => 0, # disable AI_ADDRCONFIG 436fb12b70Safresh1 ); 44*3d61058aSafresh1 my $err = "$IO::Socket::errstr"; 456fb12b70Safresh1 466fb12b70Safresh1 ok( !defined $testsock, 'Unable to connect PF_INET socket to PF_INET6 socket with V6Only true' ); 476fb12b70Safresh1 like( $err, qr/\Q$ECONNREFUSED_STR/, 'Socket creation fails with connection refused' ); 486fb12b70Safresh1} 496fb12b70Safresh1 506fb12b70Safresh1SKIP: { 516fb12b70Safresh1 skip "This platform does not allow turning IPV6_V6ONLY off", 3 unless IO::Socket::IP->CAN_DISABLE_V6ONLY; 526fb12b70Safresh1 536fb12b70Safresh1 local $ENV{LANG} = "C"; # avoid locale-dependent error messages 546fb12b70Safresh1 556fb12b70Safresh1 my $listensock = IO::Socket::IP->new( 566fb12b70Safresh1 Listen => 1, 576fb12b70Safresh1 Family => PF_INET6, 586fb12b70Safresh1 LocalPort => 0, 596fb12b70Safresh1 Type => SOCK_STREAM, 606fb12b70Safresh1 V6Only => 0, 61b8851fccSafresh1 GetAddrInfoFlags => 0, # disable AI_ADDRCONFIG 62*3d61058aSafresh1 ) or die "Cannot listen on PF_INET6 - $IO::Socket::errstr"; 636fb12b70Safresh1 646fb12b70Safresh1 is( $listensock->getsockopt( IPPROTO_IPV6, IPV6_V6ONLY ), 0, 'IPV6_V6ONLY is 0 on $listensock' ); 656fb12b70Safresh1 666fb12b70Safresh1 my $testsock = IO::Socket::IP->new( 676fb12b70Safresh1 Family => PF_INET, 686fb12b70Safresh1 PeerHost => "127.0.0.1", 696fb12b70Safresh1 PeerPort => $listensock->sockport, 706fb12b70Safresh1 Type => SOCK_STREAM, 71b8851fccSafresh1 GetAddrInfoFlags => 0, # disable AI_ADDRCONFIG 726fb12b70Safresh1 ); 73*3d61058aSafresh1 my $err = "$IO::Socket::errstr"; 746fb12b70Safresh1 756fb12b70Safresh1 ok( defined $testsock, 'Connected PF_INET socket to PF_INET6 socket with V6Only false' ) or 766fb12b70Safresh1 diag( "IO::Socket::IP->new failed - $err" ); 776fb12b70Safresh1 is( $testsock->peerport, $listensock->sockport, 'Test socket connected to correct peer port' ); 786fb12b70Safresh1} 796fb12b70Safresh1 806fb12b70Safresh1done_testing; 81