=== modified file 'MANIFEST'
--- MANIFEST 2012-06-01 15:10:07 +0000
+++ MANIFEST 2012-06-01 15:44:23 +0000
@@ -31,6 +31,7 @@
t/core.t
t/dhe.t
t/inet6.t
+t/io-socket-ip.t
t/memleak_bad_handshake.t
t/nonblock.t
t/npn.t
=== modified file 'Makefile.PL'
--- Makefile.PL 2012-06-01 15:10:07 +0000
+++ Makefile.PL 2012-06-01 15:14:02 +0000
@@ -90,6 +90,10 @@
'ABSTRACT' => 'Nearly transparent SSL encapsulation for IO::Socket::INET.',
'VERSION_FROM' => 'SSL.pm',
'DISTNAME' => 'IO-Socket-SSL',
- 'PREREQ_PM' => { 'Net::SSLeay' => 1.21, 'Scalar::Util' => 0 },
+ 'PREREQ_PM' => {
+ 'Net::SSLeay' => 1.21,
+ 'Scalar::Util' => 0,
+ 'Socket' => 1.95,
+ },
'dist' => { COMPRESS => 'gzip', SUFFIX => 'gz', },
);
=== modified file 'SSL.pm'
--- SSL.pm 2012-06-01 15:10:07 +0000
+++ SSL.pm 2012-06-01 15:54:56 +0000
@@ -18,6 +18,7 @@
use Net::SSLeay 1.21;
use Exporter ();
use Errno qw( EAGAIN ETIMEDOUT );
+use Socket 1.95 qw( inet_pton );
use Carp;
use strict;
@@ -61,23 +62,28 @@
}
my @caller_force_inet4; # in case inet4 gets forced we store here who forced it
-my $can_ipv6; # true if we successfully enabled ipv6 while loading
BEGIN {
# Declare @ISA, $VERSION, $GLOBAL_CONTEXT_ARGS
+ # if we have IO::Socket::IP >= 0.11 we will use this in preference
+ # because it can handle both IPv4 and IPv6
+ if ( eval { require IO::Socket::IP; IO::Socket::IP->VERSION(0.11); } ) {
+ @ISA = qw(IO::Socket::IP);
+ constant->import( CAN_IPV6 => "IO::Socket::IP" );
+ }
# if we have IO::Socket::INET6 we will use this not IO::Socket::INET, because
# it can handle both IPv4 and IPv6. If we don't have INET6 available fall back
# to INET
- if ( ! eval {
- require Socket6;
- Socket6->import( 'inet_pton' );
- require IO::Socket::INET6;
+ elsif( eval { require IO::Socket::INET6; } ) {
@ISA = qw(IO::Socket::INET6);
- $can_ipv6 = 1;
- }) {
+ constant->import( CAN_IPV6 => "IO::Socket::INET6" );
+ }
+ else {
@ISA = qw(IO::Socket::INET);
+ constant->import( CAN_IPV6 => '' );
}
+
$VERSION = '1.74';
$GLOBAL_CONTEXT_ARGS = {};
@@ -151,11 +157,11 @@
# either we don't support it or we disabled it by explicitly
# loading it with 'inet4'. In this case re-enable but warn
# because this is probably an error
- if ( $can_ipv6 ) {
- @ISA = 'IO::Socket::INET6';
+ if ( CAN_IPV6 ) {
+ @ISA = ( CAN_IPV6 );
warn "IPv6 support re-enabled in __PACKAGE__, got disabled in file $caller_force_inet4[1] line $caller_force_inet4[2]";
} else {
- die "INET6 is not supported, missing Socket6 or IO::Socket::INET6";
+ die "INET6 is not supported, install IO::Socket::INET6";
}
}
} elsif ( /^:?debug(\d+)/ ) {
@@ -185,7 +191,7 @@
# work around Bug in IO::Socket::INET6 where it doesn't use the
# right family for the socket on BSD systems:
#
http://rt.cpan.org/Ticket/Display.html?id=39550
- if ( $can_ipv6 && ! $arg_hash->{Domain} &&
+ if ( CAN_IPV6 eq "IO::Socket::INET6" && ! $arg_hash->{Domain} &&
! ( $arg_hash->{LocalAddr} || $arg_hash->{LocalHost} ) &&
(my $peer = $arg_hash->{PeerAddr} || $arg_hash->{PeerHost})) {
# set Domain to AF_INET/AF_INET6 if there is only one choice
@@ -1187,9 +1193,6 @@
my $ipn;
if ( $identity =~m{:} ) {
# no IPv4 or hostname have ':' in it, try IPv6.
- # make sure that Socket6 was loaded properly
- UNIVERSAL::can( __PACKAGE__, 'inet_pton' ) or croak
- q[Looks like IPv6 address, make sure that Socket6 is loaded or make "use IO::Socket::SSL 'inet6'];
$ipn = inet_pton(AF_INET6,$identity)
or croak "'$identity' is not IPv6, but neither IPv4 nor hostname";
} elsif ( $identity =~m{^\d+\.\d+\.\d+\.\d+$} ) {
=== modified file 't/inet6.t'
--- t/inet6.t 2012-06-01 15:10:07 +0000
+++ t/inet6.t 2012-06-01 16:00:08 +0000
@@ -13,9 +13,16 @@
exit
}
+# check first if we have loaded IO::Socket::IP, as if so we won't need or use
+# IO::Socket::INET6
+if( IO::Socket::SSL->CAN_IPV6 eq "IO::Socket::IP" ) {
+ print "1..0 # Skipped: using IO::Socket::IP instead\n";
+ exit;
+}
+
# check if we have loaded INET6, IO::Socket::SSL should do it by itself
# if it is available
-if ( ! $INC{ 'IO/Socket/INET6.pm' } ) {
+unless( IO::Socket::SSL->CAN_IPV6 eq "IO::Socket::INET6" ) {
# not available or IO::Socket::SSL forgot to load it
if ( ! eval { require IO::Socket::INET6 } ) {
print "1..0 # Skipped: no IO::Socket::INET6 available\n";
=== added file 't/io-socket-ip.t'
--- t/io-socket-ip.t 1970-01-01 00:00:00 +0000
+++ t/io-socket-ip.t 2012-06-01 15:57:20 +0000
@@ -0,0 +1,84 @@
+#!perl -w
+# Before `make install' is performed this script should be runnable with
+# `make test'. After `make install' it should work as `perl t/dhe.t'
+
+use Net::SSLeay;
+use Socket;
+use IO::Socket::SSL;
+use strict;
+
+
+if ( grep { $^O =~m{$_} } qw( MacOS VOS vmesa riscos amigaos ) ) {
+ print "1..0 # Skipped: fork not implemented on this platform\n";
+ exit
+}
+
+# check if we have loaded IO::Socket::IP, IO::Socket::SSL should do it by
+# itself if it is available
+unless( IO::Socket::SSL->CAN_IPV6 eq "IO::Socket::IP" ) {
+ # not available or IO::Socket::SSL forgot to load it
+ if ( ! eval { require IO::Socket::IP; IO::Socket::IP->VERSION(0.11) } ) {
+ print "1..0 # Skipped: no IO::Socket::IP 0.11 available\n";
+ } else {
+ print "1..1\nnot ok # automatic use of IO::Socket::IP\n";
+ }
+ exit
+}
+
+my $addr = '::1';
+# check if we can use ::1, e.g if the computer has IPv6 enabled
+if ( ! IO::Socket::IP->new(
+ Listen => 10,
+ LocalAddr => $addr,
+)) {
+ print "1..0 # no IPv6 enabled on this computer\n";
+ exit
+}
+
+$|=1;
+print "1..3\n";
+
+# first create simple ssl-server
+my $ID = 'server';
+my $server = IO::Socket::SSL->new(
+ LocalAddr => $addr,
+ Listen => 2,
+ SSL_cert_file => "certs/server-cert.pem",
+ SSL_key_file => "certs/server-key.pem",
+) || do {
+ notok($!);
+ exit
+};
+ok("Server Initialization at $addr");
+
+# add server port to addr
+$addr = "[$addr]:".$server->sockport;
+print "# server at $addr\n";
+
+my $pid = fork();
+if ( !defined $pid ) {
+ die $!; # fork failed
+
+} elsif ( !$pid ) { ###### Client
+
+ $ID = 'client';
+ close($server);
+ my $to_server = IO::Socket::SSL->new( $addr ) || do {
+ notok( "connect failed: ".IO::Socket::SSL->errstr() );
+ exit
+ };
+ ok( "client connected" );
+
+} else { ###### Server
+
+ my $to_client = $server->accept || do {
+ notok( "accept failed: ".$server->errstr() );
+ kill(9,$pid);
+ exit;
+ };
+ ok( "Server accepted" );
+ wait;
+}
+
+sub ok { print "ok # [$ID] @_\n"; }
+sub notok { print "not ok # [$ID] @_\n"; }