Skip Menu |

This queue is for tickets about the Crypt-SSLeay CPAN distribution.

Report information
The Basics
Id: 120481
Status: open
Priority: 0/
Queue: Crypt-SSLeay

People
Owner: nanis [...] runu.moc.invalid
Requestors: dyolcekaj [...] gmail.com
Cc:
AdminCc:

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



Subject: Possible Bug Report: Round Robin DNS
Date: Thu, 2 Mar 2017 16:32:26 -0600
To: bug-Crypt-SSLeay [...] rt.cpan.org
From: Jake Cloyd <dyolcekaj [...] gmail.com>
Hello, In the "connect()" subroutine of Net::SSL.pm when a connection can't be made the code currently croaks on line 114 else { *$self->{io_socket_peername}=@_ == 1 ? $_[0] : IO::Socket::sockaddr_in(@_); if(!$self->SUPER::connect(@_)) { # better to die than return here $@ = "Connect failed: $@; $!"; croak($@); } } When gethostbyname() returns multiple IP addresses and the first "connect()" attempt results in failure the croak will kill the iterating code. IO::Socket::INET.pm will iterate over gethostbyname()'s output and die in this scenario before attempting the second IP. We were seeing intermittent failures when one of the IPs a hostname would resolve to was unreachable. To fix this in our application connect() will return undef instead of croaking in a modified Net:SSL.pm file. else { *$self->{io_socket_peername}=@_ == 1 ? $_[0] : IO::Socket::sockaddr_in(@_); if(!$self->SUPER::connect(@_)) { $@ = "Connect failed: $@; $!"; return undef; #croak($@); } } Here is basically the code we were running. To reproduce you need to have a round robin DNS entry with one of the IPs being bogus and run something similar to the below. @LWP::Protocol::http::EXTRA_SOCK_OPTS = ( MultiHomed => 1, ); my $useragent = LWP::UserAgent->new; ## build request my $response = $useragent->request($request); Thanks, Jake Cloyd
Thank you for the clear and concise report. I have not yet decided how to handle this, but I do have a question: Are you sure you want to continue to rely on Crypt::SSLeay (and, by extension, Net::SSL)? Have you read <https://metacpan.org/pod/Crypt::SSLeay#DO-YOU-NEED-Crypt::SSLeay%3F>? If you have are using a recent version of LWP, you would have had to install LWP::Protocol::https to install Crypt::SSLeay which would have resulted in installing IO::Socket::SSL and Net::SSLeay which are much better maintained, and, more importantly, much more secure and not just because they verify hostnames. If in your code you are forcing the use of Crypt::SSLeay/Net::SSL using one of the techniques shown in the documentation linked above, could you try not doing it and seeing if your application suffers any ill effects? If not, there is no reason to force the use of Crypt::SSLeay and Net::SSL. HTH, -- Sinan On Thu Mar 02 17:32:36 2017, dyolcekaj@gmail.com wrote: Show quoted text
> Hello, > > In the "connect()" subroutine of Net::SSL.pm when a connection can't be > made the code currently croaks on line 114 > > else { > *$self->{io_socket_peername}=@_ == 1 ? $_[0] : > IO::Socket::sockaddr_in(@_); > if(!$self->SUPER::connect(@_)) { > # better to die than return here > $@ = "Connect failed: $@; $!"; > croak($@); > } > } > > When gethostbyname() returns multiple IP addresses and the first > "connect()" attempt results in failure the croak will kill the > iterating code. IO::Socket::INET.pm will iterate over > gethostbyname()'s output and die in this scenario before attempting > the second IP. We were seeing intermittent failures when one of the > IPs a hostname would resolve to was unreachable. > > To fix this in our application connect() will return undef instead of > croaking in a modified Net:SSL.pm file. > > else { > *$self->{io_socket_peername}=@_ == 1 ? $_[0] : > IO::Socket::sockaddr_in(@_); > if(!$self->SUPER::connect(@_)) { > $@ = "Connect failed: $@; $!"; > return undef; > #croak($@); > } > } > > > Here is basically the code we were running. To reproduce you need to > have a round robin DNS entry with one of the IPs being bogus and run > something similar to the below. > > @LWP::Protocol::http::EXTRA_SOCK_OPTS = ( > MultiHomed => 1, > ); > my $useragent = LWP::UserAgent->new; > ## build request > my $response = $useragent->request($request); > > > Thanks, > > Jake Cloyd