albus123 has asked for the wisdom of the Perl Monks concerning the following question:
I have recently started using SSL with LWP and it works great! I am currently going through the code to get a basic understanding of where (and how) the SSL handshake happens. After enabling debugs in SSL.pm, I figured that connect_SSL() is the relevant function call and the SSL handshake seems to be 'complete' after the following code snippet:
for my $dummy (1) { #DEBUG( 'calling ssleay::connect' ); my $rv = Net::SSLeay::connect($ssl); $DEBUG>=3 && DEBUG("Net::SSLeay::connect -> $rv" ); if ( $rv < 0 ) { unless ( $self->_set_rw_error( $ssl,$rv )) { $self->error("SSL connect attempt failed with unknown +error"); delete ${*$self}{'_SSL_opening'}; ${*$self}{'_SSL_opened'} = -1; $DEBUG>=1 && DEBUG( "fatal SSL error: $SSL_ERROR" ); return $self->fatal_ssl_error(); } $DEBUG>=2 && DEBUG('ssl handshake in progress' ); # connect failed because handshake needs to be completed # if socket was non-blocking or no timeout was given retur +n with this error return if ! defined($timeout); # wait until socket is readable or writable my $rv; if ( $timeout>0 ) { my $vec = ''; vec($vec,$self->fileno,1) = 1; $DEBUG>=2 && DEBUG( "waiting for fd to become ready: $ +SSL_ERROR" ); $rv = $SSL_ERROR == SSL_WANT_READ ? select( $vec,undef,u +ndef,$timeout) : $SSL_ERROR == SSL_WANT_WRITE ? select( undef,$vec, +undef,$timeout) : undef; } else { $DEBUG>=2 && DEBUG("handshake failed because no more t +ime" ); $! = ETIMEDOUT } if ( ! $rv ) { $DEBUG>=2 && DEBUG("handshake failed because socket di +d not became ready" ); # failed because of timeout, return $! ||= ETIMEDOUT; delete ${*$self}{'_SSL_opening'}; ${*$self}{'_SSL_opened'} = -1; $self->blocking(1); # was blocking before return } # socket is ready, try non-blocking connect again after re +computing timeout $DEBUG>=2 && DEBUG("socket ready, retrying connect" ); my $now = time(); $timeout -= $now - $start; $start = $now; redo; } elsif ( $rv == 0 ) { delete ${*$self}{'_SSL_opening'}; $DEBUG>=2 && DEBUG("connection failed - connect returned 0 +" ); $self->error("SSL connect attempt failed because of handsh +ake problems" ); ${*$self}{'_SSL_opened'} = -1; return $self->fatal_ssl_error(); } }
I can see the cipher list being set before this 'for' loop. But I do not understand the code in this loop. Why does SSLeay::connect() fail and why is a READ performed on the socket? From debugs, I could see that this loop is executing more than once. After the READ is successful, there is a comment 'socket is ready, try non-blocking connect again after recomputing timeout'. Does this mean that there is some data on the socket (client/server cipher list?) and will be 'processed'? This example here http://search.cpan.org/~sampo/Net_SSLeay.pm-1.25/SSLeay.pm calls this function only once, which doesn't clarify things. Can someone please help me understand this.
IO::Socket::SSL version: 1.84
Net::SSLeay version: 1.21
Thanks & Regards,
|
|---|
| Replies are listed 'Best First'. | |
|---|---|
|
Re: Query regarding connect_SSL (IO::Socket::SSL.pm)
by Athanasius (Archbishop) on Aug 08, 2015 at 09:46 UTC | |
by albus123 (Novice) on Aug 17, 2015 at 22:21 UTC |