mirror of
https://github.com/php/php-src.git
synced 2025-08-16 05:58:45 +02:00
Bug #41631: Observe socket read timeouts in SSL streams
This commit is contained in:
parent
7189039d65
commit
6569db8808
1 changed files with 46 additions and 0 deletions
|
@ -204,13 +204,59 @@ static size_t php_openssl_sockop_write(php_stream *stream, const char *buf, size
|
||||||
return didwrite;
|
return didwrite;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void php_openssl_stream_wait_for_data(php_netstream_data_t *sock TSRMLS_DC)
|
||||||
|
{
|
||||||
|
int retval;
|
||||||
|
struct timeval *ptimeout;
|
||||||
|
|
||||||
|
if (sock->socket == -1) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
sock->timeout_event = 0;
|
||||||
|
|
||||||
|
if (sock->timeout.tv_sec == -1)
|
||||||
|
ptimeout = NULL;
|
||||||
|
else
|
||||||
|
ptimeout = &sock->timeout;
|
||||||
|
|
||||||
|
while(1) {
|
||||||
|
retval = php_pollfd_for(sock->socket, PHP_POLLREADABLE, ptimeout);
|
||||||
|
|
||||||
|
if (retval == 0)
|
||||||
|
sock->timeout_event = 1;
|
||||||
|
|
||||||
|
if (retval >= 0)
|
||||||
|
break;
|
||||||
|
|
||||||
|
if (php_socket_errno() != EINTR)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static size_t php_openssl_sockop_read(php_stream *stream, char *buf, size_t count TSRMLS_DC)
|
static size_t php_openssl_sockop_read(php_stream *stream, char *buf, size_t count TSRMLS_DC)
|
||||||
{
|
{
|
||||||
php_openssl_netstream_data_t *sslsock = (php_openssl_netstream_data_t*)stream->abstract;
|
php_openssl_netstream_data_t *sslsock = (php_openssl_netstream_data_t*)stream->abstract;
|
||||||
|
php_netstream_data_t *sock;
|
||||||
int nr_bytes = 0;
|
int nr_bytes = 0;
|
||||||
|
|
||||||
if (sslsock->ssl_active) {
|
if (sslsock->ssl_active) {
|
||||||
int retry = 1;
|
int retry = 1;
|
||||||
|
sock = (php_netstream_data_t*)stream->abstract;
|
||||||
|
|
||||||
|
/* The SSL_read() function will block indefinitely waiting for data on a blocking
|
||||||
|
socket. If we don't poll for readability first this operation has the potential
|
||||||
|
to hang forever. To avoid this scenario we poll with a timeout before performing
|
||||||
|
the actual read. If it times out we're finished.
|
||||||
|
*/
|
||||||
|
if (sock->is_blocked) {
|
||||||
|
php_openssl_stream_wait_for_data(sock);
|
||||||
|
if (sock->timeout_event) {
|
||||||
|
stream->eof = 1;
|
||||||
|
php_error_docref(NULL TSRMLS_CC, E_WARNING, "SSL read operation timed out");
|
||||||
|
return nr_bytes;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
do {
|
do {
|
||||||
nr_bytes = SSL_read(sslsock->ssl_handle, buf, count);
|
nr_bytes = SSL_read(sslsock->ssl_handle, buf, count);
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue