]> granicus.if.org Git - php/commitdiff
When a socket is non-blocking, don't block ssl enabled sockets.
authorWez Furlong <wez@php.net>
Sat, 25 Dec 2004 02:02:56 +0000 (02:02 +0000)
committerWez Furlong <wez@php.net>
Sat, 25 Dec 2004 02:02:56 +0000 (02:02 +0000)
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

ext/openssl/xp_ssl.c
ext/standard/streamsfuncs.c

index 1607b9d4861af897f63c072c09410c288a295533..4b995cdc3241b00ccc2fa052031f40ba607953e4 100644 (file)
@@ -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;
index 7ee44a0752bf94abd3858defcccc7135ca431ed4..949a14656a7c0653c1f16bcfeaaeec1b7c0d8996 100644 (file)
@@ -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;
+       }
 }
 /* }}} */