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 ) || 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; } } }