1#!/usr/bin/perl 2 3use v5.14; 4use warnings; 5 6use Test::More; 7 8use Socket qw(PF_INET6 PF_INET IPPROTO_IPV6 IPV6_V6ONLY); 9use IO::Socket::IP; 10 11eval { IO::Socket::IP->new( LocalHost => "::1" ) } or 12 plan skip_all => "Unable to bind to ::1"; 13 14eval { defined IPV6_V6ONLY } or 15 plan skip_all => "IPV6_V6ONLY not available"; 16 17# https://rt.cpan.org/Ticket/Display.html?id=102662 18$^O eq "irix" and 19 plan skip_all => "$^O: IPV6_V6ONLY exists but getnameinfo() fails with EAI_NONAME"; 20 21# Don't be locale-sensitive 22$! = Errno::ECONNREFUSED; 23my $ECONNREFUSED_STR = "$!"; 24 25{ 26 my $listensock = IO::Socket::IP->new( 27 Listen => 1, 28 Family => PF_INET6, 29 LocalPort => 0, 30 Type => SOCK_STREAM, 31 V6Only => 1, 32 GetAddrInfoFlags => 0, # disable AI_ADDRCONFIG 33 ) or die "Cannot listen on PF_INET6 - $IO::Socket::errstr"; 34 35 is( $listensock->getsockopt( IPPROTO_IPV6, IPV6_V6ONLY ), 1, 'IPV6_V6ONLY is 1 on $listensock' ); 36 37 my $testsock = IO::Socket::IP->new( 38 Family => PF_INET, 39 PeerHost => "127.0.0.1", 40 PeerPort => $listensock->sockport, 41 Type => SOCK_STREAM, 42 GetAddrInfoFlags => 0, # disable AI_ADDRCONFIG 43 ); 44 my $err = "$IO::Socket::errstr"; 45 46 ok( !defined $testsock, 'Unable to connect PF_INET socket to PF_INET6 socket with V6Only true' ); 47 like( $err, qr/\Q$ECONNREFUSED_STR/, 'Socket creation fails with connection refused' ); 48} 49 50SKIP: { 51 skip "This platform does not allow turning IPV6_V6ONLY off", 3 unless IO::Socket::IP->CAN_DISABLE_V6ONLY; 52 53 local $ENV{LANG} = "C"; # avoid locale-dependent error messages 54 55 my $listensock = IO::Socket::IP->new( 56 Listen => 1, 57 Family => PF_INET6, 58 LocalPort => 0, 59 Type => SOCK_STREAM, 60 V6Only => 0, 61 GetAddrInfoFlags => 0, # disable AI_ADDRCONFIG 62 ) or die "Cannot listen on PF_INET6 - $IO::Socket::errstr"; 63 64 is( $listensock->getsockopt( IPPROTO_IPV6, IPV6_V6ONLY ), 0, 'IPV6_V6ONLY is 0 on $listensock' ); 65 66 my $testsock = IO::Socket::IP->new( 67 Family => PF_INET, 68 PeerHost => "127.0.0.1", 69 PeerPort => $listensock->sockport, 70 Type => SOCK_STREAM, 71 GetAddrInfoFlags => 0, # disable AI_ADDRCONFIG 72 ); 73 my $err = "$IO::Socket::errstr"; 74 75 ok( defined $testsock, 'Connected PF_INET socket to PF_INET6 socket with V6Only false' ) or 76 diag( "IO::Socket::IP->new failed - $err" ); 77 is( $testsock->peerport, $listensock->sockport, 'Test socket connected to correct peer port' ); 78} 79 80done_testing; 81