1#!/usr/bin/perl 2 3use strict; 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# Don't be locale-sensitive 18$! = Errno::ECONNREFUSED; 19my $ECONNREFUSED_STR = "$!"; 20 21{ 22 my $listensock = IO::Socket::IP->new( 23 Listen => 1, 24 Family => PF_INET6, 25 LocalPort => 0, 26 Type => SOCK_STREAM, 27 V6Only => 1, 28 ) or die "Cannot listen on PF_INET6 - $@"; 29 30 is( $listensock->getsockopt( IPPROTO_IPV6, IPV6_V6ONLY ), 1, 'IPV6_V6ONLY is 1 on $listensock' ); 31 32 my $testsock = IO::Socket::IP->new( 33 Family => PF_INET, 34 PeerHost => "127.0.0.1", 35 PeerPort => $listensock->sockport, 36 Type => SOCK_STREAM, 37 ); 38 my $err = "$@"; 39 40 ok( !defined $testsock, 'Unable to connect PF_INET socket to PF_INET6 socket with V6Only true' ); 41 like( $err, qr/\Q$ECONNREFUSED_STR/, 'Socket creation fails with connection refused' ); 42} 43 44SKIP: { 45 skip "This platform does not allow turning IPV6_V6ONLY off", 3 unless IO::Socket::IP->CAN_DISABLE_V6ONLY; 46 47 local $ENV{LANG} = "C"; # avoid locale-dependent error messages 48 49 my $listensock = IO::Socket::IP->new( 50 Listen => 1, 51 Family => PF_INET6, 52 LocalPort => 0, 53 Type => SOCK_STREAM, 54 V6Only => 0, 55 ) or die "Cannot listen on PF_INET6 - $@"; 56 57 is( $listensock->getsockopt( IPPROTO_IPV6, IPV6_V6ONLY ), 0, 'IPV6_V6ONLY is 0 on $listensock' ); 58 59 my $testsock = IO::Socket::IP->new( 60 Family => PF_INET, 61 PeerHost => "127.0.0.1", 62 PeerPort => $listensock->sockport, 63 Type => SOCK_STREAM, 64 ); 65 my $err = "$@"; 66 67 ok( defined $testsock, 'Connected PF_INET socket to PF_INET6 socket with V6Only false' ) or 68 diag( "IO::Socket::IP->new failed - $err" ); 69 is( $testsock->peerport, $listensock->sockport, 'Test socket connected to correct peer port' ); 70} 71 72done_testing; 73