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