use strict;
use IO::Socket::INET;
use IO::Socket::SSL;
if ( grep { $^O =~m{$_} } qw( MacOS VOS vmesa riscos amigaos ) ) {
print "1..0 # Skipped: fork not implemented on this platform\n";
exit
}
use vars qw( $SSL_SERVER_ADDR );
do "t/ssl_settings.req" || do "ssl_settings.req";
$|=1;
my @tests = qw( start stop start close );
print "1..16\n";
my $server = IO::Socket::INET->new(
LocalAddr => $SSL_SERVER_ADDR,
Listen => 2,
ReuseAddr => 1,
) || die "not ok #tcp listen failed: $!\n";
print "ok #listen\n";
my ($SSL_SERVER_PORT) = unpack_sockaddr_in( $server->sockname );
defined( my $pid = fork() ) || die $!;
$pid ? server():client();
wait;
exit(0);
sub client {
close($server);
my $client = IO::Socket::INET->new( "$SSL_SERVER_ADDR:$SSL_SERVER_PORT" ) or
die "not ok #client connect: $!\n";
$client->autoflush;
print "ok #client connect\n";
for my $test (@tests) {
alarm(15);
#print STDERR "begin test $test\n";
if ( $test eq 'start' ) {
print $client "start\n";
sleep(1); # avoid race condition, if client calls start but server is not yet available
#print STDERR ">>$$(client) start\n";
IO::Socket::SSL->start_SSL($client, SSL_verify_mode => 0 )
|| die "not ok #client::start_SSL: $SSL_ERROR\n";
#print STDERR "<<$$(client) start\n";
print "ok # client::start_SSL\n";
ref($client) eq "IO::Socket::SSL" or print "not ";
print "ok # client::class=".ref($client)."\n";
} elsif ( $test eq 'stop' ) {
print $client "stop\n";
$client->stop_SSL || die "not ok #client::stop_SSL\n";
print "ok # client::stop_SSL\n";
ref($client) eq "IO::Socket::INET" or print "not ";
print "ok # client::class=".ref($client)."\n";
} elsif ( $test eq 'close' ) {
print $client "close\n";
my $class = ref($client);
$client->close || die "not ok # client::close\n";
print "ok # client::close\n";
ref($client) eq $class or print "not ";
print "ok # client::class=".ref($client)."\n";
last;
}
#print STDERR "cont test $test\n";
defined( my $line = <$client> ) or return;
die "'$line'" if $line ne "OK\n";
}
}
sub server {
my $client = $server->accept || die $!;
$client->autoflush;
while (1) {
alarm(15);
defined( my $line = <$client> ) or last;
chomp($line);
if ( $line eq 'start' ) {
#print STDERR ">>$$ start\n";
IO::Socket::SSL->start_SSL( $client,
SSL_server => 1,
SSL_cert_file => "certs/client-cert.pem",
SSL_key_file => "certs/client-key.pem"
) || die "not ok #server::start_SSL: $SSL_ERROR\n";
#print STDERR "<<$$ start\n";
ref($client) eq "IO::Socket::SSL" or print "not ";
print "ok # server::class=".ref($client)."\n";
print $client "OK\n";
} elsif ( $line eq 'stop' ) {
$client->stop_SSL || die "not ok #server::stop_SSL\n";
print "ok #server::stop_SSL\n";
ref($client) eq "IO::Socket::INET" or print "not ";
print "ok # class=".ref($client)."\n";
print $client "OK\n";
} elsif ( $line eq 'close' ) {
my $class = ref($client);
$client->close || die "not ok #server::close\n";
print "ok #server::close\n";
ref($client) eq $class or print "not ";
print "ok # class=".ref($client)."\n";
last;
}
}
}