Thread

Posted on Sun May 8 22:39:19 2005 by martinw
accept() blocks until ssl session is started
Hi *,

I want to write a little Perl SSL deamon with IO::Socket::SSL. There I found a (in my opinion) strange behavior. Look at the following example code:
my $port = shift || 8080; my $socket = IO::Socket::SSL-> new( LocalPort => $port, Listen => 10, Reuse => 1, SSL_key_file => '/home/martin/test.key', SSL_cert_file => '/home/martin/test.crt', SSL_use_cert => 1, SSL_server => 1, SSL_cipher_list => 'ALL', ) or die "Cannot open socket: $!"; while (my $c = $socket->accept) { print "ACCEPT\n"; my $pid = fork(); defined $pid || die "Cannot fork: $!"; next if $pid; print "Client.\n"; print $c "Hello, client."; $c->close(); # child exits exit(0); } close $socket;
If I connect to the daemon with "openssl s_client" everything works as expected. The fork(2) is done and the response is written. But if I connect to the port without an SSL client like netcat, the daemon blocks at the accept line. A second request can connect, but it is blocked.
I dived into IO::Socket::SSL and see, the daemon blocks at line 176 (in version 0.96) at this sequence at the accept_SSL subroutine:
sub accept_SSL { ... 176 -> while (Net::SSLeay::accept($ssl)<1) { $socket->error("SSL accept attempt failed"); if ($socket->errstr =~ /SSL wants a (write|read) first!/) {
My question is, if this is a bug in IO::Socket::SSL or openssl (Version 0.9.7e from Debian Sarge) or is this my misunderstanding in the use of IO::Socket::SSL or, respectly (Open)SSL.

Best regards, martin!
Direct Responses: 445 | Write a response
Posted on Wed May 11 10:21:03 2005 by martinw in response to 433
Re: accept() blocks until ssl session is started
Hi *, Peter Behroozi gave me the tip to solve the problem (Thanks, Peter!).
The inital Socket must be opened as an INET socket like:
my $socket = IO::Socket::INET->new( LocalPort => $port, Listen => 10, Reuse => 1 ) or die "Cannot open socket: $!";
The SSL session than starts after the fork command:
while (my $c = $socket->accept) { print "ACCEPT\n"; my $pid = fork(); defined $pid || die "Cannot fork: $!"; next if $pid; IO::Socket::SSL->start_SSL($c, SSL_key_file => '/home/martin/test.key', SSL_cert_file => '/home/martin/test.crt', SSL_use_cert => 1, SSL_server => 1, SSL_cipher_list => 'ALL', ); ...
Now, the daemon will not block after a connect from client without doing the SSL handshake. Regards,
martin!
Write a response