From e9f3139f438ef712d82b69984a65da4230fdfeb2 Mon Sep 17 00:00:00 2001 From: Andrey Hristov Date: Mon, 9 Nov 2015 14:56:16 +0100 Subject: [PATCH] MNDR: - split MYSQLND_NET into MYSQLND_NET and MYSQLND_VIO MYSQLND_NET is above MYSQLND_VIO. _NET takes care of protocol packet counting (even with compressed), while VIO is just about the network (or in case of windows, non-network, but PIPE) transport. --- ext/mysqlnd/mysqlnd.c | 34 ++- ext/mysqlnd/mysqlnd_auth.c | 8 +- ext/mysqlnd/mysqlnd_driver.c | 47 +++- ext/mysqlnd/mysqlnd_ext_plugin.c | 22 ++ ext/mysqlnd/mysqlnd_ext_plugin.h | 16 +- ext/mysqlnd/mysqlnd_loaddata.c | 9 +- ext/mysqlnd/mysqlnd_net.c | 362 +++++++++++++++++++---------- ext/mysqlnd/mysqlnd_net.h | 3 + ext/mysqlnd/mysqlnd_priv.h | 1 + ext/mysqlnd/mysqlnd_structs.h | 170 +++++++++----- ext/mysqlnd/mysqlnd_wireprotocol.c | 124 ++++++---- ext/mysqlnd/mysqlnd_wireprotocol.h | 1 + 12 files changed, 537 insertions(+), 260 deletions(-) diff --git a/ext/mysqlnd/mysqlnd.c b/ext/mysqlnd/mysqlnd.c index 4259ab91cf..616c5c379f 100644 --- a/ext/mysqlnd/mysqlnd.c +++ b/ext/mysqlnd/mysqlnd.c @@ -270,6 +270,10 @@ MYSQLND_METHOD(mysqlnd_conn_data, free_contents)(MYSQLND_CONN_DATA * conn) conn->net->data->m.free_contents(conn->net); } + if (conn->vio) { + conn->vio->data->m.free_contents(conn->vio); + } + DBG_INF("Freeing memory of members"); if (conn->host) { @@ -341,6 +345,11 @@ MYSQLND_METHOD_PRIVATE(mysqlnd_conn_data, dtor)(MYSQLND_CONN_DATA * conn) conn->net = NULL; } + if (conn->vio) { + mysqlnd_vio_free(conn->vio, conn->stats, conn->error_info); + conn->vio = NULL; + } + if (conn->payload_decoder_factory) { mysqlnd_protocol_payload_decoder_factory_free(conn->payload_decoder_factory); conn->payload_decoder_factory = NULL; @@ -655,6 +664,7 @@ static unsigned int MYSQLND_METHOD(mysqlnd_conn_data, get_updated_connect_flags)(MYSQLND_CONN_DATA * conn, unsigned int mysql_flags) { MYSQLND_NET * net = conn->net; + MYSQLND_VIO * vio = conn->vio; DBG_ENTER("mysqlnd_conn_data::get_updated_connect_flags"); /* we allow load data local infile by default */ @@ -680,8 +690,8 @@ MYSQLND_METHOD(mysqlnd_conn_data, get_updated_connect_flags)(MYSQLND_CONN_DATA * mysql_flags &= ~CLIENT_SSL; } #else - if (net && (net->data->options.ssl_key || net->data->options.ssl_cert || - net->data->options.ssl_ca || net->data->options.ssl_capath || net->data->options.ssl_cipher)) + if (vio && (vio->data->options.ssl_key || vio->data->options.ssl_cert || + vio->data->options.ssl_ca || vio->data->options.ssl_capath || vio->data->options.ssl_cipher)) { mysql_flags |= CLIENT_SSL; } @@ -705,9 +715,9 @@ MYSQLND_METHOD(mysqlnd_conn_data, connect_handshake)(MYSQLND_CONN_DATA * conn, size_t client_flags = mysql_flags; DBG_ENTER("mysqlnd_conn_data::connect_handshake"); - if (FAIL == conn->net->data->m.connect_ex(conn->net, *scheme, conn->persistent, conn->stats, conn->error_info)) { + if (FAIL == conn->vio->data->m.connect(conn->vio, *scheme, conn->persistent, conn->stats, conn->error_info)) { DBG_RETURN(FAIL); - } else { + } else if (PASS == conn->net->data->m.connect(conn->net, *scheme, conn->persistent, conn->stats, conn->error_info)) { struct st_mysqlnd_protocol_command * command = conn->command_factory(COM_HANDSHAKE, conn, username, password, database, client_flags); if (command) { ret = command->run(command); @@ -1203,7 +1213,7 @@ static int mysqlnd_stream_array_to_fd_set(MYSQLND ** conn_array, fd_set * fds, p * when casting. It is only used here so that the buffered data warning * is not displayed. * */ - stream = (*p)->data->net->data->m.get_stream((*p)->data->net); + stream = (*p)->data->vio->data->m.get_stream((*p)->data->vio); DBG_INF_FMT("conn=%llu stream=%p", (*p)->data->thread_id, stream); if (stream != NULL && SUCCESS == php_stream_cast(stream, PHP_STREAM_AS_FD_FOR_SELECT | PHP_STREAM_CAST_INTERNAL, (void*)&this_fd, 1) && ZEND_VALID_SOCKET(this_fd)) { @@ -1233,7 +1243,7 @@ static int mysqlnd_stream_array_from_fd_set(MYSQLND ** conn_array, fd_set * fds) DBG_ENTER("mysqlnd_stream_array_from_fd_set"); while (*fwd) { - stream = (*fwd)->data->net->data->m.get_stream((*fwd)->data->net); + stream = (*fwd)->data->vio->data->m.get_stream((*fwd)->data->vio); DBG_INF_FMT("conn=%llu stream=%p", (*fwd)->data->thread_id, stream); if (stream != NULL && SUCCESS == php_stream_cast(stream, PHP_STREAM_AS_FD_FOR_SELECT | PHP_STREAM_CAST_INTERNAL, (void*)&this_fd, 1) && ZEND_VALID_SOCKET(this_fd)) { @@ -1426,7 +1436,7 @@ MYSQLND_METHOD(mysqlnd_conn_data, ssl_set)(MYSQLND_CONN_DATA * const conn, const { const size_t this_func = STRUCT_OFFSET(MYSQLND_CLASS_METHODS_TYPE(mysqlnd_conn_data), ssl_set); enum_func_status ret = FAIL; - MYSQLND_NET * net = conn->net; + MYSQLND_VIO * net = conn->vio; DBG_ENTER("mysqlnd_conn_data::ssl_set"); if (PASS == conn->m->local_tx_start(conn, this_func)) { @@ -1677,8 +1687,8 @@ static enum_func_status MYSQLND_METHOD(mysqlnd_conn_data, send_close)(MYSQLND_CONN_DATA * const conn) { enum_func_status ret = PASS; - MYSQLND_NET * net = conn->net; - php_stream * net_stream = net->data->m.get_stream(net); + MYSQLND_VIO * vio = conn->vio; + php_stream * net_stream = vio->data->m.get_stream(vio); enum mysqlnd_connection_state state; DBG_ENTER("mysqlnd_send_close"); @@ -1702,7 +1712,7 @@ MYSQLND_METHOD(mysqlnd_conn_data, send_close)(MYSQLND_CONN_DATA * const conn) ret = command->run(command); command->free_command(command); } - net->data->m.close_stream(net, conn->stats, conn->error_info); + vio->data->m.close_stream(vio, conn->stats, conn->error_info); } SET_CONNECTION_STATE(&conn->state, CONN_QUIT_SENT); break; @@ -1732,7 +1742,7 @@ MYSQLND_METHOD(mysqlnd_conn_data, send_close)(MYSQLND_CONN_DATA * const conn) /* Fall-through */ case CONN_QUIT_SENT: /* The user has killed its own connection */ - net->data->m.close_stream(net, conn->stats, conn->error_info); + vio->data->m.close_stream(vio, conn->stats, conn->error_info); break; } @@ -2104,6 +2114,8 @@ MYSQLND_METHOD(mysqlnd_conn_data, set_client_option)(MYSQLND_CONN_DATA * const c case MYSQL_OPT_CONNECT_TIMEOUT: case MYSQLND_OPT_NET_CMD_BUFFER_SIZE: case MYSQLND_OPT_NET_READ_BUFFER_SIZE: + ret = conn->vio->data->m.set_client_option(conn->vio, option, value); + break; case MYSQL_SERVER_PUBLIC_KEY: ret = conn->net->data->m.set_client_option(conn->net, option, value); break; diff --git a/ext/mysqlnd/mysqlnd_auth.c b/ext/mysqlnd/mysqlnd_auth.c index 814a06bd2a..3a57f3f10c 100644 --- a/ext/mysqlnd/mysqlnd_auth.c +++ b/ext/mysqlnd/mysqlnd_auth.c @@ -360,7 +360,7 @@ mysqlnd_native_auth_get_auth_data(struct st_mysqlnd_authentication_plugin * self MYSQLND_CONN_DATA * conn, const char * const user, const char * const passwd, const size_t passwd_len, zend_uchar * auth_plugin_data, size_t auth_plugin_data_len, const MYSQLND_SESSION_OPTIONS * const session_options, - const MYSQLND_IO_OPTIONS * const io_options, + const MYSQLND_NET_OPTIONS * const io_options, zend_ulong mysql_flags ) { @@ -420,7 +420,7 @@ mysqlnd_pam_auth_get_auth_data(struct st_mysqlnd_authentication_plugin * self, MYSQLND_CONN_DATA * conn, const char * const user, const char * const passwd, const size_t passwd_len, zend_uchar * auth_plugin_data, size_t auth_plugin_data_len, const MYSQLND_SESSION_OPTIONS * const session_options, - const MYSQLND_IO_OPTIONS * const io_options, + const MYSQLND_NET_OPTIONS * const io_options, zend_ulong mysql_flags ) { @@ -481,7 +481,7 @@ mysqlnd_xor_string(char * dst, const size_t dst_len, const char * xor_str, const static RSA * mysqlnd_sha256_get_rsa_key(MYSQLND_CONN_DATA * conn, const MYSQLND_SESSION_OPTIONS * const session_options, - const MYSQLND_IO_OPTIONS * const io_options + const MYSQLND_NET_OPTIONS * const io_options ) { RSA * ret = NULL; @@ -570,7 +570,7 @@ mysqlnd_sha256_auth_get_auth_data(struct st_mysqlnd_authentication_plugin * self MYSQLND_CONN_DATA * conn, const char * const user, const char * const passwd, const size_t passwd_len, zend_uchar * auth_plugin_data, size_t auth_plugin_data_len, const MYSQLND_SESSION_OPTIONS * const session_options, - const MYSQLND_IO_OPTIONS * const io_options, + const MYSQLND_NET_OPTIONS * const io_options, zend_ulong mysql_flags ) { diff --git a/ext/mysqlnd/mysqlnd_driver.c b/ext/mysqlnd/mysqlnd_driver.c index cda731b934..ed4506322e 100644 --- a/ext/mysqlnd/mysqlnd_driver.c +++ b/ext/mysqlnd/mysqlnd_driver.c @@ -140,6 +140,7 @@ MYSQLND_METHOD(mysqlnd_object_factory, get_connection)(struct st_mysqlnd_object_ mysqlnd_stats_init(&data->stats, STAT_LAST, persistent); data->net = mysqlnd_net_init(persistent, data->stats, data->error_info); + data->vio = mysqlnd_vio_init(persistent, data->stats, data->error_info); data->payload_decoder_factory = mysqlnd_protocol_payload_decoder_factory_init(data, persistent); data->command_factory = mysqlnd_command_factory_get(); @@ -241,16 +242,16 @@ MYSQLND_METHOD(mysqlnd_object_factory, get_prepared_statement)(MYSQLND_CONN_DATA /* }}} */ -/* {{{ mysqlnd_object_factory::get_io_channel */ -PHPAPI MYSQLND_NET * -MYSQLND_METHOD(mysqlnd_object_factory, get_io_channel)(zend_bool persistent, MYSQLND_STATS * stats, MYSQLND_ERROR_INFO * error_info) +/* {{{ mysqlnd_object_factory::get_net */ +static MYSQLND_NET * +MYSQLND_METHOD(mysqlnd_object_factory, get_net)(zend_bool persistent, MYSQLND_STATS * stats, MYSQLND_ERROR_INFO * error_info) { size_t net_alloc_size = sizeof(MYSQLND_NET) + mysqlnd_plugin_count() * sizeof(void *); size_t net_data_alloc_size = sizeof(MYSQLND_NET_DATA) + mysqlnd_plugin_count() * sizeof(void *); MYSQLND_NET * net = mnd_pecalloc(1, net_alloc_size, persistent); MYSQLND_NET_DATA * net_data = mnd_pecalloc(1, net_data_alloc_size, persistent); - DBG_ENTER("mysqlnd_object_factory::get_io_channel"); + DBG_ENTER("mysqlnd_object_factory::get_net"); DBG_INF_FMT("persistent=%u", persistent); if (net && net_data) { net->data = net_data; @@ -276,6 +277,41 @@ MYSQLND_METHOD(mysqlnd_object_factory, get_io_channel)(zend_bool persistent, MYS /* }}} */ +/* {{{ mysqlnd_object_factory::get_vio */ +static MYSQLND_VIO * +MYSQLND_METHOD(mysqlnd_object_factory, get_vio)(zend_bool persistent, MYSQLND_STATS * stats, MYSQLND_ERROR_INFO * error_info) +{ + size_t vio_alloc_size = sizeof(MYSQLND_VIO) + mysqlnd_plugin_count() * sizeof(void *); + size_t vio_data_alloc_size = sizeof(MYSQLND_VIO_DATA) + mysqlnd_plugin_count() * sizeof(void *); + MYSQLND_VIO * vio = mnd_pecalloc(1, vio_alloc_size, persistent); + MYSQLND_VIO_DATA * vio_data = mnd_pecalloc(1, vio_data_alloc_size, persistent); + + DBG_ENTER("mysqlnd_object_factory::get_vio"); + DBG_INF_FMT("persistent=%u", persistent); + if (vio && vio_data) { + vio->data = vio_data; + vio->persistent = vio->data->persistent = persistent; + vio->data->m = *mysqlnd_vio_get_methods(); + + if (PASS != vio->data->m.init(vio, stats, error_info)) { + vio->data->m.dtor(vio, stats, error_info); + vio = NULL; + } + } else { + if (vio_data) { + mnd_pefree(vio_data, persistent); + vio_data = NULL; + } + if (vio) { + mnd_pefree(vio, persistent); + vio = NULL; + } + } + DBG_RETURN(vio); +} +/* }}} */ + + /* {{{ mysqlnd_object_factory::get_protocol_payload_decoder_factory */ static MYSQLND_PROTOCOL_PAYLOAD_DECODER_FACTORY * MYSQLND_METHOD(mysqlnd_object_factory, get_protocol_payload_decoder_factory)(MYSQLND_CONN_DATA * conn, zend_bool persistent) @@ -300,7 +336,8 @@ PHPAPI MYSQLND_CLASS_METHODS_START(mysqlnd_object_factory) MYSQLND_METHOD(mysqlnd_object_factory, get_connection), MYSQLND_METHOD(mysqlnd_object_factory, clone_connection_object), MYSQLND_METHOD(mysqlnd_object_factory, get_prepared_statement), - MYSQLND_METHOD(mysqlnd_object_factory, get_io_channel), + MYSQLND_METHOD(mysqlnd_object_factory, get_net), + MYSQLND_METHOD(mysqlnd_object_factory, get_vio), MYSQLND_METHOD(mysqlnd_object_factory, get_protocol_payload_decoder_factory) MYSQLND_CLASS_METHODS_END; diff --git a/ext/mysqlnd/mysqlnd_ext_plugin.c b/ext/mysqlnd/mysqlnd_ext_plugin.c index 8048a2a67e..76d51bcc18 100644 --- a/ext/mysqlnd/mysqlnd_ext_plugin.c +++ b/ext/mysqlnd/mysqlnd_ext_plugin.c @@ -327,6 +327,24 @@ _mysqlnd_net_set_methods(MYSQLND_CLASS_METHODS_TYPE(mysqlnd_net) * methods) /* }}} */ +/* {{{ _mysqlnd_vio_get_methods */ +static MYSQLND_CLASS_METHODS_TYPE(mysqlnd_vio) * +_mysqlnd_vio_get_methods() +{ + return &MYSQLND_CLASS_METHOD_TABLE_NAME(mysqlnd_vio); +} +/* }}} */ + + +/* {{{ _mysqlnd_vio_set_methods */ +static void +_mysqlnd_vio_set_methods(MYSQLND_CLASS_METHODS_TYPE(mysqlnd_vio) * methods) +{ + MYSQLND_CLASS_METHOD_TABLE_NAME(mysqlnd_vio) = *methods; +} +/* }}} */ + + /* {{{ mysqlnd_command_factory_get */ static func_mysqlnd__command_factory _mysqlnd_command_factory_get() @@ -401,6 +419,10 @@ struct st_mysqlnd_plugin_methods_xetters mysqlnd_plugin_methods_xetters = _mysqlnd_net_get_methods, _mysqlnd_net_set_methods, }, + { + _mysqlnd_vio_get_methods, + _mysqlnd_vio_set_methods, + }, { _mysqlnd_error_info_get_methods, _mysqlnd_error_info_set_methods, diff --git a/ext/mysqlnd/mysqlnd_ext_plugin.h b/ext/mysqlnd/mysqlnd_ext_plugin.h index f994ba018a..2808cb984d 100644 --- a/ext/mysqlnd/mysqlnd_ext_plugin.h +++ b/ext/mysqlnd/mysqlnd_ext_plugin.h @@ -97,11 +97,17 @@ struct st_mysqlnd_plugin_methods_xetters void (*set)(MYSQLND_CLASS_METHODS_TYPE(mysqlnd_protocol_payload_decoder_factory) *methods); } protocol; - struct st_mnd_io_xetters + struct st_mnd_net_xetters { MYSQLND_CLASS_METHODS_TYPE(mysqlnd_net) * (*get)(); void (*set)(MYSQLND_CLASS_METHODS_TYPE(mysqlnd_net) * methods); - } io; + } net; + + struct st_mnd_vio_xetters + { + MYSQLND_CLASS_METHODS_TYPE(mysqlnd_vio) * (*get)(); + void (*set)(MYSQLND_CLASS_METHODS_TYPE(mysqlnd_vio) * methods); + } vio; struct st_mnd_error_info_xetters { @@ -143,9 +149,11 @@ extern struct st_mysqlnd_plugin_methods_xetters mysqlnd_plugin_methods_xetters; #define mysqlnd_protocol_get_methods() mysqlnd_plugin_methods_xetters.protocol.get() #define mysqlnd_protocol_set_methods(m) mysqlnd_plugin_methods_xetters.protocol.set((m)) -#define mysqlnd_net_get_methods() mysqlnd_plugin_methods_xetters.io.get() -#define mysqlnd_net_set_methods(m) mysqlnd_plugin_methods_xetters.io.set((m)) +#define mysqlnd_net_get_methods() mysqlnd_plugin_methods_xetters.net.get() +#define mysqlnd_net_set_methods(m) mysqlnd_plugin_methods_xetters.net.set((m)) +#define mysqlnd_vio_get_methods() mysqlnd_plugin_methods_xetters.vio.get() +#define mysqlnd_vio_set_methods(m) mysqlnd_plugin_methods_xetters.vio.set((m)) #define mysqlnd_command_factory_get() mysqlnd_plugin_methods_xetters.command_factory.get() #define mysqlnd_command_factory_set(m) mysqlnd_plugin_methods_xetters.command_factory.set((m)) diff --git a/ext/mysqlnd/mysqlnd_loaddata.c b/ext/mysqlnd/mysqlnd_loaddata.c index 65e696f079..70688d32ca 100644 --- a/ext/mysqlnd/mysqlnd_loaddata.c +++ b/ext/mysqlnd/mysqlnd_loaddata.c @@ -152,13 +152,14 @@ mysqlnd_handle_local_infile(MYSQLND_CONN_DATA * conn, const char * const filenam size_t ret; MYSQLND_INFILE infile; MYSQLND_NET * net = conn->net; + MYSQLND_VIO * vio = conn->vio; DBG_ENTER("mysqlnd_handle_local_infile"); if (!(conn->options->flags & CLIENT_LOCAL_FILES)) { php_error_docref(NULL, E_WARNING, "LOAD DATA LOCAL INFILE forbidden"); /* write empty packet to server */ - ret = net->data->m.send_ex(net, empty_packet, 0, conn->stats, conn->error_info); + ret = net->data->m.send(net, vio, empty_packet, 0, conn->stats, conn->error_info); *is_warning = TRUE; goto infile_error; } @@ -178,13 +179,13 @@ mysqlnd_handle_local_infile(MYSQLND_CONN_DATA * conn, const char * const filenam tmp_error_no = infile.local_infile_error(info, tmp_buf, sizeof(tmp_buf)); SET_CLIENT_ERROR(conn->error_info, tmp_error_no, UNKNOWN_SQLSTATE, tmp_buf); /* write empty packet to server */ - ret = net->data->m.send_ex(net, empty_packet, 0, conn->stats, conn->error_info); + ret = net->data->m.send(net, vio, empty_packet, 0, conn->stats, conn->error_info); goto infile_error; } /* read data */ while ((bufsize = infile.local_infile_read (info, buf + MYSQLND_HEADER_SIZE, buflen - MYSQLND_HEADER_SIZE)) > 0) { - if ((ret = net->data->m.send_ex(net, buf, bufsize, conn->stats, conn->error_info)) == 0) { + if ((ret = net->data->m.send(net, vio, buf, bufsize, conn->stats, conn->error_info)) == 0) { DBG_ERR_FMT("Error during read : %d %s %s", CR_SERVER_LOST, UNKNOWN_SQLSTATE, lost_conn); SET_CLIENT_ERROR(conn->error_info, CR_SERVER_LOST, UNKNOWN_SQLSTATE, lost_conn); goto infile_error; @@ -192,7 +193,7 @@ mysqlnd_handle_local_infile(MYSQLND_CONN_DATA * conn, const char * const filenam } /* send empty packet for eof */ - if ((ret = net->data->m.send_ex(net, empty_packet, 0, conn->stats, conn->error_info)) == 0) { + if ((ret = net->data->m.send(net, vio, empty_packet, 0, conn->stats, conn->error_info)) == 0) { SET_CLIENT_ERROR(conn->error_info, CR_SERVER_LOST, UNKNOWN_SQLSTATE, lost_conn); goto infile_error; } diff --git a/ext/mysqlnd/mysqlnd_net.c b/ext/mysqlnd/mysqlnd_net.c index 379c97ccd9..e2c125fdfb 100644 --- a/ext/mysqlnd/mysqlnd_net.c +++ b/ext/mysqlnd/mysqlnd_net.c @@ -82,21 +82,21 @@ mysqlnd_set_sock_keepalive(php_stream * stream) /* }}} */ -/* {{{ mysqlnd_net::network_read_ex */ +/* {{{ mysqlnd_vio::network_read */ static enum_func_status -MYSQLND_METHOD(mysqlnd_net, network_read_ex)(MYSQLND_NET * const net, zend_uchar * const buffer, const size_t count, +MYSQLND_METHOD(mysqlnd_vio, network_read)(MYSQLND_VIO * const vio, zend_uchar * const buffer, const size_t count, MYSQLND_STATS * const stats, MYSQLND_ERROR_INFO * const error_info) { enum_func_status return_value = PASS; - php_stream * net_stream = net->data->m.get_stream(net); + php_stream * net_stream = vio->data->m.get_stream(vio); size_t old_chunk_size = net_stream->chunk_size; size_t to_read = count, ret; zend_uchar * p = buffer; - DBG_ENTER("mysqlnd_net::network_read_ex"); + DBG_ENTER("mysqlnd_vio::network_read"); DBG_INF_FMT("count="MYSQLND_SZ_T_SPEC, count); - net_stream->chunk_size = MIN(to_read, net->data->options.net_read_buffer_size); + net_stream->chunk_size = MIN(to_read, vio->data->options.net_read_buffer_size); while (to_read) { if (!(ret = php_stream_read(net_stream, (char *) p, to_read))) { DBG_ERR_FMT("Error while reading header from socket"); @@ -113,23 +113,23 @@ MYSQLND_METHOD(mysqlnd_net, network_read_ex)(MYSQLND_NET * const net, zend_uchar /* }}} */ -/* {{{ mysqlnd_net::network_write_ex */ +/* {{{ mysqlnd_vio::network_write */ static size_t -MYSQLND_METHOD(mysqlnd_net, network_write_ex)(MYSQLND_NET * const net, const zend_uchar * const buffer, const size_t count, +MYSQLND_METHOD(mysqlnd_vio, network_write)(MYSQLND_VIO * const vio, const zend_uchar * const buffer, const size_t count, MYSQLND_STATS * const stats, MYSQLND_ERROR_INFO * const error_info) { size_t ret; - DBG_ENTER("mysqlnd_net::network_write_ex"); + DBG_ENTER("mysqlnd_vio::network_write"); DBG_INF_FMT("sending %u bytes", count); - ret = php_stream_write(net->data->m.get_stream(net), (char *)buffer, count); + ret = php_stream_write(vio->data->m.get_stream(vio), (char *)buffer, count); DBG_RETURN(ret); } /* }}} */ -/* {{{ mysqlnd_net::open_pipe */ +/* {{{ mysqlnd_vio::open_pipe */ static php_stream * -MYSQLND_METHOD(mysqlnd_net, open_pipe)(MYSQLND_NET * const net, const MYSQLND_CSTRING scheme, const zend_bool persistent, +MYSQLND_METHOD(mysqlnd_vio, open_pipe)(MYSQLND_VIO * const vio, const MYSQLND_CSTRING scheme, const zend_bool persistent, MYSQLND_STATS * const conn_stats, MYSQLND_ERROR_INFO * const error_info) { #if PHP_API_VERSION < 20100412 @@ -140,7 +140,7 @@ MYSQLND_METHOD(mysqlnd_net, open_pipe)(MYSQLND_NET * const net, const MYSQLND_CS dtor_func_t origin_dtor; php_stream * net_stream = NULL; - DBG_ENTER("mysqlnd_net::open_pipe"); + DBG_ENTER("mysqlnd_vio::open_pipe"); if (persistent) { streams_options |= STREAM_OPEN_PERSISTENT; } @@ -166,9 +166,9 @@ MYSQLND_METHOD(mysqlnd_net, open_pipe)(MYSQLND_NET * const net, const MYSQLND_CS /* }}} */ -/* {{{ mysqlnd_net::open_tcp_or_unix */ +/* {{{ mysqlnd_vio::open_tcp_or_unix */ static php_stream * -MYSQLND_METHOD(mysqlnd_net, open_tcp_or_unix)(MYSQLND_NET * const net, const MYSQLND_CSTRING scheme, const zend_bool persistent, +MYSQLND_METHOD(mysqlnd_vio, open_tcp_or_unix)(MYSQLND_VIO * const vio, const MYSQLND_CSTRING scheme, const zend_bool persistent, MYSQLND_STATS * const conn_stats, MYSQLND_ERROR_INFO * const error_info) { #if PHP_API_VERSION < 20100412 @@ -185,23 +185,23 @@ MYSQLND_METHOD(mysqlnd_net, open_tcp_or_unix)(MYSQLND_NET * const net, const MYS dtor_func_t origin_dtor; php_stream * net_stream = NULL; - DBG_ENTER("mysqlnd_net::open_tcp_or_unix"); + DBG_ENTER("mysqlnd_vio::open_tcp_or_unix"); - net->data->stream = NULL; + vio->data->stream = NULL; if (persistent) { - hashed_details_len = mnd_sprintf(&hashed_details, 0, "%p", net); + hashed_details_len = mnd_sprintf(&hashed_details, 0, "%p", vio); DBG_INF_FMT("hashed_details=%s", hashed_details); } - if (net->data->options.timeout_connect) { - tv.tv_sec = net->data->options.timeout_connect; + if (vio->data->options.timeout_connect) { + tv.tv_sec = vio->data->options.timeout_connect; tv.tv_usec = 0; } DBG_INF_FMT("calling php_stream_xport_create"); net_stream = php_stream_xport_create(scheme.s, scheme.l, streams_options, streams_flags, - hashed_details, (net->data->options.timeout_connect) ? &tv : NULL, + hashed_details, (vio->data->options.timeout_connect) ? &tv : NULL, NULL /*ctx*/, &errstr, &errcode); if (errstr || !net_stream) { DBG_ERR("Error"); @@ -261,18 +261,18 @@ MYSQLND_METHOD(mysqlnd_net, open_tcp_or_unix)(MYSQLND_NET * const net, const MYS /* }}} */ -/* {{{ mysqlnd_net::post_connect_set_opt */ +/* {{{ mysqlnd_vio::post_connect_set_opt */ static void -MYSQLND_METHOD(mysqlnd_net, post_connect_set_opt)(MYSQLND_NET * const net, const MYSQLND_CSTRING scheme, +MYSQLND_METHOD(mysqlnd_vio, post_connect_set_opt)(MYSQLND_VIO * const vio, const MYSQLND_CSTRING scheme, MYSQLND_STATS * const conn_stats, MYSQLND_ERROR_INFO * const error_info) { - php_stream * net_stream = net->data->m.get_stream(net); - DBG_ENTER("mysqlnd_net::post_connect_set_opt"); + php_stream * net_stream = vio->data->m.get_stream(vio); + DBG_ENTER("mysqlnd_vio::post_connect_set_opt"); if (net_stream) { - if (net->data->options.timeout_read) { + if (vio->data->options.timeout_read) { struct timeval tv; - DBG_INF_FMT("setting %u as PHP_STREAM_OPTION_READ_TIMEOUT", net->data->options.timeout_read); - tv.tv_sec = net->data->options.timeout_read; + DBG_INF_FMT("setting %u as PHP_STREAM_OPTION_READ_TIMEOUT", vio->data->options.timeout_read); + tv.tv_sec = vio->data->options.timeout_read; tv.tv_usec = 0; php_stream_set_option(net_stream, PHP_STREAM_OPTION_READ_TIMEOUT, 0, &tv); } @@ -290,20 +290,20 @@ MYSQLND_METHOD(mysqlnd_net, post_connect_set_opt)(MYSQLND_NET * const net, const /* }}} */ -/* {{{ mysqlnd_net::get_open_stream */ -static func_mysqlnd_net__open_stream -MYSQLND_METHOD(mysqlnd_net, get_open_stream)(MYSQLND_NET * const net, const MYSQLND_CSTRING scheme, +/* {{{ mysqlnd_vio::get_open_stream */ +static func_mysqlnd_vio__open_stream +MYSQLND_METHOD(mysqlnd_vio, get_open_stream)(MYSQLND_VIO * const vio, const MYSQLND_CSTRING scheme, MYSQLND_ERROR_INFO * const error_info) { - func_mysqlnd_net__open_stream ret = NULL; - DBG_ENTER("mysqlnd_net::get_open_stream"); + func_mysqlnd_vio__open_stream ret = NULL; + DBG_ENTER("mysqlnd_vio::get_open_stream"); if (scheme.l > (sizeof("pipe://") - 1) && !memcmp(scheme.s, "pipe://", sizeof("pipe://") - 1)) { - ret = net->data->m.open_pipe; + ret = vio->data->m.open_pipe; } else if ((scheme.l > (sizeof("tcp://") - 1) && !memcmp(scheme.s, "tcp://", sizeof("tcp://") - 1)) || (scheme.l > (sizeof("unix://") - 1) && !memcmp(scheme.s, "unix://", sizeof("unix://") - 1))) { - ret = net->data->m.open_tcp_or_unix; + ret = vio->data->m.open_tcp_or_unix; } if (!ret) { @@ -315,25 +315,35 @@ MYSQLND_METHOD(mysqlnd_net, get_open_stream)(MYSQLND_NET * const net, const MYSQ /* }}} */ -/* {{{ mysqlnd_net::connect_ex */ +/* {{{ mysqlnd_net::connect */ static enum_func_status -MYSQLND_METHOD(mysqlnd_net, connect_ex)(MYSQLND_NET * const net, const MYSQLND_CSTRING scheme, const zend_bool persistent, - MYSQLND_STATS * const conn_stats, MYSQLND_ERROR_INFO * const error_info) +MYSQLND_METHOD(mysqlnd_net, connect)(MYSQLND_NET * const net, const MYSQLND_CSTRING scheme, const zend_bool persistent, + MYSQLND_STATS * const conn_stats, MYSQLND_ERROR_INFO * const error_info) { - enum_func_status ret = FAIL; - func_mysqlnd_net__open_stream open_stream = NULL; - DBG_ENTER("mysqlnd_net::connect_ex"); - + DBG_ENTER("mysqlnd_net::connect"); net->packet_no = net->compressed_envelope_packet_no = 0; + DBG_RETURN(PASS); +} +/* }}} */ - net->data->m.close_stream(net, conn_stats, error_info); - open_stream = net->data->m.get_open_stream(net, scheme, error_info); +/* {{{ mysqlnd_vio::connect */ +static enum_func_status +MYSQLND_METHOD(mysqlnd_vio, connect)(MYSQLND_VIO * const vio, const MYSQLND_CSTRING scheme, const zend_bool persistent, + MYSQLND_STATS * const conn_stats, MYSQLND_ERROR_INFO * const error_info) +{ + enum_func_status ret = FAIL; + func_mysqlnd_vio__open_stream open_stream = NULL; + DBG_ENTER("mysqlnd_vio::connect"); + + vio->data->m.close_stream(vio, conn_stats, error_info); + + open_stream = vio->data->m.get_open_stream(vio, scheme, error_info); if (open_stream) { - php_stream * net_stream = open_stream(net, scheme, persistent, conn_stats, error_info); + php_stream * net_stream = open_stream(vio, scheme, persistent, conn_stats, error_info); if (net_stream) { - (void) net->data->m.set_stream(net, net_stream); - net->data->m.post_connect_set_opt(net, scheme, conn_stats, error_info); + (void) vio->data->m.set_stream(vio, net_stream); + vio->data->m.post_connect_set_opt(vio, scheme, conn_stats, error_info); ret = PASS; } } @@ -353,7 +363,7 @@ MYSQLND_METHOD(mysqlnd_net, connect_ex)(MYSQLND_NET * const net, const MYSQLND_C #define RESTORE_HEADER_SIZE(buffer, safe_storage) STORE_HEADER_SIZE((safe_storage), (buffer)) -/* {{{ mysqlnd_net::send_ex */ +/* {{{ mysqlnd_net::send */ /* IMPORTANT : It's expected that buffer has place in the beginning for MYSQLND_HEADER_SIZE !!!! This is done for performance reasons in the caller of this function. @@ -365,8 +375,8 @@ MYSQLND_METHOD(mysqlnd_net, connect_ex)(MYSQLND_NET * const net, const MYSQLND_C count + MYSQLND_HEADER_SIZE = sizeof(buffer) (not the pointer but the actual buffer) */ static size_t -MYSQLND_METHOD(mysqlnd_net, send_ex)(MYSQLND_NET * const net, zend_uchar * const buffer, const size_t count, - MYSQLND_STATS * const conn_stats, MYSQLND_ERROR_INFO * const error_info) +MYSQLND_METHOD(mysqlnd_net, send)(MYSQLND_NET * const net, MYSQLND_VIO * const vio, zend_uchar * const buffer, const size_t count, + MYSQLND_STATS * const conn_stats, MYSQLND_ERROR_INFO * const error_info) { zend_uchar safe_buf[((MYSQLND_HEADER_SIZE) + (sizeof(zend_uchar)) - 1) / (sizeof(zend_uchar))]; zend_uchar * safe_storage = safe_buf; @@ -376,7 +386,7 @@ MYSQLND_METHOD(mysqlnd_net, send_ex)(MYSQLND_NET * const net, zend_uchar * const zend_uchar * compress_buf = NULL; size_t to_be_sent; - DBG_ENTER("mysqlnd_net::send_ex"); + DBG_ENTER("mysqlnd_net::send"); DBG_INF_FMT("count=" MYSQLND_SZ_T_SPEC " compression=%u", count, net->data->compressed); if (net->data->compressed == TRUE) { @@ -416,15 +426,14 @@ MYSQLND_METHOD(mysqlnd_net, send_ex)(MYSQLND_NET * const net, zend_uchar * const int3store(compress_buf, payload_size); int1store(compress_buf + 3, net->packet_no); DBG_INF_FMT("writing "MYSQLND_SZ_T_SPEC" bytes to the network", payload_size + MYSQLND_HEADER_SIZE + COMPRESSED_HEADER_SIZE); - bytes_sent = net->data->m.network_write_ex(net, compress_buf, payload_size + MYSQLND_HEADER_SIZE + COMPRESSED_HEADER_SIZE, - conn_stats, error_info); + bytes_sent = vio->data->m.network_write(vio, compress_buf, payload_size + MYSQLND_HEADER_SIZE + COMPRESSED_HEADER_SIZE, conn_stats, error_info); net->compressed_envelope_packet_no++; #if WHEN_WE_NEED_TO_CHECK_WHETHER_COMPRESSION_WORKS_CORRECTLY if (res == Z_OK) { size_t decompressed_size = left + MYSQLND_HEADER_SIZE; zend_uchar * decompressed_data = mnd_malloc(decompressed_size); int error = net->data->m.decode(decompressed_data, decompressed_size, - compress_buf + MYSQLND_HEADER_SIZE + COMPRESSED_HEADER_SIZE, payload_size); + compress_buf + MYSQLND_HEADER_SIZE + COMPRESSED_HEADER_SIZE, payload_size); if (error == Z_OK) { int i; DBG_INF("success decompressing"); @@ -448,7 +457,7 @@ MYSQLND_METHOD(mysqlnd_net, send_ex)(MYSQLND_NET * const net, zend_uchar * const STORE_HEADER_SIZE(safe_storage, p); int3store(p, to_be_sent); int1store(p + 3, net->packet_no); - bytes_sent = net->data->m.network_write_ex(net, p, to_be_sent + MYSQLND_HEADER_SIZE, conn_stats, error_info); + bytes_sent = vio->data->m.network_write(vio, p, to_be_sent + MYSQLND_HEADER_SIZE, conn_stats, error_info); RESTORE_HEADER_SIZE(p, safe_storage); net->compressed_envelope_packet_no++; } @@ -555,7 +564,7 @@ mysqlnd_create_read_buffer(size_t count) /* {{{ mysqlnd_net::read_compressed_packet_from_stream_and_fill_read_buffer */ static enum_func_status MYSQLND_METHOD(mysqlnd_net, read_compressed_packet_from_stream_and_fill_read_buffer) - (MYSQLND_NET * net, size_t net_payload_size, MYSQLND_STATS * conn_stats, MYSQLND_ERROR_INFO * error_info) + (MYSQLND_NET * net, MYSQLND_VIO * vio, size_t net_payload_size, MYSQLND_STATS * conn_stats, MYSQLND_ERROR_INFO * error_info) { size_t decompressed_size; enum_func_status retval = PASS; @@ -564,7 +573,7 @@ MYSQLND_METHOD(mysqlnd_net, read_compressed_packet_from_stream_and_fill_read_buf DBG_ENTER("mysqlnd_net::read_compressed_packet_from_stream_and_fill_read_buffer"); /* Read the compressed header */ - if (FAIL == net->data->m.network_read_ex(net, comp_header, COMPRESSED_HEADER_SIZE, conn_stats, error_info)) { + if (FAIL == vio->data->m.network_read(vio, comp_header, COMPRESSED_HEADER_SIZE, conn_stats, error_info)) { DBG_RETURN(FAIL); } decompressed_size = uint3korr(comp_header); @@ -574,7 +583,7 @@ MYSQLND_METHOD(mysqlnd_net, read_compressed_packet_from_stream_and_fill_read_buf if (decompressed_size) { compressed_data = mnd_emalloc(net_payload_size); - if (FAIL == net->data->m.network_read_ex(net, compressed_data, net_payload_size, conn_stats, error_info)) { + if (FAIL == vio->data->m.network_read(vio, compressed_data, net_payload_size, conn_stats, error_info)) { retval = FAIL; goto end; } @@ -586,7 +595,7 @@ MYSQLND_METHOD(mysqlnd_net, read_compressed_packet_from_stream_and_fill_read_buf } else { DBG_INF_FMT("The server decided not to compress the data. Our job is easy. Copying %u bytes", net_payload_size); net->uncompressed_data = mysqlnd_create_read_buffer(net_payload_size); - if (FAIL == net->data->m.network_read_ex(net, net->uncompressed_data->data, net_payload_size, conn_stats, error_info)) { + if (FAIL == vio->data->m.network_read(vio, net->uncompressed_data->data, net_payload_size, conn_stats, error_info)) { retval = FAIL; goto end; } @@ -652,15 +661,15 @@ MYSQLND_METHOD(mysqlnd_net, encode)(zend_uchar * compress_buffer, size_t * compr /* }}} */ -/* {{{ mysqlnd_net::receive_ex */ +/* {{{ mysqlnd_net::receive */ static enum_func_status -MYSQLND_METHOD(mysqlnd_net, receive_ex)(MYSQLND_NET * const net, zend_uchar * const buffer, const size_t count, - MYSQLND_STATS * const conn_stats, MYSQLND_ERROR_INFO * const error_info) +MYSQLND_METHOD(mysqlnd_net, receive)(MYSQLND_NET * const net, MYSQLND_VIO * const vio, zend_uchar * const buffer, const size_t count, + MYSQLND_STATS * const conn_stats, MYSQLND_ERROR_INFO * const error_info) { size_t to_read = count; zend_uchar * p = buffer; - DBG_ENTER("mysqlnd_net::receive_ex"); + DBG_ENTER("mysqlnd_net::receive"); #ifdef MYSQLND_COMPRESSION_ENABLED if (net->data->compressed) { if (net->uncompressed_data) { @@ -682,7 +691,7 @@ MYSQLND_METHOD(mysqlnd_net, receive_ex)(MYSQLND_NET * const net, zend_uchar * co size_t net_payload_size; zend_uchar packet_no; - if (FAIL == net->data->m.network_read_ex(net, net_header, MYSQLND_HEADER_SIZE, conn_stats, error_info)) { + if (FAIL == vio->data->m.network_read(vio, net_header, MYSQLND_HEADER_SIZE, conn_stats, error_info)) { DBG_RETURN(FAIL); } net_payload_size = uint3korr(net_header); @@ -700,7 +709,7 @@ MYSQLND_METHOD(mysqlnd_net, receive_ex)(MYSQLND_NET * const net, zend_uchar * co DBG_INF_FMT("HEADER: hwd_packet_no=%u size=%3u", packet_no, (zend_ulong) net_payload_size); #endif /* Now let's read from the wire, decompress it and fill the read buffer */ - net->data->m.read_compressed_packet_from_stream_and_fill_read_buffer(net, net_payload_size, conn_stats, error_info); + net->data->m.read_compressed_packet_from_stream_and_fill_read_buffer(net, vio, net_payload_size, conn_stats, error_info); /* Now a bit of recursion - read from the read buffer, @@ -708,12 +717,12 @@ MYSQLND_METHOD(mysqlnd_net, receive_ex)(MYSQLND_NET * const net, zend_uchar * co is not enough, then the recursive call will try to satisfy it until it is satisfied. */ - DBG_RETURN(net->data->m.receive_ex(net, p, to_read, conn_stats, error_info)); + DBG_RETURN(net->data->m.receive(net, vio, p, to_read, conn_stats, error_info)); } DBG_RETURN(PASS); } #endif /* MYSQLND_COMPRESSION_ENABLED */ - DBG_RETURN(net->data->m.network_read_ex(net, p, to_read, conn_stats, error_info)); + DBG_RETURN(vio->data->m.network_read(vio, p, to_read, conn_stats, error_info)); } /* }}} */ @@ -724,6 +733,33 @@ MYSQLND_METHOD(mysqlnd_net, set_client_option)(MYSQLND_NET * const net, enum_mys { DBG_ENTER("mysqlnd_net::set_client_option"); DBG_INF_FMT("option=%u", option); + switch (option) { + case MYSQL_OPT_COMPRESS: + net->data->options.flags |= MYSQLND_NET_FLAG_USE_COMPRESSION; + break; + case MYSQL_SERVER_PUBLIC_KEY: + { + zend_bool pers = net->persistent; + if (net->data->options.sha256_server_public_key) { + mnd_pefree(net->data->options.sha256_server_public_key, pers); + } + net->data->options.sha256_server_public_key = value? mnd_pestrdup(value, pers) : NULL; + break; + } + default: + DBG_RETURN(FAIL); + } + DBG_RETURN(PASS); +} +/* }}} */ + + +/* {{{ mysqlnd_vio::set_client_option */ +static enum_func_status +MYSQLND_METHOD(mysqlnd_vio, set_client_option)(MYSQLND_VIO * const net, enum_mysqlnd_client_option option, const char * const value) +{ + DBG_ENTER("mysqlnd_vio::set_client_option"); + DBG_INF_FMT("option=%u", option); switch (option) { case MYSQLND_OPT_NET_CMD_BUFFER_SIZE: DBG_INF("MYSQLND_OPT_NET_CMD_BUFFER_SIZE"); @@ -831,18 +867,6 @@ MYSQLND_METHOD(mysqlnd_net, set_client_option)(MYSQLND_NET * const net, enum_mys net->data->options.timeout_write = *(unsigned int*) value; break; #endif - case MYSQL_OPT_COMPRESS: - net->data->options.flags |= MYSQLND_NET_FLAG_USE_COMPRESSION; - break; - case MYSQL_SERVER_PUBLIC_KEY: - { - zend_bool pers = net->persistent; - if (net->data->options.sha256_server_public_key) { - mnd_pefree(net->data->options.sha256_server_public_key, pers); - } - net->data->options.sha256_server_public_key = value? mnd_pestrdup(value, pers) : NULL; - break; - } default: DBG_RETURN(FAIL); } @@ -850,9 +874,10 @@ MYSQLND_METHOD(mysqlnd_net, set_client_option)(MYSQLND_NET * const net, enum_mys } /* }}} */ -/* {{{ mysqlnd_net::consume_uneaten_data */ + +/* {{{ mysqlnd_vio::consume_uneaten_data */ size_t -MYSQLND_METHOD(mysqlnd_net, consume_uneaten_data)(MYSQLND_NET * const net, enum php_mysqlnd_server_command cmd) +MYSQLND_METHOD(mysqlnd_vio, consume_uneaten_data)(MYSQLND_VIO * const net, enum php_mysqlnd_server_command cmd) { #ifdef MYSQLND_DO_WIRE_CHECK_BEFORE_COMMAND /* @@ -883,7 +908,7 @@ MYSQLND_METHOD(mysqlnd_net, consume_uneaten_data)(MYSQLND_NET * const net, enum } if (bytes_consumed) { - DBG_ERR_FMT("Skipped %u bytes. Last command %s hasn't consumed all the output from the server", + DBG_ERR_FMT("Skipped %u bytes. Last command hasn't consumed all the output from the server", bytes_consumed, mysqlnd_command_to_text[net->last_command]); php_error_docref(NULL, E_WARNING, "Skipped %u bytes. Last command %s hasn't " "consumed all the output from the server", @@ -902,16 +927,16 @@ MYSQLND_METHOD(mysqlnd_net, consume_uneaten_data)(MYSQLND_NET * const net, enum /* in libmyusql, if cert and !key then key=cert */ -/* {{{ mysqlnd_net::enable_ssl */ +/* {{{ mysqlnd_vio::enable_ssl */ static enum_func_status -MYSQLND_METHOD(mysqlnd_net, enable_ssl)(MYSQLND_NET * const net) +MYSQLND_METHOD(mysqlnd_vio, enable_ssl)(MYSQLND_VIO * const net) { #ifdef MYSQLND_SSL_SUPPORTED php_stream_context * context = php_stream_context_alloc(); php_stream * net_stream = net->data->m.get_stream(net); zend_bool any_flag = FALSE; - DBG_ENTER("mysqlnd_net::enable_ssl"); + DBG_ENTER("mysqlnd_vio::enable_ssl"); if (!context) { DBG_RETURN(FAIL); } @@ -1011,7 +1036,7 @@ MYSQLND_METHOD(mysqlnd_net, enable_ssl)(MYSQLND_NET * const net) DBG_RETURN(PASS); #else - DBG_ENTER("mysqlnd_net::enable_ssl"); + DBG_ENTER("mysqlnd_vio::enable_ssl"); DBG_INF("MYSQLND_SSL_SUPPORTED is not defined"); DBG_RETURN(PASS); #endif @@ -1019,9 +1044,9 @@ MYSQLND_METHOD(mysqlnd_net, enable_ssl)(MYSQLND_NET * const net) /* }}} */ -/* {{{ mysqlnd_net::disable_ssl */ +/* {{{ mysqlnd_vio::disable_ssl */ static enum_func_status -MYSQLND_METHOD(mysqlnd_net, disable_ssl)(MYSQLND_NET * const net) +MYSQLND_METHOD(mysqlnd_vio, disable_ssl)(MYSQLND_VIO * const vio) { DBG_ENTER("mysqlnd_net::disable_ssl"); DBG_RETURN(PASS); @@ -1041,6 +1066,23 @@ MYSQLND_METHOD(mysqlnd_net, free_contents)(MYSQLND_NET * net) net->uncompressed_data->free_buffer(&net->uncompressed_data); } #endif + if (net->data->options.sha256_server_public_key) { + mnd_pefree(net->data->options.sha256_server_public_key, pers); + net->data->options.sha256_server_public_key = NULL; + } + + DBG_VOID_RETURN; +} +/* }}} */ + + +/* {{{ mysqlnd_vio::free_contents */ +static void +MYSQLND_METHOD(mysqlnd_vio, free_contents)(MYSQLND_VIO * net) +{ + zend_bool pers = net->persistent; + DBG_ENTER("mysqlnd_vio::free_contents"); + if (net->data->options.ssl_key) { mnd_pefree(net->data->options.ssl_key, pers); net->data->options.ssl_key = NULL; @@ -1061,22 +1103,18 @@ MYSQLND_METHOD(mysqlnd_net, free_contents)(MYSQLND_NET * net) mnd_pefree(net->data->options.ssl_cipher, pers); net->data->options.ssl_cipher = NULL; } - if (net->data->options.sha256_server_public_key) { - mnd_pefree(net->data->options.sha256_server_public_key, pers); - net->data->options.sha256_server_public_key = NULL; - } DBG_VOID_RETURN; } /* }}} */ -/* {{{ mysqlnd_net::close_stream */ +/* {{{ mysqlnd_vio::close_stream */ static void -MYSQLND_METHOD(mysqlnd_net, close_stream)(MYSQLND_NET * const net, MYSQLND_STATS * const stats, MYSQLND_ERROR_INFO * const error_info) +MYSQLND_METHOD(mysqlnd_vio, close_stream)(MYSQLND_VIO * const net, MYSQLND_STATS * const stats, MYSQLND_ERROR_INFO * const error_info) { php_stream * net_stream; - DBG_ENTER("mysqlnd_net::close_stream"); + DBG_ENTER("mysqlnd_vio::close_stream"); if (net && (net_stream = net->data->m.get_stream(net))) { zend_bool pers = net->persistent; DBG_INF_FMT("Freeing stream. abstract=%p", net_stream->abstract); @@ -1104,9 +1142,18 @@ MYSQLND_METHOD(mysqlnd_net, close_stream)(MYSQLND_NET * const net, MYSQLND_STATS /* {{{ mysqlnd_net::init */ static enum_func_status MYSQLND_METHOD(mysqlnd_net, init)(MYSQLND_NET * const net, MYSQLND_STATS * const stats, MYSQLND_ERROR_INFO * const error_info) +{ + return PASS; +} +/* }}} */ + + +/* {{{ mysqlnd_vio::init */ +static enum_func_status +MYSQLND_METHOD(mysqlnd_vio, init)(MYSQLND_VIO * const net, MYSQLND_STATS * const stats, MYSQLND_ERROR_INFO * const error_info) { unsigned int buf_size; - DBG_ENTER("mysqlnd_net::init"); + DBG_ENTER("mysqlnd_vio::init"); buf_size = MYSQLND_G(net_cmd_buffer_size); /* this is long, cast to unsigned int*/ net->data->m.set_client_option(net, MYSQLND_OPT_NET_CMD_BUFFER_SIZE, (char *) &buf_size); @@ -1129,39 +1176,55 @@ MYSQLND_METHOD(mysqlnd_net, dtor)(MYSQLND_NET * const net, MYSQLND_STATS * const DBG_ENTER("mysqlnd_net::dtor"); if (net) { net->data->m.free_contents(net); - net->data->m.close_stream(net, stats, error_info); - if (net->cmd_buffer.buffer) { + mnd_pefree(net->data, net->data->persistent); + mnd_pefree(net, net->persistent); + } + DBG_VOID_RETURN; +} +/* }}} */ + + +/* {{{ mysqlnd_vio::dtor */ +static void +MYSQLND_METHOD(mysqlnd_vio, dtor)(MYSQLND_VIO * const vio, MYSQLND_STATS * const stats, MYSQLND_ERROR_INFO * const error_info) +{ + DBG_ENTER("mysqlnd_vio::dtor"); + if (vio) { + vio->data->m.free_contents(vio); + vio->data->m.close_stream(vio, stats, error_info); + + if (vio->cmd_buffer.buffer) { DBG_INF("Freeing cmd buffer"); - mnd_pefree(net->cmd_buffer.buffer, net->persistent); - net->cmd_buffer.buffer = NULL; + mnd_pefree(vio->cmd_buffer.buffer, vio->persistent); + vio->cmd_buffer.buffer = NULL; } - mnd_pefree(net->data, net->data->persistent); - mnd_pefree(net, net->persistent); + mnd_pefree(vio->data, vio->data->persistent); + mnd_pefree(vio, vio->persistent); } DBG_VOID_RETURN; } /* }}} */ -/* {{{ mysqlnd_net::get_stream */ +/* {{{ mysqlnd_vio::get_stream */ static php_stream * -MYSQLND_METHOD(mysqlnd_net, get_stream)(const MYSQLND_NET * const net) +MYSQLND_METHOD(mysqlnd_vio, get_stream)(const MYSQLND_VIO * const net) { - DBG_ENTER("mysqlnd_net::get_stream"); + DBG_ENTER("mysqlnd_vio::get_stream"); DBG_INF_FMT("%p", net? net->data->stream:NULL); DBG_RETURN(net? net->data->stream:NULL); } /* }}} */ -/* {{{ mysqlnd_net::set_stream */ +/* {{{ mysqlnd_vio::set_stream */ static php_stream * -MYSQLND_METHOD(mysqlnd_net, set_stream)(MYSQLND_NET * const net, php_stream * net_stream) +MYSQLND_METHOD(mysqlnd_vio, set_stream)(MYSQLND_VIO * const net, php_stream * net_stream) { php_stream * ret = NULL; - DBG_ENTER("mysqlnd_net::set_stream"); + DBG_ENTER("mysqlnd_vio::set_stream"); if (net) { net->data->stream = net_stream; ret = net->data->stream; @@ -1174,35 +1237,52 @@ MYSQLND_METHOD(mysqlnd_net, set_stream)(MYSQLND_NET * const net, php_stream * ne MYSQLND_CLASS_METHODS_START(mysqlnd_net) MYSQLND_METHOD(mysqlnd_net, init), MYSQLND_METHOD(mysqlnd_net, dtor), - MYSQLND_METHOD(mysqlnd_net, connect_ex), - MYSQLND_METHOD(mysqlnd_net, close_stream), - MYSQLND_METHOD(mysqlnd_net, open_pipe), - MYSQLND_METHOD(mysqlnd_net, open_tcp_or_unix), - MYSQLND_METHOD(mysqlnd_net, get_stream), - MYSQLND_METHOD(mysqlnd_net, set_stream), - MYSQLND_METHOD(mysqlnd_net, get_open_stream), - MYSQLND_METHOD(mysqlnd_net, post_connect_set_opt), + MYSQLND_METHOD(mysqlnd_net, connect), + MYSQLND_METHOD(mysqlnd_net, set_client_option), + MYSQLND_METHOD(mysqlnd_net, decode), MYSQLND_METHOD(mysqlnd_net, encode), - MYSQLND_METHOD(mysqlnd_net, consume_uneaten_data), - MYSQLND_METHOD(mysqlnd_net, free_contents), - MYSQLND_METHOD(mysqlnd_net, enable_ssl), - MYSQLND_METHOD(mysqlnd_net, disable_ssl), - MYSQLND_METHOD(mysqlnd_net, network_read_ex), - MYSQLND_METHOD(mysqlnd_net, network_write_ex), - MYSQLND_METHOD(mysqlnd_net, send_ex), - MYSQLND_METHOD(mysqlnd_net, receive_ex), + + MYSQLND_METHOD(mysqlnd_net, send), + MYSQLND_METHOD(mysqlnd_net, receive), + #ifdef MYSQLND_COMPRESSION_ENABLED MYSQLND_METHOD(mysqlnd_net, read_compressed_packet_from_stream_and_fill_read_buffer), #else NULL, #endif - NULL, /* unused 1 */ - NULL, /* unused 2 */ - NULL, /* unused 3 */ - NULL, /* unused 4 */ - NULL /* unused 5 */ + + MYSQLND_METHOD(mysqlnd_net, free_contents), +MYSQLND_CLASS_METHODS_END; + + +MYSQLND_CLASS_METHODS_START(mysqlnd_vio) + MYSQLND_METHOD(mysqlnd_vio, init), + MYSQLND_METHOD(mysqlnd_vio, dtor), + + MYSQLND_METHOD(mysqlnd_vio, connect), + + MYSQLND_METHOD(mysqlnd_vio, close_stream), + MYSQLND_METHOD(mysqlnd_vio, open_pipe), + MYSQLND_METHOD(mysqlnd_vio, open_tcp_or_unix), + + MYSQLND_METHOD(mysqlnd_vio, get_stream), + MYSQLND_METHOD(mysqlnd_vio, set_stream), + MYSQLND_METHOD(mysqlnd_vio, get_open_stream), + + MYSQLND_METHOD(mysqlnd_vio, set_client_option), + MYSQLND_METHOD(mysqlnd_vio, post_connect_set_opt), + + MYSQLND_METHOD(mysqlnd_vio, enable_ssl), + MYSQLND_METHOD(mysqlnd_vio, disable_ssl), + + MYSQLND_METHOD(mysqlnd_vio, network_read), + MYSQLND_METHOD(mysqlnd_vio, network_write), + + MYSQLND_METHOD(mysqlnd_vio, consume_uneaten_data), + + MYSQLND_METHOD(mysqlnd_vio, free_contents), MYSQLND_CLASS_METHODS_END; @@ -1212,7 +1292,7 @@ mysqlnd_net_init(zend_bool persistent, MYSQLND_STATS * stats, MYSQLND_ERROR_INFO { MYSQLND_NET * net; DBG_ENTER("mysqlnd_net_init"); - net = MYSQLND_CLASS_METHOD_TABLE_NAME(mysqlnd_object_factory).get_io_channel(persistent, stats, error_info); + net = MYSQLND_CLASS_METHOD_TABLE_NAME(mysqlnd_object_factory).get_net(persistent, stats, error_info); DBG_RETURN(net); } /* }}} */ @@ -1231,6 +1311,30 @@ mysqlnd_net_free(MYSQLND_NET * const net, MYSQLND_STATS * stats, MYSQLND_ERROR_I /* }}} */ +/* {{{ mysqlnd_vio_init */ +PHPAPI MYSQLND_VIO * +mysqlnd_vio_init(zend_bool persistent, MYSQLND_STATS * stats, MYSQLND_ERROR_INFO * error_info) +{ + MYSQLND_VIO * vio; + DBG_ENTER("mysqlnd_vio_init"); + vio = MYSQLND_CLASS_METHOD_TABLE_NAME(mysqlnd_object_factory).get_vio(persistent, stats, error_info); + DBG_RETURN(vio); +} +/* }}} */ + + +/* {{{ mysqlnd_vio_free */ +PHPAPI void +mysqlnd_vio_free(MYSQLND_VIO * const vio, MYSQLND_STATS * stats, MYSQLND_ERROR_INFO * error_info) +{ + DBG_ENTER("mysqlnd_vio_free"); + if (vio) { + vio->data->m.dtor(vio, stats, error_info); + } + DBG_VOID_RETURN; +} +/* }}} */ + /* * Local variables: diff --git a/ext/mysqlnd/mysqlnd_net.h b/ext/mysqlnd/mysqlnd_net.h index d863753a86..3c7e3cb6a1 100644 --- a/ext/mysqlnd/mysqlnd_net.h +++ b/ext/mysqlnd/mysqlnd_net.h @@ -26,6 +26,9 @@ PHPAPI MYSQLND_NET * mysqlnd_net_init(zend_bool persistent, MYSQLND_STATS * stats, MYSQLND_ERROR_INFO * error_info); PHPAPI void mysqlnd_net_free(MYSQLND_NET * const net, MYSQLND_STATS * stats, MYSQLND_ERROR_INFO * error_info); +PHPAPI MYSQLND_VIO * mysqlnd_vio_init(zend_bool persistent, MYSQLND_STATS * stats, MYSQLND_ERROR_INFO * error_info); +PHPAPI void mysqlnd_vio_free(MYSQLND_VIO * const vio, MYSQLND_STATS * stats, MYSQLND_ERROR_INFO * error_info); + #endif /* MYSQLND_NET_H */ /* diff --git a/ext/mysqlnd/mysqlnd_priv.h b/ext/mysqlnd/mysqlnd_priv.h index a0a061f4ee..fbd433dfda 100644 --- a/ext/mysqlnd/mysqlnd_priv.h +++ b/ext/mysqlnd/mysqlnd_priv.h @@ -155,6 +155,7 @@ PHPAPI extern MYSQLND_CLASS_METHOD_TABLE_NAME_FORWARD(mysqlnd_result_unbuffered) PHPAPI extern MYSQLND_CLASS_METHOD_TABLE_NAME_FORWARD(mysqlnd_result_buffered); PHPAPI extern MYSQLND_CLASS_METHOD_TABLE_NAME_FORWARD(mysqlnd_protocol_payload_decoder_factory); PHPAPI extern MYSQLND_CLASS_METHOD_TABLE_NAME_FORWARD(mysqlnd_net); +PHPAPI extern MYSQLND_CLASS_METHOD_TABLE_NAME_FORWARD(mysqlnd_vio); PHPAPI extern MYSQLND_CLASS_METHOD_TABLE_NAME_FORWARD(mysqlnd_upsert_status); PHPAPI extern MYSQLND_CLASS_METHOD_TABLE_NAME_FORWARD(mysqlnd_error_info); diff --git a/ext/mysqlnd/mysqlnd_structs.h b/ext/mysqlnd/mysqlnd_structs.h index 502378f72f..ef4dc0e52d 100644 --- a/ext/mysqlnd/mysqlnd_structs.h +++ b/ext/mysqlnd/mysqlnd_structs.h @@ -234,7 +234,14 @@ typedef struct st_mysqlnd_session_options #endif } MYSQLND_SESSION_OPTIONS; -typedef struct st_mysqlnd_io_options +typedef struct st_mysqlnd_net_options +{ + uint64_t flags; + + char * sha256_server_public_key; +} MYSQLND_NET_OPTIONS; + +typedef struct st_mysqlnd_vio_options { /* timeouts */ unsigned int timeout_connect; @@ -257,17 +264,16 @@ typedef struct st_mysqlnd_io_options #define MYSQLND_SSL_PEER_DEFAULT_ACTION MYSQLND_SSL_PEER_VERIFY } ssl_verify_peer; - uint64_t flags; - - char * sha256_server_public_key; -} MYSQLND_IO_OPTIONS; +} MYSQLND_VIO_OPTIONS; typedef struct st_mysqlnd_connection MYSQLND; typedef struct st_mysqlnd_connection_data MYSQLND_CONN_DATA; -typedef struct st_mysqlnd_net MYSQLND_NET; +typedef struct st_mysqlnd_net MYSQLND_NET; typedef struct st_mysqlnd_net_data MYSQLND_NET_DATA; +typedef struct st_mysqlnd_vio MYSQLND_VIO; +typedef struct st_mysqlnd_vio_data MYSQLND_VIO_DATA; typedef struct st_mysqlnd_protocol_payload_decoder_factory MYSQLND_PROTOCOL_PAYLOAD_DECODER_FACTORY; typedef struct st_mysqlnd_res MYSQLND_RES; typedef char** MYSQLND_ROW_C; /* return data as array of strings */ @@ -325,63 +331,86 @@ typedef struct st_mysqlnd_read_buffer { +typedef enum_func_status (*func_mysqlnd_net__init)(MYSQLND_NET * const net, MYSQLND_STATS * const stats, MYSQLND_ERROR_INFO * const error_info); +typedef void (*func_mysqlnd_net__dtor)(MYSQLND_NET * const net, MYSQLND_STATS * const conn_stats, MYSQLND_ERROR_INFO * const error_info); +typedef enum_func_status (*func_mysqlnd_net__connect)(MYSQLND_NET * const net, const MYSQLND_CSTRING scheme, const zend_bool persistent, MYSQLND_STATS * const conn_stats, MYSQLND_ERROR_INFO * const error_info); typedef enum_func_status (*func_mysqlnd_net__set_client_option)(MYSQLND_NET * const net, enum_mysqlnd_client_option option, const char * const value); typedef enum_func_status (*func_mysqlnd_net__decode)(zend_uchar * uncompressed_data, const size_t uncompressed_data_len, const zend_uchar * const compressed_data, const size_t compressed_data_len); typedef enum_func_status (*func_mysqlnd_net__encode)(zend_uchar * compress_buffer, size_t * compress_buffer_len, const zend_uchar * const uncompressed_data, const size_t uncompressed_data_len); -typedef size_t (*func_mysqlnd_net__consume_uneaten_data)(MYSQLND_NET * const net, enum php_mysqlnd_server_command cmd); +typedef size_t (*func_mysqlnd_net__send)(MYSQLND_NET * const net, MYSQLND_VIO * const vio, zend_uchar * const buffer, const size_t count, MYSQLND_STATS * const conn_stats, MYSQLND_ERROR_INFO * const error_info); +typedef enum_func_status (*func_mysqlnd_net__receive)(MYSQLND_NET * const net, MYSQLND_VIO * const vio, zend_uchar * const buffer, const size_t count, MYSQLND_STATS * const conn_stats, MYSQLND_ERROR_INFO * const error_info); +typedef enum_func_status (*func_mysqlnd_net__read_compressed_packet_from_stream_and_fill_read_buffer)(MYSQLND_NET * net, MYSQLND_VIO * const vio, size_t net_payload_size, MYSQLND_STATS * conn_stats, MYSQLND_ERROR_INFO * error_info); typedef void (*func_mysqlnd_net__free_contents)(MYSQLND_NET * net); -typedef enum_func_status (*func_mysqlnd_net__enable_ssl)(MYSQLND_NET * const net); -typedef enum_func_status (*func_mysqlnd_net__disable_ssl)(MYSQLND_NET * const net); -typedef enum_func_status (*func_mysqlnd_net__network_read_ex)(MYSQLND_NET * const net, zend_uchar * const buffer, const size_t count, MYSQLND_STATS * const stats, MYSQLND_ERROR_INFO * const error_info); -typedef size_t (*func_mysqlnd_net__network_write_ex)(MYSQLND_NET * const net, const zend_uchar * const buf, const size_t count, MYSQLND_STATS * const stats, MYSQLND_ERROR_INFO * const error_info); -typedef size_t (*func_mysqlnd_net__send_ex)(MYSQLND_NET * const net, zend_uchar * const buffer, const size_t count, MYSQLND_STATS * const conn_stats, MYSQLND_ERROR_INFO * const error_info); -typedef enum_func_status (*func_mysqlnd_net__receive_ex)(MYSQLND_NET * const net, zend_uchar * const buffer, const size_t count, MYSQLND_STATS * const conn_stats, MYSQLND_ERROR_INFO * const error_info); -typedef enum_func_status (*func_mysqlnd_net__init)(MYSQLND_NET * const net, MYSQLND_STATS * const stats, MYSQLND_ERROR_INFO * const error_info); -typedef void (*func_mysqlnd_net__dtor)(MYSQLND_NET * const net, MYSQLND_STATS * const conn_stats, MYSQLND_ERROR_INFO * const error_info); -typedef enum_func_status (*func_mysqlnd_net__connect_ex)(MYSQLND_NET * const net, const MYSQLND_CSTRING scheme, const zend_bool persistent, MYSQLND_STATS * const conn_stats, MYSQLND_ERROR_INFO * const error_info); -typedef void (*func_mysqlnd_net__close_stream)(MYSQLND_NET * const net, MYSQLND_STATS * const conn_stats, MYSQLND_ERROR_INFO * const error_info); -typedef php_stream * (*func_mysqlnd_net__open_stream)(MYSQLND_NET * const net, const MYSQLND_CSTRING scheme, const zend_bool persistent, MYSQLND_STATS * const conn_stats, MYSQLND_ERROR_INFO * const error_info); -typedef php_stream * (*func_mysqlnd_net__get_stream)(const MYSQLND_NET * const net); -typedef php_stream * (*func_mysqlnd_net__set_stream)(MYSQLND_NET * const net, php_stream * net_stream); -typedef func_mysqlnd_net__open_stream (*func_mysqlnd_net__get_open_stream)(MYSQLND_NET * const net, const MYSQLND_CSTRING scheme, MYSQLND_ERROR_INFO * const error_info); -typedef void (*func_mysqlnd_net__post_connect_set_opt)(MYSQLND_NET * const net, const MYSQLND_CSTRING scheme, MYSQLND_STATS * const conn_stats, MYSQLND_ERROR_INFO * const error_info); -typedef enum_func_status (*func_mysqlnd_net__read_compressed_packet_from_stream_and_fill_read_buffer)(MYSQLND_NET * net, size_t net_payload_size, MYSQLND_STATS * conn_stats, MYSQLND_ERROR_INFO * error_info); MYSQLND_CLASS_METHODS_TYPE(mysqlnd_net) { func_mysqlnd_net__init init; func_mysqlnd_net__dtor dtor; - func_mysqlnd_net__connect_ex connect_ex; - func_mysqlnd_net__close_stream close_stream; - func_mysqlnd_net__open_stream open_pipe; - func_mysqlnd_net__open_stream open_tcp_or_unix; - - func_mysqlnd_net__get_stream get_stream; - func_mysqlnd_net__set_stream set_stream; - func_mysqlnd_net__get_open_stream get_open_stream; - - func_mysqlnd_net__post_connect_set_opt post_connect_set_opt; - + func_mysqlnd_net__connect connect; func_mysqlnd_net__set_client_option set_client_option; + func_mysqlnd_net__decode decode; func_mysqlnd_net__encode encode; - func_mysqlnd_net__consume_uneaten_data consume_uneaten_data; - func_mysqlnd_net__free_contents free_contents; - func_mysqlnd_net__enable_ssl enable_ssl; - func_mysqlnd_net__disable_ssl disable_ssl; - func_mysqlnd_net__network_read_ex network_read_ex; - func_mysqlnd_net__network_write_ex network_write_ex; - func_mysqlnd_net__send_ex send_ex; - func_mysqlnd_net__receive_ex receive_ex; + func_mysqlnd_net__send send; + func_mysqlnd_net__receive receive; func_mysqlnd_net__read_compressed_packet_from_stream_and_fill_read_buffer read_compressed_packet_from_stream_and_fill_read_buffer; - void * unused1; - void * unused2; - void * unused3; - void * unused4; - void * unused5; + func_mysqlnd_net__free_contents free_contents; +}; + + +typedef enum_func_status (*func_mysqlnd_vio__init)(MYSQLND_VIO * const vio, MYSQLND_STATS * const stats, MYSQLND_ERROR_INFO * const error_info); +typedef void (*func_mysqlnd_vio__dtor)(MYSQLND_VIO * const vio, MYSQLND_STATS * const conn_stats, MYSQLND_ERROR_INFO * const error_info); + +typedef enum_func_status (*func_mysqlnd_vio__connect)(MYSQLND_VIO * const vio, const MYSQLND_CSTRING scheme, const zend_bool persistent, MYSQLND_STATS * const conn_stats, MYSQLND_ERROR_INFO * const error_info); + +typedef void (*func_mysqlnd_vio__close_stream)(MYSQLND_VIO * const vio, MYSQLND_STATS * const conn_stats, MYSQLND_ERROR_INFO * const error_info); +typedef php_stream * (*func_mysqlnd_vio__open_stream)(MYSQLND_VIO * const vio, const MYSQLND_CSTRING scheme, const zend_bool persistent, MYSQLND_STATS * const conn_stats, MYSQLND_ERROR_INFO * const error_info); +typedef php_stream * (*func_mysqlnd_vio__get_stream)(const MYSQLND_VIO * const vio); +typedef php_stream * (*func_mysqlnd_vio__set_stream)(MYSQLND_VIO * const vio, php_stream * vio_stream); +typedef func_mysqlnd_vio__open_stream (*func_mysqlnd_vio__get_open_stream)(MYSQLND_VIO * const vio, const MYSQLND_CSTRING scheme, MYSQLND_ERROR_INFO * const error_info); + +typedef enum_func_status (*func_mysqlnd_vio__set_client_option)(MYSQLND_VIO * const vio, enum_mysqlnd_client_option option, const char * const value); +typedef void (*func_mysqlnd_vio__post_connect_set_opt)(MYSQLND_VIO * const vio, const MYSQLND_CSTRING scheme, MYSQLND_STATS * const conn_stats, MYSQLND_ERROR_INFO * const error_info); + +typedef enum_func_status (*func_mysqlnd_vio__enable_ssl)(MYSQLND_VIO * const vio); +typedef enum_func_status (*func_mysqlnd_vio__disable_ssl)(MYSQLND_VIO * const vio); +typedef enum_func_status (*func_mysqlnd_vio__network_read)(MYSQLND_VIO * const vio, zend_uchar * const buffer, const size_t count, MYSQLND_STATS * const stats, MYSQLND_ERROR_INFO * const error_info); +typedef size_t (*func_mysqlnd_vio__network_write)(MYSQLND_VIO * const vio, const zend_uchar * const buf, const size_t count, MYSQLND_STATS * const stats, MYSQLND_ERROR_INFO * const error_info); + +typedef size_t (*func_mysqlnd_vio__consume_uneaten_data)(MYSQLND_VIO * const vio, enum php_mysqlnd_server_command cmd); + +typedef void (*func_mysqlnd_vio__free_contents)(MYSQLND_VIO * vio); + + +MYSQLND_CLASS_METHODS_TYPE(mysqlnd_vio) +{ + func_mysqlnd_vio__init init; + func_mysqlnd_vio__dtor dtor; + func_mysqlnd_vio__connect connect; + + func_mysqlnd_vio__close_stream close_stream; + func_mysqlnd_vio__open_stream open_pipe; + func_mysqlnd_vio__open_stream open_tcp_or_unix; + + func_mysqlnd_vio__get_stream get_stream; + func_mysqlnd_vio__set_stream set_stream; + func_mysqlnd_vio__get_open_stream get_open_stream; + + func_mysqlnd_vio__set_client_option set_client_option; + func_mysqlnd_vio__post_connect_set_opt post_connect_set_opt; + + func_mysqlnd_vio__enable_ssl enable_ssl; + func_mysqlnd_vio__disable_ssl disable_ssl; + + func_mysqlnd_vio__network_read network_read; + func_mysqlnd_vio__network_write network_write; + + func_mysqlnd_vio__consume_uneaten_data consume_uneaten_data; + + func_mysqlnd_vio__free_contents free_contents; }; @@ -390,7 +419,8 @@ MYSQLND_CLASS_METHODS_TYPE(mysqlnd_object_factory); typedef MYSQLND * (*func_mysqlnd_object_factory__get_connection)(struct st_mysqlnd_object_factory_methods * factory, zend_bool persistent); typedef MYSQLND * (*func_mysqlnd_object_factory__clone_connection_object)(MYSQLND * conn); typedef MYSQLND_STMT * (*func_mysqlnd_object_factory__get_prepared_statement)(MYSQLND_CONN_DATA * conn, zend_bool persistent); -typedef MYSQLND_NET * (*func_mysqlnd_object_factory__get_io_channel)(zend_bool persistent, MYSQLND_STATS * stats, MYSQLND_ERROR_INFO * error_info); +typedef MYSQLND_NET * (*func_mysqlnd_object_factory__get_net)(zend_bool persistent, MYSQLND_STATS * stats, MYSQLND_ERROR_INFO * error_info); +typedef MYSQLND_VIO * (*func_mysqlnd_object_factory__get_vio)(zend_bool persistent, MYSQLND_STATS * stats, MYSQLND_ERROR_INFO * error_info); typedef MYSQLND_PROTOCOL_PAYLOAD_DECODER_FACTORY * (*func_mysqlnd_object_factory__get_protocol_payload_decoder_factory)(MYSQLND_CONN_DATA * conn, zend_bool persistent); @@ -399,7 +429,8 @@ MYSQLND_CLASS_METHODS_TYPE(mysqlnd_object_factory) func_mysqlnd_object_factory__get_connection get_connection; func_mysqlnd_object_factory__clone_connection_object clone_connection_object; func_mysqlnd_object_factory__get_prepared_statement get_prepared_statement; - func_mysqlnd_object_factory__get_io_channel get_io_channel; + func_mysqlnd_object_factory__get_net get_net; + func_mysqlnd_object_factory__get_vio get_vio; func_mysqlnd_object_factory__get_protocol_payload_decoder_factory get_protocol_payload_decoder_factory; }; @@ -841,12 +872,7 @@ struct st_mysqlnd_net_data php_stream *stream; zend_bool compressed; zend_bool ssl; -#ifdef MYSQLND_DO_WIRE_CHECK_BEFORE_COMMAND - zend_uchar last_command; -#else - zend_uchar unused_pad1; -#endif - MYSQLND_IO_OPTIONS options; + MYSQLND_NET_OPTIONS options; unsigned int refcount; @@ -859,7 +885,7 @@ struct st_mysqlnd_net_data struct st_mysqlnd_net { /* cmd buffer */ - MYSQLND_CMD_BUFFER cmd_buffer; +// MYSQLND_CMD_BUFFER cmd_buffer; struct st_mysqlnd_net_data * data; @@ -877,6 +903,35 @@ struct st_mysqlnd_net }; +struct st_mysqlnd_vio_data +{ + php_stream *stream; + zend_bool ssl; + MYSQLND_VIO_OPTIONS options; +#ifdef MYSQLND_DO_WIRE_CHECK_BEFORE_COMMAND + zend_uchar last_command; +#else + zend_uchar unused_pad1; +#endif + + zend_bool persistent; + + MYSQLND_CLASS_METHODS_TYPE(mysqlnd_vio) m; +}; + + +struct st_mysqlnd_vio +{ + /* cmd buffer */ + MYSQLND_CMD_BUFFER cmd_buffer; + + struct st_mysqlnd_vio_data * data; + + zend_bool persistent; +}; + + + struct st_mysqlnd_protocol_command { enum_func_status (*run)(void *cmd); @@ -909,6 +964,7 @@ struct st_mysqlnd_connection_data { /* Operation related */ MYSQLND_NET * net; + MYSQLND_VIO * vio; MYSQLND_PROTOCOL_PAYLOAD_DECODER_FACTORY * payload_decoder_factory; /* Information related */ @@ -1317,7 +1373,7 @@ typedef zend_uchar * (*func_auth_plugin__get_auth_data)(struct st_mysqlnd_authen MYSQLND_CONN_DATA * conn, const char * const user, const char * const passwd, const size_t passwd_len, zend_uchar * auth_plugin_data, size_t auth_plugin_data_len, const MYSQLND_SESSION_OPTIONS * const session_options, - const MYSQLND_IO_OPTIONS * const io_options, zend_ulong mysql_flags + const MYSQLND_NET_OPTIONS * const net_options, zend_ulong mysql_flags ); struct st_mysqlnd_authentication_plugin diff --git a/ext/mysqlnd/mysqlnd_wireprotocol.c b/ext/mysqlnd/mysqlnd_wireprotocol.c index be400654ac..e2fd68e5d3 100644 --- a/ext/mysqlnd/mysqlnd_wireprotocol.c +++ b/ext/mysqlnd/mysqlnd_wireprotocol.c @@ -245,14 +245,14 @@ end: /* {{{ mysqlnd_read_header */ static enum_func_status -mysqlnd_read_header(MYSQLND_NET * net, MYSQLND_PACKET_HEADER * header, +mysqlnd_read_header(MYSQLND_NET * net, MYSQLND_VIO * vio, MYSQLND_PACKET_HEADER * header, MYSQLND_STATS * conn_stats, MYSQLND_ERROR_INFO * error_info) { zend_uchar buffer[MYSQLND_HEADER_SIZE]; DBG_ENTER(mysqlnd_read_header_name); DBG_INF_FMT("compressed=%u", net->data->compressed); - if (FAIL == net->data->m.receive_ex(net, buffer, MYSQLND_HEADER_SIZE, conn_stats, error_info)) { + if (FAIL == net->data->m.receive(net, vio, buffer, MYSQLND_HEADER_SIZE, conn_stats, error_info)) { DBG_RETURN(FAIL); } @@ -290,6 +290,7 @@ mysqlnd_read_header(MYSQLND_NET * net, MYSQLND_PACKET_HEADER * header, static enum_func_status mysqlnd_read_packet_header_and_body(MYSQLND_PACKET_HEADER * packet_header, MYSQLND_NET * net, + MYSQLND_VIO * vio, MYSQLND_STATS * stats, MYSQLND_ERROR_INFO * error_info, MYSQLND_CONNECTION_STATE * connection_state, @@ -298,7 +299,7 @@ mysqlnd_read_packet_header_and_body(MYSQLND_PACKET_HEADER * packet_header, { DBG_ENTER("mysqlnd_read_packet_header_and_body"); DBG_INF_FMT("buf=%p size=%u", buf, buf_size); - if (FAIL == mysqlnd_read_header(net, packet_header, stats, error_info)) { + if (FAIL == mysqlnd_read_header(net, vio, packet_header, stats, error_info)) { SET_CONNECTION_STATE(connection_state, CONN_QUIT_SENT); SET_CLIENT_ERROR(error_info, CR_SERVER_GONE_ERROR, UNKNOWN_SQLSTATE, mysqlnd_server_gone); php_error_docref(NULL, E_WARNING, "%s", mysqlnd_server_gone); @@ -310,7 +311,7 @@ mysqlnd_read_packet_header_and_body(MYSQLND_PACKET_HEADER * packet_header, buf_size, packet_header->size, packet_header->size - buf_size); DBG_RETURN(FAIL); } - if (FAIL == net->data->m.receive_ex(net, buf, packet_header->size, stats, error_info)) { + if (FAIL == net->data->m.receive(net, vio, buf, packet_header->size, stats, error_info)) { SET_CONNECTION_STATE(connection_state, CONN_QUIT_SENT); SET_CLIENT_ERROR(error_info, CR_SERVER_GONE_ERROR, UNKNOWN_SQLSTATE, mysqlnd_server_gone); php_error_docref(NULL, E_WARNING, "%s", mysqlnd_server_gone); @@ -337,12 +338,13 @@ php_mysqlnd_greet_read(void * _packet) MYSQLND_PACKET_GREET *packet= (MYSQLND_PACKET_GREET *) _packet; MYSQLND_ERROR_INFO * error_info = packet->header.error_info; MYSQLND_NET * net = packet->header.net; + MYSQLND_VIO * vio = packet->header.vio; MYSQLND_STATS * stats = packet->header.stats; MYSQLND_CONNECTION_STATE * connection_state = packet->header.connection_state; DBG_ENTER("php_mysqlnd_greet_read"); - if (FAIL == mysqlnd_read_packet_header_and_body(&(packet->header), net, stats, error_info, connection_state, buf, sizeof(buf), "greeting", PROT_GREET_PACKET)) { + if (FAIL == mysqlnd_read_packet_header_and_body(&(packet->header), net, vio, stats, error_info, connection_state, buf, sizeof(buf), "greeting", PROT_GREET_PACKET)) { DBG_RETURN(FAIL); } BAIL_IF_NO_MORE_DATA; @@ -505,6 +507,7 @@ size_t php_mysqlnd_auth_write(void * _packet) MYSQLND_CONN_DATA * conn = packet->header.conn; MYSQLND_ERROR_INFO * error_info = packet->header.error_info; MYSQLND_NET * net = packet->header.net; + MYSQLND_VIO * vio = packet->header.vio; MYSQLND_STATS * stats = packet->header.stats; MYSQLND_CONNECTION_STATE * connection_state = packet->header.connection_state; @@ -635,7 +638,7 @@ size_t php_mysqlnd_auth_write(void * _packet) DBG_RETURN(ret == PASS? (p - buffer - MYSQLND_HEADER_SIZE) : 0); } else { - size_t sent = net->data->m.send_ex(net, buffer, p - buffer - MYSQLND_HEADER_SIZE, stats, error_info); + size_t sent = net->data->m.send(net, vio, buffer, p - buffer - MYSQLND_HEADER_SIZE, stats, error_info); if (!sent) { SET_CONNECTION_STATE(connection_state, CONN_QUIT_SENT); } @@ -666,11 +669,12 @@ php_mysqlnd_auth_response_read(void * _packet) register MYSQLND_PACKET_AUTH_RESPONSE * packet= (MYSQLND_PACKET_AUTH_RESPONSE *) _packet; MYSQLND_ERROR_INFO * error_info = packet->header.error_info; MYSQLND_NET * net = packet->header.net; + MYSQLND_VIO * vio = packet->header.vio; MYSQLND_STATS * stats = packet->header.stats; MYSQLND_CONNECTION_STATE * connection_state = packet->header.connection_state; zend_uchar local_buf[AUTH_RESP_BUFFER_SIZE]; - size_t buf_len = net->cmd_buffer.buffer? net->cmd_buffer.length: AUTH_RESP_BUFFER_SIZE; - zend_uchar *buf = net->cmd_buffer.buffer? (zend_uchar *) net->cmd_buffer.buffer : local_buf; + size_t buf_len = vio->cmd_buffer.buffer? vio->cmd_buffer.length: AUTH_RESP_BUFFER_SIZE; + zend_uchar *buf = vio->cmd_buffer.buffer? (zend_uchar *) vio->cmd_buffer.buffer : local_buf; zend_uchar *p = buf; zend_uchar *begin = buf; zend_ulong i; @@ -679,7 +683,7 @@ php_mysqlnd_auth_response_read(void * _packet) /* leave space for terminating safety \0 */ buf_len--; - if (FAIL == mysqlnd_read_packet_header_and_body(&(packet->header), net, stats, error_info, connection_state, buf, buf_len, "OK", PROT_OK_PACKET)) { + if (FAIL == mysqlnd_read_packet_header_and_body(&(packet->header), net, vio, stats, error_info, connection_state, buf, buf_len, "OK", PROT_OK_PACKET)) { DBG_RETURN(FAIL); } BAIL_IF_NO_MORE_DATA; @@ -792,9 +796,10 @@ php_mysqlnd_change_auth_response_write(void * _packet) MYSQLND_PACKET_CHANGE_AUTH_RESPONSE *packet= (MYSQLND_PACKET_CHANGE_AUTH_RESPONSE *) _packet; MYSQLND_ERROR_INFO * error_info = packet->header.error_info; MYSQLND_NET * net = packet->header.net; + MYSQLND_VIO * vio = packet->header.vio; MYSQLND_STATS * stats = packet->header.stats; MYSQLND_CONNECTION_STATE * connection_state = packet->header.connection_state; - zend_uchar * buffer = net->cmd_buffer.length >= packet->auth_data_len? net->cmd_buffer.buffer : mnd_emalloc(packet->auth_data_len); + zend_uchar * buffer = vio->cmd_buffer.length >= packet->auth_data_len? vio->cmd_buffer.buffer : mnd_emalloc(packet->auth_data_len); zend_uchar *p = buffer + MYSQLND_HEADER_SIZE; /* start after the header */ DBG_ENTER("php_mysqlnd_change_auth_response_write"); @@ -805,8 +810,8 @@ php_mysqlnd_change_auth_response_write(void * _packet) } { - size_t sent = net->data->m.send_ex(net, buffer, p - buffer - MYSQLND_HEADER_SIZE, stats, error_info); - if (buffer != net->cmd_buffer.buffer) { + size_t sent = net->data->m.send(net, vio, buffer, p - buffer - MYSQLND_HEADER_SIZE, stats, error_info); + if (buffer != vio->cmd_buffer.buffer) { mnd_efree(buffer); } if (!sent) { @@ -839,18 +844,19 @@ php_mysqlnd_ok_read(void * _packet) register MYSQLND_PACKET_OK *packet= (MYSQLND_PACKET_OK *) _packet; MYSQLND_ERROR_INFO * error_info = packet->header.error_info; MYSQLND_NET * net = packet->header.net; + MYSQLND_VIO * vio = packet->header.vio; MYSQLND_STATS * stats = packet->header.stats; MYSQLND_CONNECTION_STATE * connection_state = packet->header.connection_state; zend_uchar local_buf[OK_BUFFER_SIZE]; - size_t buf_len = net->cmd_buffer.buffer? net->cmd_buffer.length : OK_BUFFER_SIZE; - zend_uchar *buf = net->cmd_buffer.buffer? (zend_uchar *) net->cmd_buffer.buffer : local_buf; + size_t buf_len = vio->cmd_buffer.buffer? vio->cmd_buffer.length : OK_BUFFER_SIZE; + zend_uchar *buf = vio->cmd_buffer.buffer? (zend_uchar *) vio->cmd_buffer.buffer : local_buf; zend_uchar *p = buf; zend_uchar *begin = buf; zend_ulong i; DBG_ENTER("php_mysqlnd_ok_read"); - if (FAIL == mysqlnd_read_packet_header_and_body(&(packet->header), net, stats, error_info, connection_state, buf, buf_len, "OK", PROT_OK_PACKET)) { + if (FAIL == mysqlnd_read_packet_header_and_body(&(packet->header), net, vio, stats, error_info, connection_state, buf, buf_len, "OK", PROT_OK_PACKET)) { DBG_RETURN(FAIL); } BAIL_IF_NO_MORE_DATA; @@ -936,16 +942,17 @@ php_mysqlnd_eof_read(void * _packet) MYSQLND_PACKET_EOF *packet= (MYSQLND_PACKET_EOF *) _packet; MYSQLND_ERROR_INFO * error_info = packet->header.error_info; MYSQLND_NET * net = packet->header.net; + MYSQLND_VIO * vio = packet->header.vio; MYSQLND_STATS * stats = packet->header.stats; MYSQLND_CONNECTION_STATE * connection_state = packet->header.connection_state; - size_t buf_len = net->cmd_buffer.length; - zend_uchar *buf = (zend_uchar *) net->cmd_buffer.buffer; + size_t buf_len = vio->cmd_buffer.length; + zend_uchar *buf = (zend_uchar *) vio->cmd_buffer.buffer; zend_uchar *p = buf; zend_uchar *begin = buf; DBG_ENTER("php_mysqlnd_eof_read"); - if (FAIL == mysqlnd_read_packet_header_and_body(&(packet->header), net, stats, error_info, connection_state, buf, buf_len, "EOF", PROT_EOF_PACKET)) { + if (FAIL == mysqlnd_read_packet_header_and_body(&(packet->header), net, vio, stats, error_info, connection_state, buf, buf_len, "EOF", PROT_EOF_PACKET)) { DBG_RETURN(FAIL); } BAIL_IF_NO_MORE_DATA; @@ -1014,6 +1021,7 @@ size_t php_mysqlnd_cmd_write(void * _packet) MYSQLND_PACKET_COMMAND * packet= (MYSQLND_PACKET_COMMAND *) _packet; MYSQLND_ERROR_INFO * error_info = packet->header.error_info; MYSQLND_NET * net = packet->header.net; + MYSQLND_VIO * vio = packet->header.vio; MYSQLND_STATS * stats = packet->header.stats; MYSQLND_CONNECTION_STATE * connection_state = packet->header.connection_state; unsigned int error_reporting = EG(error_reporting); @@ -1034,18 +1042,18 @@ size_t php_mysqlnd_cmd_write(void * _packet) MYSQLND_INC_CONN_STATISTIC(stats, STAT_PACKETS_SENT_CMD); #ifdef MYSQLND_DO_WIRE_CHECK_BEFORE_COMMAND - net->data->m.consume_uneaten_data(net, packet->command); + vio->data->m.consume_uneaten_data(vio, packet->command); #endif if (!packet->argument.s || !packet->argument.l) { zend_uchar buffer[MYSQLND_HEADER_SIZE + 1]; int1store(buffer + MYSQLND_HEADER_SIZE, packet->command); - sent = net->data->m.send_ex(net, buffer, 1, stats, error_info); + sent = net->data->m.send(net, vio, buffer, 1, stats, error_info); } else { size_t tmp_len = packet->argument.l + 1 + MYSQLND_HEADER_SIZE; zend_uchar *tmp, *p; - tmp = (tmp_len > net->cmd_buffer.length)? mnd_emalloc(tmp_len):net->cmd_buffer.buffer; + tmp = (tmp_len > vio->cmd_buffer.length)? mnd_emalloc(tmp_len):vio->cmd_buffer.buffer; if (!tmp) { goto end; } @@ -1056,8 +1064,8 @@ size_t php_mysqlnd_cmd_write(void * _packet) memcpy(p, packet->argument.s, packet->argument.l); - sent = net->data->m.send_ex(net, tmp, tmp_len - MYSQLND_HEADER_SIZE, stats, error_info); - if (tmp != net->cmd_buffer.buffer) { + sent = net->data->m.send(net, vio, tmp, tmp_len - MYSQLND_HEADER_SIZE, stats, error_info); + if (tmp != vio->cmd_buffer.buffer) { MYSQLND_INC_CONN_STATISTIC(stats, STAT_CMD_BUFFER_TOO_SMALL); mnd_efree(tmp); } @@ -1094,18 +1102,19 @@ php_mysqlnd_rset_header_read(void * _packet) MYSQLND_PACKET_RSET_HEADER * packet= (MYSQLND_PACKET_RSET_HEADER *) _packet; MYSQLND_ERROR_INFO * error_info = packet->header.error_info; MYSQLND_NET * net = packet->header.net; + MYSQLND_VIO * vio = packet->header.vio; MYSQLND_STATS * stats = packet->header.stats; MYSQLND_CONNECTION_STATE * connection_state = packet->header.connection_state; enum_func_status ret = PASS; - size_t buf_len = net->cmd_buffer.length; - zend_uchar *buf = (zend_uchar *) net->cmd_buffer.buffer; + size_t buf_len = vio->cmd_buffer.length; + zend_uchar *buf = (zend_uchar *) vio->cmd_buffer.buffer; zend_uchar *p = buf; zend_uchar *begin = buf; size_t len; DBG_ENTER("php_mysqlnd_rset_header_read"); - if (FAIL == mysqlnd_read_packet_header_and_body(&(packet->header), net, stats, error_info, connection_state, buf, buf_len, "resultset header", PROT_RSET_HEADER_PACKET)) { + if (FAIL == mysqlnd_read_packet_header_and_body(&(packet->header), net, vio, stats, error_info, connection_state, buf, buf_len, "resultset header", PROT_RSET_HEADER_PACKET)) { DBG_RETURN(FAIL); } BAIL_IF_NO_MORE_DATA; @@ -1239,10 +1248,11 @@ php_mysqlnd_rset_field_read(void * _packet) MYSQLND_PACKET_RES_FIELD *packet = (MYSQLND_PACKET_RES_FIELD *) _packet; MYSQLND_ERROR_INFO * error_info = packet->header.error_info; MYSQLND_NET * net = packet->header.net; + MYSQLND_VIO * vio = packet->header.vio; MYSQLND_STATS * stats = packet->header.stats; MYSQLND_CONNECTION_STATE * connection_state = packet->header.connection_state; - size_t buf_len = net->cmd_buffer.length, total_len = 0; - zend_uchar *buf = (zend_uchar *) net->cmd_buffer.buffer; + size_t buf_len = vio->cmd_buffer.length, total_len = 0; + zend_uchar *buf = (zend_uchar *) vio->cmd_buffer.buffer; zend_uchar *p = buf; zend_uchar *begin = buf; char *root_ptr; @@ -1252,7 +1262,7 @@ php_mysqlnd_rset_field_read(void * _packet) DBG_ENTER("php_mysqlnd_rset_field_read"); - if (FAIL == mysqlnd_read_packet_header_and_body(&(packet->header), net, stats, error_info, connection_state, buf, buf_len, "field", PROT_RSET_FLD_PACKET)) { + if (FAIL == mysqlnd_read_packet_header_and_body(&(packet->header), net, vio, stats, error_info, connection_state, buf, buf_len, "field", PROT_RSET_FLD_PACKET)) { DBG_RETURN(FAIL); } @@ -1453,6 +1463,7 @@ void php_mysqlnd_rset_field_free_mem(void * _packet, zend_bool stack_allocation) /* {{{ php_mysqlnd_read_row_ex */ static enum_func_status php_mysqlnd_read_row_ex(MYSQLND_NET * net, + MYSQLND_VIO * vio, MYSQLND_STATS * stats, MYSQLND_ERROR_INFO * error_info, MYSQLND_MEMORY_POOL * result_set_memory_pool, @@ -1477,7 +1488,7 @@ php_mysqlnd_read_row_ex(MYSQLND_NET * net, *data_size = prealloc_more_bytes; while (1) { - if (FAIL == mysqlnd_read_header(net, &header, stats, error_info)) { + if (FAIL == mysqlnd_read_header(net, vio, &header, stats, error_info)) { ret = FAIL; break; } @@ -1510,7 +1521,7 @@ php_mysqlnd_read_row_ex(MYSQLND_NET * net, p = (*buffer)->ptr + (*data_size - header.size); } - if (PASS != (ret = net->data->m.receive_ex(net, p, header.size, stats, error_info))) { + if (PASS != (ret = net->data->m.receive(net, vio, p, header.size, stats, error_info))) { DBG_ERR("Empty row packet body"); php_error(E_WARNING, "Empty row packet body"); break; @@ -1812,6 +1823,7 @@ php_mysqlnd_rowp_read(void * _packet) MYSQLND_PACKET_ROW *packet= (MYSQLND_PACKET_ROW *) _packet; MYSQLND_ERROR_INFO * error_info = packet->header.error_info; MYSQLND_NET * net = packet->header.net; + MYSQLND_VIO * vio = packet->header.vio; MYSQLND_STATS * stats = packet->header.stats; zend_uchar *p; enum_func_status ret = PASS; @@ -1825,7 +1837,7 @@ php_mysqlnd_rowp_read(void * _packet) post_alloc_for_bit_fields = packet->bit_fields_total_len + packet->bit_fields_count; } - ret = php_mysqlnd_read_row_ex(net, stats, error_info, + ret = php_mysqlnd_read_row_ex(net, vio, stats, error_info, packet->result_set_memory_pool, &packet->row_buffer, &data_size, packet->persistent_alloc, post_alloc_for_bit_fields ); @@ -1936,14 +1948,15 @@ php_mysqlnd_stats_read(void * _packet) MYSQLND_PACKET_STATS *packet= (MYSQLND_PACKET_STATS *) _packet; MYSQLND_ERROR_INFO * error_info = packet->header.error_info; MYSQLND_NET * net = packet->header.net; + MYSQLND_VIO * vio = packet->header.vio; MYSQLND_STATS * stats = packet->header.stats; MYSQLND_CONNECTION_STATE * connection_state = packet->header.connection_state; - size_t buf_len = net->cmd_buffer.length; - zend_uchar *buf = (zend_uchar *) net->cmd_buffer.buffer; + size_t buf_len = vio->cmd_buffer.length; + zend_uchar *buf = (zend_uchar *) vio->cmd_buffer.buffer; DBG_ENTER("php_mysqlnd_stats_read"); - if (FAIL == mysqlnd_read_packet_header_and_body(&(packet->header), net, stats, error_info, connection_state, buf, buf_len, "statistics", PROT_STATS_PACKET)) { + if (FAIL == mysqlnd_read_packet_header_and_body(&(packet->header), net, vio, stats, error_info, connection_state, buf, buf_len, "statistics", PROT_STATS_PACKET)) { DBG_RETURN(FAIL); } @@ -1984,18 +1997,19 @@ php_mysqlnd_prepare_read(void * _packet) MYSQLND_PACKET_PREPARE_RESPONSE *packet= (MYSQLND_PACKET_PREPARE_RESPONSE *) _packet; MYSQLND_ERROR_INFO * error_info = packet->header.error_info; MYSQLND_NET * net = packet->header.net; + MYSQLND_VIO * vio = packet->header.vio; MYSQLND_STATS * stats = packet->header.stats; MYSQLND_CONNECTION_STATE * connection_state = packet->header.connection_state; /* In case of an error, we should have place to put it */ - size_t buf_len = net->cmd_buffer.length; - zend_uchar *buf = (zend_uchar *) net->cmd_buffer.buffer; + size_t buf_len = vio->cmd_buffer.length; + zend_uchar *buf = (zend_uchar *) vio->cmd_buffer.buffer; zend_uchar *p = buf; zend_uchar *begin = buf; unsigned int data_size; DBG_ENTER("php_mysqlnd_prepare_read"); - if (FAIL == mysqlnd_read_packet_header_and_body(&(packet->header), net, stats, error_info, connection_state, buf, buf_len, "prepare", PROT_PREPARE_RESP_PACKET)) { + if (FAIL == mysqlnd_read_packet_header_and_body(&(packet->header), net, vio, stats, error_info, connection_state, buf, buf_len, "prepare", PROT_PREPARE_RESP_PACKET)) { DBG_RETURN(FAIL); } BAIL_IF_NO_MORE_DATA; @@ -2078,17 +2092,18 @@ php_mysqlnd_chg_user_read(void * _packet) MYSQLND_PACKET_CHG_USER_RESPONSE *packet= (MYSQLND_PACKET_CHG_USER_RESPONSE *) _packet; MYSQLND_ERROR_INFO * error_info = packet->header.error_info; MYSQLND_NET * net = packet->header.net; + MYSQLND_VIO * vio = packet->header.vio; MYSQLND_STATS * stats = packet->header.stats; MYSQLND_CONNECTION_STATE * connection_state = packet->header.connection_state; /* There could be an error message */ - size_t buf_len = net->cmd_buffer.length; - zend_uchar *buf = (zend_uchar *) net->cmd_buffer.buffer; + size_t buf_len = vio->cmd_buffer.length; + zend_uchar *buf = (zend_uchar *) vio->cmd_buffer.buffer; zend_uchar *p = buf; zend_uchar *begin = buf; DBG_ENTER("php_mysqlnd_chg_user_read"); - if (FAIL == mysqlnd_read_packet_header_and_body(&(packet->header), net, stats, error_info, connection_state, buf, buf_len, "change user response", PROT_CHG_USER_RESP_PACKET)) { + if (FAIL == mysqlnd_read_packet_header_and_body(&(packet->header), net, vio, stats, error_info, connection_state, buf, buf_len, "change user response", PROT_CHG_USER_RESP_PACKET)) { DBG_RETURN(FAIL); } BAIL_IF_NO_MORE_DATA; @@ -2172,6 +2187,7 @@ size_t php_mysqlnd_sha256_pk_request_write(void * _packet) MYSQLND_PACKET_SHA256_PK_REQUEST * packet = (MYSQLND_PACKET_SHA256_PK_REQUEST *) _packet; MYSQLND_ERROR_INFO * error_info = packet->header.error_info; MYSQLND_NET * net = packet->header.net; + MYSQLND_VIO * vio = packet->header.vio; MYSQLND_STATS * stats = packet->header.stats; zend_uchar buffer[MYSQLND_HEADER_SIZE + 1]; size_t sent; @@ -2179,7 +2195,7 @@ size_t php_mysqlnd_sha256_pk_request_write(void * _packet) DBG_ENTER("php_mysqlnd_sha256_pk_request_write"); int1store(buffer + MYSQLND_HEADER_SIZE, '\1'); - sent = net->data->m.send_ex(net, buffer, 1, stats, error_info); + sent = net->data->m.send(net, vio, buffer, 1, stats, error_info); DBG_RETURN(sent); } @@ -2207,6 +2223,7 @@ php_mysqlnd_sha256_pk_request_response_read(void * _packet) MYSQLND_PACKET_SHA256_PK_REQUEST_RESPONSE * packet= (MYSQLND_PACKET_SHA256_PK_REQUEST_RESPONSE *) _packet; MYSQLND_ERROR_INFO * error_info = packet->header.error_info; MYSQLND_NET * net = packet->header.net; + MYSQLND_VIO * vio = packet->header.vio; MYSQLND_STATS * stats = packet->header.stats; MYSQLND_CONNECTION_STATE * connection_state = packet->header.connection_state; zend_uchar buf[SHA256_PK_REQUEST_RESP_BUFFER_SIZE]; @@ -2216,7 +2233,7 @@ php_mysqlnd_sha256_pk_request_response_read(void * _packet) DBG_ENTER("php_mysqlnd_sha256_pk_request_response_read"); /* leave space for terminating safety \0 */ - if (FAIL == mysqlnd_read_packet_header_and_body(&(packet->header), net, stats, error_info, connection_state, buf, sizeof(buf), "SHA256_PK_REQUEST_RESPONSE", PROT_SHA256_PK_REQUEST_RESPONSE_PACKET)) { + if (FAIL == mysqlnd_read_packet_header_and_body(&(packet->header), net, vio, stats, error_info, connection_state, buf, sizeof(buf), "SHA256_PK_REQUEST_RESPONSE", PROT_SHA256_PK_REQUEST_RESPONSE_PACKET)) { DBG_RETURN(FAIL); } BAIL_IF_NO_MORE_DATA; @@ -2367,6 +2384,7 @@ MYSQLND_METHOD(mysqlnd_protocol, get_greet_packet)(MYSQLND_PROTOCOL_PAYLOAD_DECO packet->header.factory = factory; packet->header.net = factory->conn->net; + packet->header.vio = factory->conn->vio; packet->header.stats = factory->conn->stats; packet->header.error_info = factory->conn->error_info; packet->header.connection_state = &factory->conn->state; @@ -2390,6 +2408,7 @@ MYSQLND_METHOD(mysqlnd_protocol, get_auth_packet)(MYSQLND_PROTOCOL_PAYLOAD_DECOD packet->header.conn = factory->conn; packet->header.net = factory->conn->net; + packet->header.vio = factory->conn->vio; packet->header.stats = factory->conn->stats; packet->header.error_info = factory->conn->error_info; packet->header.connection_state = &factory->conn->state; @@ -2412,6 +2431,7 @@ MYSQLND_METHOD(mysqlnd_protocol, get_auth_response_packet)(MYSQLND_PROTOCOL_PAYL packet->header.factory = factory; packet->header.net = factory->conn->net; + packet->header.vio = factory->conn->vio; packet->header.stats = factory->conn->stats; packet->header.error_info = factory->conn->error_info; packet->header.connection_state = &factory->conn->state; @@ -2434,6 +2454,7 @@ MYSQLND_METHOD(mysqlnd_protocol, get_change_auth_response_packet)(MYSQLND_PROTOC packet->header.factory = factory; packet->header.net = factory->conn->net; + packet->header.vio = factory->conn->vio; packet->header.stats = factory->conn->stats; packet->header.error_info = factory->conn->error_info; packet->header.connection_state = &factory->conn->state; @@ -2456,6 +2477,7 @@ MYSQLND_METHOD(mysqlnd_protocol, get_ok_packet)(MYSQLND_PROTOCOL_PAYLOAD_DECODER packet->header.factory = factory; packet->header.net = factory->conn->net; + packet->header.vio = factory->conn->vio; packet->header.stats = factory->conn->stats; packet->header.error_info = factory->conn->error_info; packet->header.connection_state = &factory->conn->state; @@ -2478,6 +2500,7 @@ MYSQLND_METHOD(mysqlnd_protocol, get_eof_packet)(MYSQLND_PROTOCOL_PAYLOAD_DECODE packet->header.factory = factory; packet->header.net = factory->conn->net; + packet->header.vio = factory->conn->vio; packet->header.stats = factory->conn->stats; packet->header.error_info = factory->conn->error_info; packet->header.connection_state = &factory->conn->state; @@ -2500,6 +2523,7 @@ MYSQLND_METHOD(mysqlnd_protocol, get_command_packet)(MYSQLND_PROTOCOL_PAYLOAD_DE packet->header.factory = factory; packet->header.net = factory->conn->net; + packet->header.vio = factory->conn->vio; packet->header.stats = factory->conn->stats; packet->header.error_info = factory->conn->error_info; packet->header.connection_state = &factory->conn->state; @@ -2522,6 +2546,7 @@ MYSQLND_METHOD(mysqlnd_protocol, get_rset_header_packet)(MYSQLND_PROTOCOL_PAYLOA packet->header.factory = factory; packet->header.net = factory->conn->net; + packet->header.vio = factory->conn->vio; packet->header.stats = factory->conn->stats; packet->header.error_info = factory->conn->error_info; packet->header.connection_state = &factory->conn->state; @@ -2544,6 +2569,7 @@ MYSQLND_METHOD(mysqlnd_protocol, get_result_field_packet)(MYSQLND_PROTOCOL_PAYLO packet->header.factory = factory; packet->header.net = factory->conn->net; + packet->header.vio = factory->conn->vio; packet->header.stats = factory->conn->stats; packet->header.error_info = factory->conn->error_info; packet->header.connection_state = &factory->conn->state; @@ -2567,6 +2593,7 @@ MYSQLND_METHOD(mysqlnd_protocol, get_row_packet)(MYSQLND_PROTOCOL_PAYLOAD_DECODE packet->header.conn = factory->conn; packet->header.net = factory->conn->net; + packet->header.vio = factory->conn->vio; packet->header.stats = factory->conn->stats; packet->header.error_info = factory->conn->error_info; packet->header.connection_state = &factory->conn->state; @@ -2589,6 +2616,7 @@ MYSQLND_METHOD(mysqlnd_protocol, get_stats_packet)(MYSQLND_PROTOCOL_PAYLOAD_DECO packet->header.factory = factory; packet->header.net = factory->conn->net; + packet->header.vio = factory->conn->vio; packet->header.stats = factory->conn->stats; packet->header.error_info = factory->conn->error_info; packet->header.connection_state = &factory->conn->state; @@ -2611,6 +2639,7 @@ MYSQLND_METHOD(mysqlnd_protocol, get_prepare_response_packet)(MYSQLND_PROTOCOL_P packet->header.factory = factory; packet->header.net = factory->conn->net; + packet->header.vio = factory->conn->vio; packet->header.stats = factory->conn->stats; packet->header.error_info = factory->conn->error_info; packet->header.connection_state = &factory->conn->state; @@ -2633,6 +2662,7 @@ MYSQLND_METHOD(mysqlnd_protocol, get_change_user_response_packet)(MYSQLND_PROTOC packet->header.factory = factory; packet->header.net = factory->conn->net; + packet->header.vio = factory->conn->vio; packet->header.stats = factory->conn->stats; packet->header.error_info = factory->conn->error_info; packet->header.connection_state = &factory->conn->state; @@ -2655,6 +2685,7 @@ MYSQLND_METHOD(mysqlnd_protocol, get_sha256_pk_request_packet)(MYSQLND_PROTOCOL_ packet->header.factory = factory; packet->header.net = factory->conn->net; + packet->header.vio = factory->conn->vio; packet->header.stats = factory->conn->stats; packet->header.error_info = factory->conn->error_info; packet->header.connection_state = &factory->conn->state; @@ -2677,6 +2708,7 @@ MYSQLND_METHOD(mysqlnd_protocol, get_sha256_pk_request_response_packet)(MYSQLND_ packet->header.factory = factory; packet->header.net = factory->conn->net; + packet->header.vio = factory->conn->vio; packet->header.stats = factory->conn->stats; packet->header.error_info = factory->conn->error_info; packet->header.connection_state = &factory->conn->state; @@ -4138,9 +4170,9 @@ mysqlnd_com_enable_ssl_run(void *cmd) goto close_conn; } - conn->net->data->m.set_client_option(conn->net, MYSQL_OPT_SSL_VERIFY_SERVER_CERT, (const char *) &verify); + conn->vio->data->m.set_client_option(conn->vio, MYSQL_OPT_SSL_VERIFY_SERVER_CERT, (const char *) &verify); - if (FAIL == conn->net->data->m.enable_ssl(conn->net)) { + if (FAIL == conn->vio->data->m.enable_ssl(conn->vio)) { goto end; } } @@ -4221,7 +4253,7 @@ mysqlnd_com_handshake_run(void *cmd) MYSQLND_PACKET_GREET * greet_packet; DBG_ENTER("mysqlnd_conn_data::connect_handshake"); - DBG_INF_FMT("stream=%p", conn->net->data->m.get_stream(conn->net)); + DBG_INF_FMT("stream=%p", conn->vio->data->m.get_stream(conn->vio)); DBG_INF_FMT("[user=%s] [db=%s:%d] [flags=%llu]", user, db, db_len, mysql_flags); greet_packet = conn->payload_decoder_factory->m.get_greet_packet(conn->payload_decoder_factory, FALSE); diff --git a/ext/mysqlnd/mysqlnd_wireprotocol.h b/ext/mysqlnd/mysqlnd_wireprotocol.h index 58ef62c645..e15a351cf2 100644 --- a/ext/mysqlnd/mysqlnd_wireprotocol.h +++ b/ext/mysqlnd/mysqlnd_wireprotocol.h @@ -66,6 +66,7 @@ typedef struct st_mysqlnd_packet_header { MYSQLND_CONN_DATA * conn; MYSQLND_NET * net; + MYSQLND_VIO * vio; MYSQLND_ERROR_INFO * error_info; MYSQLND_STATS * stats; MYSQLND_PROTOCOL_PAYLOAD_DECODER_FACTORY * factory; -- 2.40.0