Skip to content

Commit f7c63f7

Browse files
committed
ext/openssl: convert PSK callback to FCC
Prevent rechecking the given zval callable every single time
1 parent eea5d0a commit f7c63f7

1 file changed

Lines changed: 32 additions & 24 deletions

File tree

ext/openssl/xp_ssl.c

Lines changed: 32 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -183,8 +183,8 @@ static const unsigned char php_openssl_tls13_aes256gcmsha384_id[] = { 0x13, 0x02
183183
/* Holds PSK callbacks */
184184
typedef struct _php_openssl_psk_callbacks_t {
185185
int refcount;
186-
zval client_cb;
187-
zval server_cb;
186+
zend_fcall_info_cache client_cb;
187+
zend_fcall_info_cache server_cb;
188188
} php_openssl_psk_callbacks_t;
189189

190190
/* Holds session callback */
@@ -1621,7 +1621,7 @@ static SSL_SESSION *php_openssl_psk_build_session(SSL *ssl,
16211621
/**
16221622
* Invoke a user PHP callback (psk_client_cb or psk_server_cb).
16231623
*/
1624-
static zend_result php_openssl_call_psk_cb(php_stream *stream, zval *cb,
1624+
static zend_result php_openssl_call_psk_cb(php_stream *stream, zend_fcall_info_cache *fcc,
16251625
const unsigned char *identity, size_t identity_len,
16261626
zval *result)
16271627
{
@@ -1639,13 +1639,14 @@ static zend_result php_openssl_call_psk_cb(php_stream *stream, zval *cb,
16391639
}
16401640

16411641
ZVAL_UNDEF(&retval);
1642-
call_user_function(NULL, NULL, cb, &retval, argc, args);
1642+
1643+
zend_call_known_fcc(fcc, &retval, argc, args, NULL);
16431644

16441645
if (identity != NULL) {
16451646
zval_ptr_dtor(&args[1]);
16461647
}
16471648

1648-
if (EG(exception)) {
1649+
if (Z_ISUNDEF(retval)) {
16491650
ZVAL_UNDEF(result);
16501651
return FAILURE;
16511652
}
@@ -1686,7 +1687,7 @@ static unsigned int php_openssl_psk_client_cb(SSL *ssl, const char *hint,
16861687
php_openssl_netstream_data_t *sslsock =
16871688
(php_openssl_netstream_data_t *)stream->abstract;
16881689
if (sslsock == NULL || sslsock->psk_callbacks == NULL
1689-
|| Z_ISUNDEF(sslsock->psk_callbacks->client_cb)) {
1690+
|| !ZEND_FCC_INITIALIZED(sslsock->psk_callbacks->client_cb)) {
16901691
return 0;
16911692
}
16921693

@@ -1737,7 +1738,7 @@ static unsigned int php_openssl_psk_server_cb(SSL *ssl, const char *identity,
17371738
php_openssl_netstream_data_t *sslsock =
17381739
(php_openssl_netstream_data_t *)stream->abstract;
17391740
if (sslsock == NULL || sslsock->psk_callbacks == NULL
1740-
|| Z_ISUNDEF(sslsock->psk_callbacks->server_cb)) {
1741+
|| !ZEND_FCC_INITIALIZED(sslsock->psk_callbacks->server_cb)) {
17411742
return 0;
17421743
}
17431744

@@ -1793,7 +1794,7 @@ static int php_openssl_psk_use_session_cb(SSL *ssl, const EVP_MD *md,
17931794
php_openssl_netstream_data_t *sslsock =
17941795
(php_openssl_netstream_data_t *)stream->abstract;
17951796
if (sslsock == NULL || sslsock->psk_callbacks == NULL
1796-
|| Z_ISUNDEF(sslsock->psk_callbacks->client_cb)) {
1797+
|| !ZEND_FCC_INITIALIZED(sslsock->psk_callbacks->client_cb)) {
17971798
return 1;
17981799
}
17991800

@@ -1860,7 +1861,7 @@ static int php_openssl_psk_find_session_cb(SSL *ssl, const unsigned char *identi
18601861

18611862
php_openssl_netstream_data_t *sslsock = (php_openssl_netstream_data_t *)stream->abstract;
18621863
if (sslsock == NULL || sslsock->psk_callbacks == NULL
1863-
|| Z_ISUNDEF(sslsock->psk_callbacks->server_cb)) {
1864+
|| !ZEND_FCC_INITIALIZED(sslsock->psk_callbacks->server_cb)) {
18641865
return 1;
18651866
}
18661867

@@ -1896,17 +1897,19 @@ static int php_openssl_psk_find_session_cb(SSL *ssl, const unsigned char *identi
18961897
/* PSK setup */
18971898

18981899
static zend_result php_openssl_validate_and_allocate_psk_callback(
1899-
php_openssl_netstream_data_t *sslsock, zval *callable,
1900-
const char *callback_name, bool is_persistent)
1900+
php_openssl_netstream_data_t *sslsock, const zval *callable,
1901+
bool is_client, bool is_persistent)
19011902
{
1903+
const char *callback_name = is_client ? "psk_client_cb" : "psk_server_cb";
19021904
if (is_persistent) {
19031905
php_error_docref(NULL, E_WARNING,
19041906
"%s is not supported for persistent streams", callback_name);
19051907
return FAILURE;
19061908
}
19071909

19081910
char *is_callable_error = NULL;
1909-
if (!zend_is_callable_ex(callable, NULL, 0, NULL, NULL, &is_callable_error)) {
1911+
zend_fcall_info_cache fcc = {0};
1912+
if (!zend_is_callable_ex(callable, NULL, 0, NULL, &fcc, &is_callable_error)) {
19101913
if (is_callable_error) {
19111914
zend_type_error("%s must be a valid callback, %s",
19121915
callback_name, is_callable_error);
@@ -1918,12 +1921,16 @@ static zend_result php_openssl_validate_and_allocate_psk_callback(
19181921
}
19191922

19201923
if (!sslsock->psk_callbacks) {
1921-
sslsock->psk_callbacks = (php_openssl_psk_callbacks_t *)pemalloc(
1922-
sizeof(php_openssl_psk_callbacks_t), is_persistent);
1923-
ZVAL_UNDEF(&sslsock->psk_callbacks->client_cb);
1924-
ZVAL_UNDEF(&sslsock->psk_callbacks->server_cb);
1924+
sslsock->psk_callbacks = (php_openssl_psk_callbacks_t *)pecalloc(
1925+
1, sizeof(php_openssl_psk_callbacks_t), is_persistent);
19251926
sslsock->psk_callbacks->refcount = 1;
19261927
}
1928+
zend_fcc_addref(&fcc);
1929+
if (is_client) {
1930+
sslsock->psk_callbacks->client_cb = fcc;
1931+
} else {
1932+
sslsock->psk_callbacks->server_cb = fcc;
1933+
}
19271934

19281935
return SUCCESS;
19291936
}
@@ -1938,12 +1945,10 @@ static zend_result php_openssl_setup_client_psk(php_stream *stream,
19381945
}
19391946

19401947
if (FAILURE == php_openssl_validate_and_allocate_psk_callback(
1941-
sslsock, val, "psk_client_cb", php_stream_is_persistent(stream))) {
1948+
sslsock, val, true, php_stream_is_persistent(stream))) {
19421949
return FAILURE;
19431950
}
19441951

1945-
ZVAL_COPY(&sslsock->psk_callbacks->client_cb, val);
1946-
19471952
#ifndef OPENSSL_NO_PSK
19481953
SSL_CTX_set_psk_client_callback(sslsock->ctx, php_openssl_psk_client_cb);
19491954
#endif
@@ -1962,12 +1967,10 @@ static zend_result php_openssl_setup_server_psk(php_stream *stream,
19621967
}
19631968

19641969
if (FAILURE == php_openssl_validate_and_allocate_psk_callback(
1965-
sslsock, val, "psk_server_cb", php_stream_is_persistent(stream))) {
1970+
sslsock, val, false, php_stream_is_persistent(stream))) {
19661971
return FAILURE;
19671972
}
19681973

1969-
ZVAL_COPY(&sslsock->psk_callbacks->server_cb, val);
1970-
19711974
#ifndef OPENSSL_NO_PSK
19721975
SSL_CTX_set_psk_server_callback(sslsock->ctx, php_openssl_psk_server_cb);
19731976
#endif
@@ -3092,8 +3095,13 @@ static int php_openssl_sockop_close(php_stream *stream, int close_handle) /* {{{
30923095
}
30933096

30943097
if (sslsock->psk_callbacks && --sslsock->psk_callbacks->refcount == 0) {
3095-
zval_ptr_dtor(&sslsock->psk_callbacks->client_cb);
3096-
zval_ptr_dtor(&sslsock->psk_callbacks->server_cb);
3098+
if (ZEND_FCC_INITIALIZED(sslsock->psk_callbacks->client_cb)) {
3099+
zend_fcc_dtor(&sslsock->psk_callbacks->client_cb);
3100+
}
3101+
3102+
if (ZEND_FCC_INITIALIZED(sslsock->psk_callbacks->server_cb)) {
3103+
zend_fcc_dtor(&sslsock->psk_callbacks->server_cb);
3104+
}
30973105
pefree(sslsock->psk_callbacks, php_stream_is_persistent(stream));
30983106
}
30993107

0 commit comments

Comments
 (0)