Browse Source

When a socket is non-blocking, don't block ssl enabled sockets.

Allow for non-blocking negotiation when calling stream_socket_enable_crypto().
That function will return the foolowing values:

false - negotiation failed
0     - try again when more data is available (only for non-blocking sockets)
true  - ssl was enabled
PHP-5.1
Wez Furlong 22 years ago
parent
commit
843807c647
  1. 20
      ext/openssl/xp_ssl.c
  2. 15
      ext/standard/streamsfuncs.c

20
ext/openssl/xp_ssl.c

@ -46,6 +46,8 @@ typedef struct _php_openssl_netstream_data_t {
int is_client;
int ssl_active;
php_stream_xport_crypt_method_t method;
unsigned state_set:1;
unsigned _spare:31;
} php_openssl_netstream_data_t;
php_stream_ops php_openssl_socket_ops;
@ -92,6 +94,8 @@ static int handle_ssl_error(php_stream *stream, int nr_bytes TSRMLS_DC)
case SSL_ERROR_WANT_WRITE:
/* re-negotiation, or perhaps the SSL layer needs more
* packets: retry in next iteration */
errno = EAGAIN;
retry = sslsock->s.is_blocked;
break;
case SSL_ERROR_SYSCALL:
if (ERR_peek_error() == 0) {
@ -159,6 +163,7 @@ static int handle_ssl_error(php_stream *stream, int nr_bytes TSRMLS_DC)
}
retry = 0;
errno = 0;
}
return retry;
}
@ -210,7 +215,7 @@ static size_t php_openssl_sockop_read(php_stream *stream, char *buf, size_t coun
if (nr_bytes <= 0) {
retry = handle_ssl_error(stream, nr_bytes TSRMLS_CC);
stream->eof = (retry == 0 && !SSL_pending(sslsock->ssl_handle));
stream->eof = (retry == 0 && errno != EAGAIN && !SSL_pending(sslsock->ssl_handle));
} else {
/* we got the data */
@ -377,10 +382,13 @@ static inline int php_openssl_enable_crypto(php_stream *stream,
int n, retry = 1;
if (cparam->inputs.activate && !sslsock->ssl_active) {
if (sslsock->is_client) {
SSL_set_connect_state(sslsock->ssl_handle);
} else {
SSL_set_accept_state(sslsock->ssl_handle);
if (!sslsock->state_set) {
if (sslsock->is_client) {
SSL_set_connect_state(sslsock->ssl_handle);
} else {
SSL_set_accept_state(sslsock->ssl_handle);
}
sslsock->state_set = 1;
}
do {
@ -409,6 +417,8 @@ static inline int php_openssl_enable_crypto(php_stream *stream,
}
X509_free(peer_cert);
} else {
n = errno == EAGAIN ? 0 : -1;
}
return n;

15
ext/standard/streamsfuncs.c

@ -1290,7 +1290,7 @@ PHP_FUNCTION(stream_set_write_buffer)
}
/* }}} */
/* {{{ proto bool stream_socket_enable_crypto(resource stream, bool enable [, int cryptokind, resource sessionstream])
/* {{{ proto int stream_socket_enable_crypto(resource stream, bool enable [, int cryptokind, resource sessionstream])
Enable or disable a specific kind of crypto on the stream */
PHP_FUNCTION(stream_socket_enable_crypto)
{
@ -1298,6 +1298,7 @@ PHP_FUNCTION(stream_socket_enable_crypto)
zval *zstream, *zsessstream = NULL;
php_stream *stream, *sessstream = NULL;
zend_bool enable;
int ret;
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rb|lr", &zstream, &enable, &cryptokind, &zsessstream) == FAILURE) {
RETURN_FALSE;
@ -1315,7 +1316,17 @@ PHP_FUNCTION(stream_socket_enable_crypto)
}
}
RETURN_BOOL(php_stream_xport_crypto_enable(stream, enable TSRMLS_CC) < 0 ? 0 : 1);
ret = php_stream_xport_crypto_enable(stream, enable TSRMLS_CC);
switch (ret) {
case -1:
RETURN_FALSE;
case 0:
RETURN_LONG(0);
default:
RETURN_TRUE;
}
}
/* }}} */

Loading…
Cancel
Save