bad interaction between SOAP:Lite and retry mechanism in Crypt-SSLeay
- Within the Crypt-SSLeay code there is a retry mechanism that gets triggered if there is a connection failure before the SSL handshake completes. By default, the SSLv23 compatibility mode is used first and when that fails, SSLv3 is tried, followed by SSLv2. The problem I have seen is that if the initial connection attempt gets a RST and the SSL module retries with V3, the code hangs forever or the connection is timed out and reset. The reason is that the SOAP request is never sent when the retry is done within Crypt-SSLeay. From my testing this appears to be a bad interaction between SOAP:Lite and Crypt-SSLeay, as other modules using Crypt-SSLeay don't run into this problem. If you have two machines handy, you can test this yourself:
Cheesy test program:
my $soap = SOAP::Lite->new( proxy => 'https://localhost/');
my $som = $soap->call('sayHello', SOAP::Data->name('name')->value('Foo'), SOAP::Data->name('givenName')->value('Bar'));
die $som->faultstring if ($som->fault);
print $som->result, "\n";
Run openssl on server:
% sudo /usr/bin/openssl
OpenSSL> s_server -accept 443 -no_ssl2 -no_tls1 -ssl3 -key key.pem -cert crt.pem -www
Using default temp DH parameters
The -no_ssl2 is used to try to trigger the failure of the initial connection attempt. It generates a FIN instead of a RST, but still works.
Now run the test script. If you trace this in tcpdump you will see the initial connection attempt which will get closed because the SSL ClientHello is version 2. The connection is re-established, an SSLv3 ClientHello is sent and the SSL handshake is completed. At this point things should just hang, since the SOAP request is never sent.