I have a PHP script that I use to send emails to my newsletter list in one of my sites.
The script uses STARTTLS for encrypted connections, using the following line to establish the SSL handshake:
stream_set_timeout($s, 35, 0);
if(false == stream_socket_enable_crypto($s, true, STREAM_CRYPTO_METHOD_TLS_CLIENT)){
$msg = "452 failed on tls connection";
} else {
$in_tls = true;
}
The socket $s is set to blocking and is already connected to the remote server after issuing a STARTTLS command and ready to start TLS handshake at this stage. As you can see, I am using stream_set_timeout before the handshake. According to the PHP docs it should abort the handshake after X seconds, but it doesn't seem to affect it.
Now this code works most of the time, but I sometimes run into servers where the TLS handshake would just block indefinitely, causing the script to hang.
I've tried looking into non-blocking solutions, but none of them worked for my PHP version (I use v5.1.6).
The only other option is to somehow monitor this line for timeout (I'm not sure if that's possible), or to somehow transfer the socket handle to another process I can run with a timeout control method.
Anyone knows how to solve this?
You could try to set a timeout on the stream, see php manual for stream_set_timeout($s)
When the stream times out, the 'timed_out' key of the array returned by stream_get_meta_data() is set to TRUE, although no error/warning is generated.
Also found this on PHP manual
In case anyone is puzzled, stream_set_timeout DOES NOT work for sockets created with socket_create or socket_accept. Use socket_set_option instead.
Instead of:
<?php
stream_set_timeout($socket,$sec,$usec);
?>
Use:
<?php
socket_set_option($socket, SOL_SOCKET, SO_RCVTIMEO, array('sec'=>$sec, 'usec'=>$usec));
socket_set_option($socket, SOL_SOCKET, SO_SNDTIMEO, array('sec'=>$sec, 'usec'=>$usec));
?>
Update: This allowed the OP to move past the issue
ini_set('default_socket_timeout', 1);