I've implemented a small webserver in Perl. It is listening with IO::Socket::INET and IO::Socket::SSL parallel.
If a connect appears at the HTTP-port I start a thread and handle the IO::Socket::INET reference.
Because of thread-limitations in Net::SSLeay (IO::Socket::SSL says in the doc is is not thread-safe below 1.43) I did NOT parallelize the SSL. I just call the handler-function in the same context. In the parallelized case of HTTP the handler-function is the threads function.
All this is working as expected for a longer time.
I have now updated my system. Now my Net::SSLeay is 1.72 and I tried to paralellize the SSL too - the same way I do with the HTTP. But I get a segmentation fault at the first time I do a read.
use strict;
use warnings;
use IO::Handle;
use Fcntl ("F_GETFL", "F_SETFL", "O_NONBLOCK");
use Time::HiRes ("usleep");
use Socket;
use IO::Socket::SSL;
use threads;
STDOUT->autoflush ();
my $port = "4433";
my $cer = "cer.cer";
my $key = "key.key";
my $sock = IO::Socket::SSL->new (Listen => SOMAXCONN, LocalPort => $port,
Blocking => 0, Timeout => 0, ReuseAddr => 1, SSL_server => 1,
SSL_cert_file => $cer, SSL_key_file => $key) or die $@;
my $WITH_THREADS = 0; # the switch!!
for (;;)
{
eval
{
my $cl = $sock->accept ();
if ($cl)
{
print ("\nssl connect");
if ($WITH_THREADS == 0)
{
# this is no multi-threading
client ($cl);
}
else {
# with multithreading
my $th = threads->create (\&client, $cl);
$th->detach ();
}
}
}; # eval
if ($@)
{
print "ex: $@";
exit (1);
}
usleep (100000);
} # forever
sub client # worker
{
my $cl = shift;
# unblock
my $flags = fcntl ($cl, F_GETFL, 0) or die $!;
fcntl ($cl, F_SETFL, $flags | O_NONBLOCK) or die $!;
print "\n" . $cl->peerhost . "/" . $cl->peerport;
my $ret = "";
for (my $i = 0; $i < 100; $i ++)
{
$ret = $cl->read (my $recv, 5000);
# faults here if with threads!
if (defined ($ret) && length ($recv) > 0)
{
print "\nreceived $ret bytes";
}
else
{
print "\nno data";
}
usleep (200000);
}
print "\nend client";
$cl->close ();
}
I have also read some posts where they said IO::Socket::SSL is not threadsafe but I am not sure that is still the case.
Does anyone know if it is possible that way? Or maybe it is possible but I am handling it the wrong way...
Thanks, Chris
EDIT: I use Debian 8.3 with Perl 5.20.2. Net::SSLeay is 1.72, IO::Socket::SSL is 2.024. OpenSSL 1.0.1k
EDIT: Changed the code-sample to fully functional little sample-program.