Skip Menu |

This queue is for tickets about the IO-Socket-SSL CPAN distribution.

Report information
The Basics
Id: 61466
Status: resolved
Priority: 0/
Queue: IO-Socket-SSL

People
Owner: Nobody in particular
Requestors: kraih [...] cpan.org
Cc:
AdminCc:

Bug Information
Severity: Critical
Broken in: 1.33
Fixed in: (no value)



Subject: fileno($socket) not working
Hi, fileno($socket) doesn't work after $socket->accept_SSL fails with an error (like a bad handshake). This in turn seems to break IO::Poll which only removes handles that return something else than undef on fileno($socket). $socket->fileno still works btw. but that doesn't help with the IO::Poll problem. In Mojolicious the whole issue results in leaking file descriptors, 100% cpu usage and crashing servers, a quick fix or workaround would be very much appreciated. Cheers, Sebastian
Subject: Re: [rt.cpan.org #61466] fileno($socket) not working
Date: Mon, 20 Sep 2010 07:38:41 +0200
To: Sebastian Riedel via RT <bug-IO-Socket-SSL [...] rt.cpan.org>
From: Steffen Ullrich <Steffen_Ullrich [...] genua.de>
Show quoted text
> > fileno($socket) doesn't work after $socket->accept_SSL fails with an error (like a bad > handshake). > This in turn seems to break IO::Poll which only removes handles that return something else than > undef on fileno($socket).
Please give an example program to reproduce the error, because in the following test program I cannot reproduce the error, e.g. both sock->fileno and fileno(sock) return the same valid value. Please make sure that the example program is as small as possible so that I can better verify that the problem is in IO::Socket::SSL and not some third party library or bad usage etc. ------- use strict; use warnings; use IO::Socket::SSL; # create Server on random port my $srv = IO::Socket::INET->new( LocalAddr => '0.0.0.0', Listen => 10 ) or die $!; my $saddr = $srv->sockhost.':'.$srv->sockport; # fork client defined(my $pid = fork()) or die $!; exit(client()) if $pid == 0; # wait for connect my $cl = $srv->accept; # try upgrade to SSL IO::Socket::SSL->start_SSL($cl, SSL_server => 1, SSL_verify_mode => 0x00, ) or warn $SSL_ERROR; warn 'fileno($cl)='.fileno($cl); warn '$cl->fileno='.$cl->fileno; # wait for client end wait; sub client { close($srv); # connect my $cl = IO::Socket::INET->new($saddr) or die $!; # just send stuff to let SSL handshake fail syswrite($cl,'x' x 1000) or die $!; # wait a bit before closing sleep(5); }
Show quoted text
> Please give an example program to reproduce the error, because in the > following test program I cannot reproduce the error, e.g. both sock-
> >fileno
> and fileno(sock) return the same valid value.
Ok, i suspect the bug is related to non-blocking use then. I'll try to make a small test case but i guess it won't be easy, non-blocking tests seem quite sparse. In our code i've identified the exact line after which fileno($socket) stops working. http://github.com/kraih/mojo/blob/master/lib/Mojo/IOLoop.pm#L1124
Just tried the test you posted before and it actually fails here for both fileno($socket) and $socket->fileno. SSL accept attempt failed with unknown errorerror:140760FC:SSL routines:SSL23_GET_CLIENT_HELLO:unknown protocol at sslbug.pl line 19. Use of uninitialized value in concatenation (.) or string at sslbug.pl line 26. fileno($cl)= at sslbug.pl line 26. Use of uninitialized value in concatenation (.) or string at sslbug.pl line 27. $cl->fileno= at sslbug.pl line 27. Only changes i've made were SSL_cert_file and SSL_key_file. (Using the bundled Mojo::IOLoop certificates) This is Mac OS X 10.6.4 with Perl 5.12.0 and the latest cpan versions of IO::Socket::SSL and Net::SSLeay.
Subject: Re: [rt.cpan.org #61466] fileno($socket) not working
Date: Mon, 20 Sep 2010 09:26:51 +0200
To: Sebastian Riedel via RT <bug-IO-Socket-SSL [...] rt.cpan.org>
From: Steffen Ullrich <Steffen_Ullrich [...] genua.de>
Show quoted text
> Ok, i suspect the bug is related to non-blocking use then. > I'll try to make a small test case but i guess it won't be easy, non-blocking tests seem quite > sparse.
If I change in my test program the verify_mode to 0x01 or 0x02 both fileno(sock) and sock->fileno will be undef. It might be the case in your code, that fileno is still cached in _SSL_fileno but not valid any more. The reason is, that a failed accept_SSL might call ssl_fatal_error which will call kill_socket to close the socket unless you have provided an SSL_error_trap handler. So I guess what you need to do in your code is to provide an SSL_error_trap handler which removes the failed socket from the IOLoop before closing the socket. Regards, Steffen
Show quoted text
> So I guess what you need to do in your code is to provide an > SSL_error_trap > handler which removes the failed socket from the IOLoop before closing > the socket.
Thanks, worked like a charm, no chance i would have found this by myself. Disappearing sockets seem a bit wonky, but at least it's fixable, so i'm happy now. :)
starting with version 1.34 the socket will not be closed after start_SSL failed, it will just be downgraded and then work like a non-ssl socket again. This will not change the behavior with SSL_error_trap, so your code should still work.