summaryrefslogtreecommitdiff
path: root/ext/mysqlnd
diff options
context:
space:
mode:
Diffstat (limited to 'ext/mysqlnd')
-rw-r--r--ext/mysqlnd/mysqlnd.c691
-rw-r--r--ext/mysqlnd/mysqlnd.h6
-rw-r--r--ext/mysqlnd/mysqlnd_alloc.c53
-rw-r--r--ext/mysqlnd/mysqlnd_alloc.h4
-rw-r--r--ext/mysqlnd/mysqlnd_debug.h3
-rw-r--r--ext/mysqlnd/mysqlnd_driver.c31
-rw-r--r--ext/mysqlnd/mysqlnd_enum_n_def.h2
-rw-r--r--ext/mysqlnd/mysqlnd_ext_plugin.c1
-rw-r--r--ext/mysqlnd/mysqlnd_loaddata.c8
-rw-r--r--ext/mysqlnd/mysqlnd_net.c378
-rw-r--r--ext/mysqlnd/mysqlnd_priv.h12
-rw-r--r--ext/mysqlnd/mysqlnd_reverse_api.h1
-rw-r--r--ext/mysqlnd/mysqlnd_structs.h64
-rw-r--r--ext/mysqlnd/mysqlnd_wireprotocol.c23
14 files changed, 703 insertions, 574 deletions
diff --git a/ext/mysqlnd/mysqlnd.c b/ext/mysqlnd/mysqlnd.c
index 797cadd624..cc3a3917a1 100644
--- a/ext/mysqlnd/mysqlnd.c
+++ b/ext/mysqlnd/mysqlnd.c
@@ -114,7 +114,7 @@ MYSQLND_METHOD(mysqlnd_conn_data, free_contents)(MYSQLND_CONN_DATA * conn TSRMLS
}
if (conn->net) {
- conn->net->m.free_contents(conn->net TSRMLS_CC);
+ conn->net->data->m.free_contents(conn->net TSRMLS_CC);
}
DBG_INF("Freeing memory of members");
@@ -303,17 +303,16 @@ MYSQLND_METHOD(mysqlnd_conn_data, simple_command_handle_response)(MYSQLND_CONN_D
/* }}} */
-/* {{{ mysqlnd_conn_data::simple_command */
+/* {{{ mysqlnd_conn_data::simple_command_send_request */
static enum_func_status
-MYSQLND_METHOD(mysqlnd_conn_data, simple_command)(MYSQLND_CONN_DATA * conn, enum php_mysqlnd_server_command command,
- const zend_uchar * const arg, size_t arg_len, enum mysqlnd_packet_type ok_packet, zend_bool silent,
- zend_bool ignore_upsert_status TSRMLS_DC)
+MYSQLND_METHOD(mysqlnd_conn_data, simple_command_send_request)(MYSQLND_CONN_DATA * conn, enum php_mysqlnd_server_command command,
+ const zend_uchar * const arg, size_t arg_len, zend_bool silent, zend_bool ignore_upsert_status TSRMLS_DC)
{
enum_func_status ret = PASS;
MYSQLND_PACKET_COMMAND * cmd_packet;
- DBG_ENTER("mysqlnd_conn_data::simple_command");
- DBG_INF_FMT("command=%s ok_packet=%u silent=%u", mysqlnd_command_to_text[command], ok_packet, silent);
+ DBG_ENTER("mysqlnd_conn_data::simple_command_send_request");
+ DBG_INF_FMT("command=%s silent=%u", mysqlnd_command_to_text[command], silent);
switch (CONN_GET_STATE(conn)) {
case CONN_READY:
@@ -355,13 +354,30 @@ MYSQLND_METHOD(mysqlnd_conn_data, simple_command)(MYSQLND_CONN_DATA * conn, enum
php_error(E_WARNING, "Error while sending %s packet. PID=%d", mysqlnd_command_to_text[command], getpid());
}
CONN_SET_STATE(conn, CONN_QUIT_SENT);
+ conn->m->send_close(conn TSRMLS_CC);
DBG_ERR("Server is gone");
ret = FAIL;
- } else if (ok_packet != PROT_LAST) {
+ }
+ PACKET_FREE(cmd_packet);
+ DBG_RETURN(ret);
+}
+/* }}} */
+
+
+/* {{{ mysqlnd_conn_data::simple_command */
+static enum_func_status
+MYSQLND_METHOD(mysqlnd_conn_data, simple_command)(MYSQLND_CONN_DATA * conn, enum php_mysqlnd_server_command command,
+ const zend_uchar * const arg, size_t arg_len, enum mysqlnd_packet_type ok_packet, zend_bool silent,
+ zend_bool ignore_upsert_status TSRMLS_DC)
+{
+ enum_func_status ret;
+ DBG_ENTER("mysqlnd_conn_data::simple_command");
+
+ ret = conn->m->simple_command_send_request(conn, command, arg, arg_len, silent, ignore_upsert_status TSRMLS_CC);
+ if (PASS == ret && ok_packet != PROT_LAST) {
ret = conn->m->simple_command_handle_response(conn, ok_packet, silent, command, ignore_upsert_status TSRMLS_CC);
}
- PACKET_FREE(cmd_packet);
DBG_INF(ret == PASS ? "PASS":"FAIL");
DBG_RETURN(ret);
}
@@ -453,13 +469,14 @@ mysqlnd_switch_to_ssl_if_needed(
DBG_INF("Switching to SSL");
if (!PACKET_WRITE(auth_packet, conn)) {
CONN_SET_STATE(conn, CONN_QUIT_SENT);
+ conn->m->send_close(conn TSRMLS_CC);
SET_CLIENT_ERROR(*conn->error_info, CR_SERVER_GONE_ERROR, UNKNOWN_SQLSTATE, mysqlnd_server_gone);
goto end;
}
- conn->net->m.set_client_option(conn->net, MYSQL_OPT_SSL_VERIFY_SERVER_CERT, (const char *) &verify TSRMLS_CC);
+ conn->net->data->m.set_client_option(conn->net, MYSQL_OPT_SSL_VERIFY_SERVER_CERT, (const char *) &verify TSRMLS_CC);
- if (FAIL == conn->net->m.enable_ssl(conn->net TSRMLS_CC)) {
+ if (FAIL == conn->net->data->m.enable_ssl(conn->net TSRMLS_CC)) {
goto end;
}
}
@@ -472,132 +489,150 @@ end:
/* }}} */
-/* {{{ mysqlnd_connect_run_authentication */
+/* {{{ mysqlnd_conn_data::fetch_auth_plugin_by_name */
+static struct st_mysqlnd_authentication_plugin *
+MYSQLND_METHOD(mysqlnd_conn_data, fetch_auth_plugin_by_name)(const char * const requested_protocol TSRMLS_DC)
+{
+ struct st_mysqlnd_authentication_plugin * auth_plugin;
+ char * plugin_name = NULL;
+ DBG_ENTER("mysqlnd_conn_data::fetch_auth_plugin_by_name");
+
+ mnd_sprintf(&plugin_name, 0, "auth_plugin_%s", requested_protocol);
+ DBG_INF_FMT("looking for %s auth plugin", plugin_name);
+ auth_plugin = mysqlnd_plugin_find(plugin_name);
+ mnd_sprintf_free(plugin_name);
+
+ DBG_RETURN(auth_plugin);
+}
+/* }}} */
+
+
+/* {{{ mysqlnd_run_authentication */
static enum_func_status
-mysqlnd_connect_run_authentication(
+mysqlnd_run_authentication(
MYSQLND_CONN_DATA * conn,
const char * const user,
const char * const passwd,
+ const size_t passwd_len,
const char * const db,
- size_t db_len,
- size_t passwd_len,
- const MYSQLND_PACKET_GREET * const greet_packet,
+ const size_t db_len,
+ const zend_uchar * const auth_plugin_data,
+ const size_t auth_plugin_data_len,
+ const char * const auth_protocol,
+ unsigned int charset_no,
const MYSQLND_OPTIONS * const options,
- unsigned long mysql_flags
+ unsigned long mysql_flags,
+ zend_bool silent,
+ zend_bool is_change_user
TSRMLS_DC)
{
enum_func_status ret = FAIL;
- DBG_ENTER("mysqlnd_connect_run_authentication");
+ zend_bool first_call = TRUE;
- ret = mysqlnd_switch_to_ssl_if_needed(conn, greet_packet, options, mysql_flags TSRMLS_CC);
- if (PASS == ret) {
- zend_bool first_call = TRUE;
+ char * switch_to_auth_protocol = NULL;
+ size_t switch_to_auth_protocol_len = 0;
+ char * requested_protocol = NULL;
+ zend_uchar * plugin_data;
+ size_t plugin_data_len;
- char * switch_to_auth_protocol = NULL;
- size_t switch_to_auth_protocol_len = 0;
- char * requested_protocol = NULL;
- zend_uchar * plugin_data;
- size_t plugin_data_len;
+ DBG_ENTER("mysqlnd_run_authentication");
- plugin_data_len = greet_packet->auth_plugin_data_len;
- plugin_data = mnd_emalloc(plugin_data_len + 1);
- if (!plugin_data) {
- ret = FAIL;
- goto end;
- }
- memcpy(plugin_data, greet_packet->auth_plugin_data, plugin_data_len);
- plugin_data[plugin_data_len] = '\0';
+ plugin_data_len = auth_plugin_data_len;
+ plugin_data = mnd_emalloc(plugin_data_len + 1);
+ if (!plugin_data) {
+ goto end;
+ }
+ memcpy(plugin_data, auth_plugin_data, plugin_data_len);
+ plugin_data[plugin_data_len] = '\0';
- requested_protocol = mnd_pestrdup(greet_packet->auth_protocol? greet_packet->auth_protocol: "mysql_native_password", FALSE);
- if (!requested_protocol) {
- ret = FAIL;
+ requested_protocol = mnd_pestrdup(auth_protocol? auth_protocol : MYSQLND_DEFAULT_AUTH_PROTOCOL, FALSE);
+ if (!requested_protocol) {
+ goto end;
+ }
+
+ do {
+ struct st_mysqlnd_authentication_plugin * auth_plugin = conn->m->fetch_auth_plugin_by_name(requested_protocol TSRMLS_CC);
+
+ if (!auth_plugin) {
+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "The server requested authentication method unknown to the client [%s]", requested_protocol);
+ SET_CLIENT_ERROR(*conn->error_info, CR_NOT_IMPLEMENTED, UNKNOWN_SQLSTATE, "The server requested authentication method umknown to the client");
goto end;
}
+ DBG_INF("plugin found");
- do {
- struct st_mysqlnd_authentication_plugin * auth_plugin;
- {
- char * plugin_name = NULL;
-
- mnd_sprintf(&plugin_name, 0, "auth_plugin_%s", requested_protocol);
+ {
+ zend_uchar * switch_to_auth_protocol_data = NULL;
+ size_t switch_to_auth_protocol_data_len = 0;
+ zend_uchar * scrambled_data = NULL;
+ size_t scrambled_data_len = 0;
- DBG_INF_FMT("looking for %s auth plugin", plugin_name);
- auth_plugin = mysqlnd_plugin_find(plugin_name);
- mnd_sprintf_free(plugin_name);
+ switch_to_auth_protocol = NULL;
+ switch_to_auth_protocol_len = 0;
- if (!auth_plugin) {
- php_error_docref(NULL TSRMLS_CC, E_WARNING, "The server requested authentication method unknown to the client [%s]", requested_protocol);
- SET_CLIENT_ERROR(*conn->error_info, CR_NOT_IMPLEMENTED, UNKNOWN_SQLSTATE, "The server requested authentication method umknown to the client");
- break;
- }
+ if (conn->auth_plugin_data) {
+ mnd_pefree(conn->auth_plugin_data, conn->persistent);
+ conn->auth_plugin_data = NULL;
}
- DBG_INF("plugin found");
-
- {
- zend_uchar * switch_to_auth_protocol_data = NULL;
- size_t switch_to_auth_protocol_data_len = 0;
- zend_uchar * scrambled_data = NULL;
- size_t scrambled_data_len = 0;
-
- switch_to_auth_protocol = NULL;
- switch_to_auth_protocol_len = 0;
-
- if (conn->auth_plugin_data) {
- mnd_pefree(conn->auth_plugin_data, conn->persistent);
- conn->auth_plugin_data = NULL;
- }
- conn->auth_plugin_data_len = plugin_data_len;
- conn->auth_plugin_data = mnd_pemalloc(conn->auth_plugin_data_len, conn->persistent);
- if (!conn->auth_plugin_data) {
- SET_OOM_ERROR(*conn->error_info);
- goto end;
- }
- memcpy(conn->auth_plugin_data, plugin_data, plugin_data_len);
-
- DBG_INF_FMT("salt=[%*s]", plugin_data_len - 1, plugin_data);
- /* The data should be allocated with malloc() */
- scrambled_data =
- auth_plugin->methods.get_auth_data(NULL, &scrambled_data_len, conn, user, passwd, passwd_len,
- plugin_data, plugin_data_len, options, mysql_flags TSRMLS_CC);
+ conn->auth_plugin_data_len = plugin_data_len;
+ conn->auth_plugin_data = mnd_pemalloc(conn->auth_plugin_data_len, conn->persistent);
+ if (!conn->auth_plugin_data) {
+ SET_OOM_ERROR(*conn->error_info);
+ goto end;
+ }
+ memcpy(conn->auth_plugin_data, plugin_data, plugin_data_len);
+ DBG_INF_FMT("salt=[%*s]", plugin_data_len - 1, plugin_data);
+ /* The data should be allocated with malloc() */
+ scrambled_data =
+ auth_plugin->methods.get_auth_data(NULL, &scrambled_data_len, conn, user, passwd, passwd_len,
+ plugin_data, plugin_data_len, options, mysql_flags TSRMLS_CC);
+ if (FALSE == is_change_user) {
ret = mysqlnd_auth_handshake(conn, user, passwd, passwd_len, db, db_len, options, mysql_flags,
- greet_packet->charset_no,
+ charset_no,
first_call,
requested_protocol,
scrambled_data, scrambled_data_len,
&switch_to_auth_protocol, &switch_to_auth_protocol_len,
&switch_to_auth_protocol_data, &switch_to_auth_protocol_data_len
TSRMLS_CC);
- first_call = FALSE;
- free(scrambled_data);
+ } else {
+ ret = mysqlnd_auth_change_user(conn, user, strlen(user), passwd, passwd_len, db, db_len, silent,
+ first_call,
+ requested_protocol,
+ scrambled_data, scrambled_data_len,
+ &switch_to_auth_protocol, &switch_to_auth_protocol_len,
+ &switch_to_auth_protocol_data, &switch_to_auth_protocol_data_len
+ TSRMLS_CC);
+ }
+ first_call = FALSE;
+ free(scrambled_data);
- DBG_INF_FMT("switch_to_auth_protocol=%s", switch_to_auth_protocol? switch_to_auth_protocol:"n/a");
- if (requested_protocol && switch_to_auth_protocol) {
- mnd_efree(requested_protocol);
- requested_protocol = switch_to_auth_protocol;
- }
+ DBG_INF_FMT("switch_to_auth_protocol=%s", switch_to_auth_protocol? switch_to_auth_protocol:"n/a");
+ if (requested_protocol && switch_to_auth_protocol) {
+ mnd_efree(requested_protocol);
+ requested_protocol = switch_to_auth_protocol;
+ }
- if (plugin_data) {
- mnd_efree(plugin_data);
- }
- plugin_data_len = switch_to_auth_protocol_data_len;
- plugin_data = switch_to_auth_protocol_data;
+ if (plugin_data) {
+ mnd_efree(plugin_data);
}
- DBG_INF_FMT("conn->error_info->error_no = %d", conn->error_info->error_no);
- } while (ret == FAIL && conn->error_info->error_no == 0 && switch_to_auth_protocol != NULL);
- if (plugin_data) {
- mnd_efree(plugin_data);
+ plugin_data_len = switch_to_auth_protocol_data_len;
+ plugin_data = switch_to_auth_protocol_data;
}
+ DBG_INF_FMT("conn->error_info->error_no = %d", conn->error_info->error_no);
+ } while (ret == FAIL && conn->error_info->error_no == 0 && switch_to_auth_protocol != NULL);
+ if (plugin_data) {
+ mnd_efree(plugin_data);
+ }
- if (ret == PASS) {
- DBG_INF_FMT("saving requested_protocol=%s", requested_protocol);
- conn->m->set_client_option(conn, MYSQLND_OPT_AUTH_PROTOCOL, requested_protocol TSRMLS_CC);
- }
+ if (ret == PASS) {
+ DBG_INF_FMT("saving requested_protocol=%s", requested_protocol);
+ conn->m->set_client_option(conn, MYSQLND_OPT_AUTH_PROTOCOL, requested_protocol TSRMLS_CC);
+ }
- if (requested_protocol) {
- mnd_efree(requested_protocol);
- }
+ if (requested_protocol) {
+ mnd_efree(requested_protocol);
}
end:
DBG_RETURN(ret);
@@ -605,6 +640,176 @@ end:
/* }}} */
+/* {{{ mysqlnd_connect_run_authentication */
+static enum_func_status
+mysqlnd_connect_run_authentication(
+ MYSQLND_CONN_DATA * conn,
+ const char * const user,
+ const char * const passwd,
+ const char * const db,
+ size_t db_len,
+ size_t passwd_len,
+ const MYSQLND_PACKET_GREET * const greet_packet,
+ const MYSQLND_OPTIONS * const options,
+ unsigned long mysql_flags
+ TSRMLS_DC)
+{
+ enum_func_status ret = FAIL;
+ DBG_ENTER("mysqlnd_connect_run_authentication");
+
+ ret = mysqlnd_switch_to_ssl_if_needed(conn, greet_packet, options, mysql_flags TSRMLS_CC);
+ if (PASS == ret) {
+ ret = mysqlnd_run_authentication(conn, user, passwd, passwd_len, db, db_len,
+ greet_packet->auth_plugin_data, greet_packet->auth_plugin_data_len, greet_packet->auth_protocol,
+ greet_packet->charset_no, options, mysql_flags, FALSE /*silent*/, FALSE/*is_change*/ TSRMLS_CC);
+ }
+ DBG_RETURN(ret);
+}
+/* }}} */
+
+
+/* {{{ mysqlnd_conn_data::execute_init_commands */
+static enum_func_status
+MYSQLND_METHOD(mysqlnd_conn_data, execute_init_commands)(MYSQLND_CONN_DATA * conn TSRMLS_DC)
+{
+ enum_func_status ret = PASS;
+
+ DBG_ENTER("mysqlnd_conn_data::execute_init_commands");
+ if (conn->options->init_commands) {
+ unsigned int current_command = 0;
+ for (; current_command < conn->options->num_commands; ++current_command) {
+ const char * const command = conn->options->init_commands[current_command];
+ if (command) {
+ MYSQLND_INC_CONN_STATISTIC(conn->stats, STAT_INIT_COMMAND_EXECUTED_COUNT);
+ if (PASS != conn->m->query(conn, command, strlen(command) TSRMLS_CC)) {
+ MYSQLND_INC_CONN_STATISTIC(conn->stats, STAT_INIT_COMMAND_FAILED_COUNT);
+ ret = FAIL;
+ break;
+ }
+ if (conn->last_query_type == QUERY_SELECT) {
+ MYSQLND_RES * result = conn->m->use_result(conn TSRMLS_CC);
+ if (result) {
+ result->m.free_result(result, TRUE TSRMLS_CC);
+ }
+ }
+ }
+ }
+ }
+ DBG_RETURN(ret);
+}
+/* }}} */
+
+
+/* {{{ mysqlnd_conn_data::get_updated_connect_flags */
+static unsigned int
+MYSQLND_METHOD(mysqlnd_conn_data, get_updated_connect_flags)(MYSQLND_CONN_DATA * conn, unsigned int mysql_flags TSRMLS_DC)
+{
+ MYSQLND_NET * net = conn->net;
+
+ DBG_ENTER("mysqlnd_conn_data::get_updated_connect_flags");
+ /* we allow load data local infile by default */
+ mysql_flags |= MYSQLND_CAPABILITIES;
+
+ if (PG(open_basedir) && strlen(PG(open_basedir))) {
+ mysql_flags ^= CLIENT_LOCAL_FILES;
+ }
+
+#ifndef MYSQLND_COMPRESSION_ENABLED
+ if (mysql_flags & CLIENT_COMPRESS) {
+ mysql_flags &= ~CLIENT_COMPRESS;
+ }
+#else
+ if (net && net->data->options.flags & MYSQLND_NET_FLAG_USE_COMPRESSION) {
+ mysql_flags |= CLIENT_COMPRESS;
+ }
+#endif
+#ifndef MYSQLND_SSL_SUPPORTED
+ if (mysql_flags & CLIENT_SSL) {
+ 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))
+ {
+ mysql_flags |= CLIENT_SSL;
+ }
+#endif
+
+ DBG_RETURN(mysql_flags);
+}
+/* }}} */
+
+
+/* {{{ mysqlnd_conn_data::connect_handshake */
+static enum_func_status
+MYSQLND_METHOD(mysqlnd_conn_data, connect_handshake)(MYSQLND_CONN_DATA * conn,
+ const char * const host, const char * const user,
+ const char * const passwd, const unsigned int passwd_len,
+ const char * const db, const unsigned int db_len,
+ const unsigned int mysql_flags TSRMLS_DC)
+{
+ MYSQLND_PACKET_GREET * greet_packet;
+ MYSQLND_NET * net = conn->net;
+
+ DBG_ENTER("mysqlnd_conn_data::connect_handshake");
+
+ greet_packet = conn->protocol->m.get_greet_packet(conn->protocol, FALSE TSRMLS_CC);
+ if (!greet_packet) {
+ SET_OOM_ERROR(*conn->error_info);
+ DBG_RETURN(FAIL); /* OOM */
+ }
+
+ if (FAIL == net->data->m.connect_ex(conn->net, conn->scheme, conn->scheme_len, conn->persistent,
+ conn->stats, conn->error_info TSRMLS_CC))
+ {
+ goto err;
+ }
+
+ DBG_INF_FMT("stream=%p", net->data->m.get_stream(net TSRMLS_CC));
+
+ if (FAIL == PACKET_READ(greet_packet, conn)) {
+ DBG_ERR("Error while reading greeting packet");
+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "Error while reading greeting packet. PID=%d", getpid());
+ goto err;
+ } else if (greet_packet->error_no) {
+ DBG_ERR_FMT("errorno=%u error=%s", greet_packet->error_no, greet_packet->error);
+ SET_CLIENT_ERROR(*conn->error_info, greet_packet->error_no, greet_packet->sqlstate, greet_packet->error);
+ goto err;
+ } else if (greet_packet->pre41) {
+ DBG_ERR_FMT("Connecting to 3.22, 3.23 & 4.0 is not supported. Server is %-.32s", greet_packet->server_version);
+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "Connecting to 3.22, 3.23 & 4.0 "
+ " is not supported. Server is %-.32s", greet_packet->server_version);
+ SET_CLIENT_ERROR(*conn->error_info, CR_NOT_IMPLEMENTED, UNKNOWN_SQLSTATE,
+ "Connecting to 3.22, 3.23 & 4.0 servers is not supported");
+ goto err;
+ }
+
+ conn->thread_id = greet_packet->thread_id;
+ conn->protocol_version = greet_packet->protocol_version;
+ conn->server_version = mnd_pestrdup(greet_packet->server_version, conn->persistent);
+
+ conn->greet_charset = mysqlnd_find_charset_nr(greet_packet->charset_no);
+
+ if (FAIL == mysqlnd_connect_run_authentication(conn, user, passwd, db, db_len, (size_t) passwd_len,
+ greet_packet, conn->options, mysql_flags TSRMLS_CC))
+ {
+ goto err;
+ }
+ conn->client_flag = mysql_flags;
+ conn->server_capabilities = greet_packet->server_capabilities;
+ conn->upsert_status->warning_count = 0;
+ conn->upsert_status->server_status = greet_packet->server_status;
+ conn->upsert_status->affected_rows = 0;
+
+ PACKET_FREE(greet_packet);
+ DBG_RETURN(PASS);
+err:
+ PACKET_FREE(greet_packet);
+ DBG_RETURN(FAIL);
+}
+/* }}} */
+
+
/* {{{ mysqlnd_conn_data::connect */
static enum_func_status
MYSQLND_METHOD(mysqlnd_conn_data, connect)(MYSQLND_CONN_DATA * conn,
@@ -623,8 +828,7 @@ MYSQLND_METHOD(mysqlnd_conn_data, connect)(MYSQLND_CONN_DATA * conn,
zend_bool reconnect = FALSE;
zend_bool saved_compression = FALSE;
zend_bool local_tx_started = FALSE;
-
- MYSQLND_PACKET_GREET * greet_packet = NULL;
+ MYSQLND_NET * net = conn->net;
DBG_ENTER("mysqlnd_conn_data::connect");
@@ -655,14 +859,14 @@ MYSQLND_METHOD(mysqlnd_conn_data, connect)(MYSQLND_CONN_DATA * conn,
MYSQLND_DEC_CONN_STATISTIC(conn->stats, STAT_OPENED_PERSISTENT_CONNECTIONS);
}
/* Now reconnect using the same handle */
- if (conn->net->compressed) {
+ if (net->data->compressed) {
/*
we need to save the state. As we will re-connect, net->compressed should be off, or
we will look for a compression header as part of the greet message, but there will
be none.
*/
saved_compression = TRUE;
- conn->net->compressed = FALSE;
+ net->data->compressed = FALSE;
}
} else {
unsigned int max_allowed_size = MYSQLND_ASSEMBLED_PACKET_MAX_SIZE;
@@ -685,6 +889,8 @@ MYSQLND_METHOD(mysqlnd_conn_data, connect)(MYSQLND_CONN_DATA * conn,
DBG_INF_FMT("no db given, using empty string");
db = "";
db_len = 0;
+ } else {
+ mysql_flags |= CLIENT_CONNECT_WITH_DB;
}
host_len = strlen(host);
@@ -728,77 +934,9 @@ MYSQLND_METHOD(mysqlnd_conn_data, connect)(MYSQLND_CONN_DATA * conn,
}
}
- greet_packet = conn->protocol->m.get_greet_packet(conn->protocol, FALSE TSRMLS_CC);
- if (!greet_packet) {
- SET_OOM_ERROR(*conn->error_info);
- goto err; /* OOM */
- }
+ mysql_flags = conn->m->get_updated_connect_flags(conn, mysql_flags TSRMLS_CC);
- if (FAIL == conn->net->m.connect_ex(conn->net, conn->scheme, conn->scheme_len, conn->persistent,
- conn->stats, conn->error_info TSRMLS_CC))
- {
- goto err;
- }
-
- DBG_INF_FMT("stream=%p", conn->net->stream);
-
- if (FAIL == PACKET_READ(greet_packet, conn)) {
- DBG_ERR("Error while reading greeting packet");
- php_error_docref(NULL TSRMLS_CC, E_WARNING, "Error while reading greeting packet. PID=%d", getpid());
- goto err;
- } else if (greet_packet->error_no) {
- DBG_ERR_FMT("errorno=%u error=%s", greet_packet->error_no, greet_packet->error);
- SET_CLIENT_ERROR(*conn->error_info, greet_packet->error_no, greet_packet->sqlstate, greet_packet->error);
- goto err;
- } else if (greet_packet->pre41) {
- DBG_ERR_FMT("Connecting to 3.22, 3.23 & 4.0 is not supported. Server is %-.32s", greet_packet->server_version);
- php_error_docref(NULL TSRMLS_CC, E_WARNING, "Connecting to 3.22, 3.23 & 4.0 "
- " is not supported. Server is %-.32s", greet_packet->server_version);
- SET_CLIENT_ERROR(*conn->error_info, CR_NOT_IMPLEMENTED, UNKNOWN_SQLSTATE,
- "Connecting to 3.22, 3.23 & 4.0 servers is not supported");
- goto err;
- }
-
- conn->thread_id = greet_packet->thread_id;
- conn->protocol_version = greet_packet->protocol_version;
- conn->server_version = mnd_pestrdup(greet_packet->server_version, conn->persistent);
-
- conn->greet_charset = mysqlnd_find_charset_nr(greet_packet->charset_no);
- /* we allow load data local infile by default */
- mysql_flags |= MYSQLND_CAPABILITIES;
-
- if (db) {
- mysql_flags |= CLIENT_CONNECT_WITH_DB;
- }
-
- if (PG(open_basedir) && strlen(PG(open_basedir))) {
- mysql_flags ^= CLIENT_LOCAL_FILES;
- }
-
-#ifndef MYSQLND_COMPRESSION_ENABLED
- if (mysql_flags & CLIENT_COMPRESS) {
- mysql_flags &= ~CLIENT_COMPRESS;
- }
-#else
- if (conn->net->options.flags & MYSQLND_NET_FLAG_USE_COMPRESSION) {
- mysql_flags |= CLIENT_COMPRESS;
- }
-#endif
-#ifndef MYSQLND_SSL_SUPPORTED
- if (mysql_flags & CLIENT_SSL) {
- mysql_flags &= ~CLIENT_SSL;
- }
-#else
- if (conn->net->options.ssl_key || conn->net->options.ssl_cert ||
- conn->net->options.ssl_ca || conn->net->options.ssl_capath || conn->net->options.ssl_cipher)
- {
- mysql_flags |= CLIENT_SSL;
- }
-#endif
-
- if (FAIL == mysqlnd_connect_run_authentication(conn, user, passwd, db, db_len, (size_t) passwd_len,
- greet_packet, conn->options, mysql_flags TSRMLS_CC))
- {
+ if (FAIL == conn->m->connect_handshake(conn, host, user, passwd, passwd_len, db, db_len, mysql_flags TSRMLS_CC)) {
goto err;
}
@@ -806,14 +944,14 @@ MYSQLND_METHOD(mysqlnd_conn_data, connect)(MYSQLND_CONN_DATA * conn,
CONN_SET_STATE(conn, CONN_READY);
if (saved_compression) {
- conn->net->compressed = TRUE;
+ net->data->compressed = TRUE;
}
/*
If a connect on a existing handle is performed and mysql_flags is
passed which doesn't CLIENT_COMPRESS, then we need to overwrite the value
which we set based on saved_compression.
*/
- conn->net->compressed = mysql_flags & CLIENT_COMPRESS? TRUE:FALSE;
+ net->data->compressed = mysql_flags & CLIENT_COMPRESS? TRUE:FALSE;
conn->user = mnd_pestrdup(user, conn->persistent);
conn->user_len = strlen(conn->user);
@@ -875,13 +1013,8 @@ MYSQLND_METHOD(mysqlnd_conn_data, connect)(MYSQLND_CONN_DATA * conn,
}
conn->unix_socket_len = strlen(conn->unix_socket);
}
- conn->client_flag = mysql_flags;
conn->max_packet_size = MYSQLND_ASSEMBLED_PACKET_MAX_SIZE;
/* todo: check if charset is available */
- conn->server_capabilities = greet_packet->server_capabilities;
- conn->upsert_status->warning_count = 0;
- conn->upsert_status->server_status = greet_packet->server_status;
- conn->upsert_status->affected_rows = 0;
SET_EMPTY_ERROR(*conn->error_info);
@@ -894,27 +1027,10 @@ MYSQLND_METHOD(mysqlnd_conn_data, connect)(MYSQLND_CONN_DATA * conn,
DBG_INF("unicode set");
}
#endif
- if (conn->options->init_commands) {
- unsigned int current_command = 0;
- for (; current_command < conn->options->num_commands; ++current_command) {
- const char * const command = conn->options->init_commands[current_command];
- if (command) {
- MYSQLND_INC_CONN_STATISTIC(conn->stats, STAT_INIT_COMMAND_EXECUTED_COUNT);
- if (PASS != conn->m->query(conn, command, strlen(command) TSRMLS_CC)) {
- MYSQLND_INC_CONN_STATISTIC(conn->stats, STAT_INIT_COMMAND_FAILED_COUNT);
- goto err;
- }
- if (conn->last_query_type == QUERY_SELECT) {
- MYSQLND_RES * result = conn->m->use_result(conn TSRMLS_CC);
- if (result) {
- result->m.free_result(result, TRUE TSRMLS_CC);
- }
- }
- }
- }
+ if (FAIL == conn->m->execute_init_commands(conn TSRMLS_CC)) {
+ goto err;
}
-
MYSQLND_INC_CONN_STATISTIC_W_VALUE2(conn->stats, STAT_CONNECT_SUCCESS, 1, STAT_OPENED_CONNECTIONS, 1);
if (reconnect) {
MYSQLND_INC_GLOBAL_STATISTIC(STAT_RECONNECT);
@@ -925,13 +1041,10 @@ MYSQLND_METHOD(mysqlnd_conn_data, connect)(MYSQLND_CONN_DATA * conn,
DBG_INF_FMT("connection_id=%llu", conn->thread_id);
- PACKET_FREE(greet_packet);
-
conn->m->local_tx_end(conn, this_func, PASS TSRMLS_CC);
DBG_RETURN(PASS);
}
err:
- PACKET_FREE(greet_packet);
DBG_ERR_FMT("[%u] %.128s (trying to connect via %s)", conn->error_info->error_no, conn->error_info->error, conn->scheme);
if (!conn->error_info->error_no) {
@@ -1142,7 +1255,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.
* */
- if (SUCCESS == php_stream_cast((*p)->data->net->stream, PHP_STREAM_AS_FD_FOR_SELECT | PHP_STREAM_CAST_INTERNAL,
+ if (SUCCESS == php_stream_cast((*p)->data->net->data->m.get_stream((*p)->data->net TSRMLS_CC), PHP_STREAM_AS_FD_FOR_SELECT | PHP_STREAM_CAST_INTERNAL,
(void*)&this_fd, 1) && this_fd >= 0) {
PHP_SAFE_FD_SET(this_fd, fds);
@@ -1167,7 +1280,7 @@ static int mysqlnd_stream_array_from_fd_set(MYSQLND ** conn_array, fd_set * fds
MYSQLND **fwd = conn_array, **bckwd = conn_array;
while (*fwd) {
- if (SUCCESS == php_stream_cast((*fwd)->data->net->stream, PHP_STREAM_AS_FD_FOR_SELECT | PHP_STREAM_CAST_INTERNAL,
+ if (SUCCESS == php_stream_cast((*fwd)->data->net->data->m.get_stream((*fwd)->data->net TSRMLS_CC), PHP_STREAM_AS_FD_FOR_SELECT | PHP_STREAM_CAST_INTERNAL,
(void*)&this_fd, 1) && this_fd >= 0) {
if (PHP_SAFE_FD_ISSET(this_fd, fds)) {
if (disproportion) {
@@ -1438,14 +1551,15 @@ MYSQLND_METHOD(mysqlnd_conn_data, ssl_set)(MYSQLND_CONN_DATA * const conn, const
{
size_t this_func = STRUCT_OFFSET(struct st_mysqlnd_conn_data_methods, ssl_set);
enum_func_status ret = FAIL;
+ MYSQLND_NET * net = conn->net;
DBG_ENTER("mysqlnd_conn_data::ssl_set");
if (PASS == conn->m->local_tx_start(conn, this_func TSRMLS_CC)) {
- ret = (PASS == conn->net->m.set_client_option(conn->net, MYSQLND_OPT_SSL_KEY, key TSRMLS_CC) &&
- PASS == conn->net->m.set_client_option(conn->net, MYSQLND_OPT_SSL_CERT, cert TSRMLS_CC) &&
- PASS == conn->net->m.set_client_option(conn->net, MYSQLND_OPT_SSL_CA, ca TSRMLS_CC) &&
- PASS == conn->net->m.set_client_option(conn->net, MYSQLND_OPT_SSL_CAPATH, capath TSRMLS_CC) &&
- PASS == conn->net->m.set_client_option(conn->net, MYSQLND_OPT_SSL_CIPHER, cipher TSRMLS_CC)) ? PASS : FAIL;
+ ret = (PASS == net->data->m.set_client_option(net, MYSQLND_OPT_SSL_KEY, key TSRMLS_CC) &&
+ PASS == net->data->m.set_client_option(net, MYSQLND_OPT_SSL_CERT, cert TSRMLS_CC) &&
+ PASS == net->data->m.set_client_option(net, MYSQLND_OPT_SSL_CA, ca TSRMLS_CC) &&
+ PASS == net->data->m.set_client_option(net, MYSQLND_OPT_SSL_CAPATH, capath TSRMLS_CC) &&
+ PASS == net->data->m.set_client_option(net, MYSQLND_OPT_SSL_CIPHER, cipher TSRMLS_CC)) ? PASS : FAIL;
conn->m->local_tx_end(conn, this_func, ret TSRMLS_CC);
}
@@ -1620,6 +1734,7 @@ MYSQLND_METHOD(mysqlnd_conn_data, kill)(MYSQLND_CONN_DATA * conn, unsigned int p
SET_ERROR_AFF_ROWS(conn);
} else if (PASS == (ret = conn->m->simple_command(conn, COM_PROCESS_KILL, buff, 4, PROT_LAST, FALSE, TRUE TSRMLS_CC))) {
CONN_SET_STATE(conn, CONN_QUIT_SENT);
+ conn->m->send_close(conn TSRMLS_CC);
}
conn->m->local_tx_end(conn, this_func, ret TSRMLS_CC);
@@ -1717,10 +1832,11 @@ static enum_func_status
MYSQLND_METHOD(mysqlnd_conn_data, send_close)(MYSQLND_CONN_DATA * const conn TSRMLS_DC)
{
enum_func_status ret = PASS;
+ MYSQLND_NET * net = conn->net;
+ php_stream * net_stream = net->data->m.get_stream(net TSRMLS_CC);
DBG_ENTER("mysqlnd_send_close");
- DBG_INF_FMT("conn=%llu conn->net->stream->abstract=%p",
- conn->thread_id, conn->net->stream? conn->net->stream->abstract:NULL);
+ DBG_INF_FMT("conn=%llu net->data->stream->abstract=%p", conn->thread_id, net_stream? net_stream->abstract:NULL);
if (CONN_GET_STATE(conn) >= CONN_READY) {
MYSQLND_DEC_CONN_STATISTIC(conn->stats, STAT_OPENED_CONNECTIONS);
@@ -1731,10 +1847,11 @@ MYSQLND_METHOD(mysqlnd_conn_data, send_close)(MYSQLND_CONN_DATA * const conn TSR
switch (CONN_GET_STATE(conn)) {
case CONN_READY:
DBG_INF("Connection clean, sending COM_QUIT");
- if (conn->net->stream) {
+ if (net_stream) {
ret = conn->m->simple_command(conn, COM_QUIT, NULL, 0, PROT_LAST, TRUE, TRUE TSRMLS_CC);
+ net->data->m.close_stream(net, conn->stats, conn->error_info TSRMLS_CC);
}
- /* Do nothing */
+ CONN_SET_STATE(conn, CONN_QUIT_SENT);
break;
case CONN_SENDING_LOAD_DATA:
/*
@@ -1750,6 +1867,7 @@ MYSQLND_METHOD(mysqlnd_conn_data, send_close)(MYSQLND_CONN_DATA * const conn TSR
Do nothing, the connection will be brutally closed
and the server will catch it and free close from its side.
*/
+ /* Fall-through */
case CONN_ALLOCED:
/*
Allocated but not connected or there was failure when trying
@@ -1757,15 +1875,13 @@ MYSQLND_METHOD(mysqlnd_conn_data, send_close)(MYSQLND_CONN_DATA * const conn TSR
Fall-through
*/
+ CONN_SET_STATE(conn, CONN_QUIT_SENT);
+ net->data->m.close_stream(net, conn->stats, conn->error_info TSRMLS_CC);
+ /* Fall-through */
case CONN_QUIT_SENT:
/* The user has killed its own connection */
break;
}
- /*
- We hold one reference, and every other object which needs the
- connection does increase it by 1.
- */
- CONN_SET_STATE(conn, CONN_QUIT_SENT);
DBG_RETURN(ret);
}
@@ -2005,6 +2121,7 @@ MYSQLND_METHOD(mysqlnd_conn_data, next_result)(MYSQLND_CONN_DATA * const conn TS
DBG_ERR_FMT("Serious error. %s::%u", __FILE__, __LINE__);
php_error_docref(NULL TSRMLS_CC, E_WARNING, "Serious error. PID=%d", getpid());
CONN_SET_STATE(conn, CONN_QUIT_SENT);
+ conn->m->send_close(conn TSRMLS_CC);
} else {
DBG_INF_FMT("Error from the server : (%u) %s", conn->error_info->error_no, conn->error_info->error);
}
@@ -2084,13 +2201,7 @@ MYSQLND_METHOD(mysqlnd_conn_data, change_user)(MYSQLND_CONN_DATA * const conn,
TSRMLS_DC)
{
size_t this_func = STRUCT_OFFSET(struct st_mysqlnd_conn_data_methods, change_user);
- /*
- User could be max 16 * 3 (utf8), pass is 20 usually, db is up to 64*3
- Stack space is not that expensive, so use a bit more to be protected against
- buffer overflows.
- */
enum_func_status ret = FAIL;
- zend_bool local_tx_started = FALSE;
DBG_ENTER("mysqlnd_conn_data::change_user");
DBG_INF_FMT("conn=%llu user=%s passwd=%s db=%s silent=%u",
@@ -2099,7 +2210,6 @@ MYSQLND_METHOD(mysqlnd_conn_data, change_user)(MYSQLND_CONN_DATA * const conn,
if (PASS != conn->m->local_tx_start(conn, this_func TSRMLS_CC)) {
goto end;
}
- local_tx_started = TRUE;
SET_EMPTY_ERROR(*conn->error_info);
SET_ERROR_AFF_ROWS(conn);
@@ -2112,122 +2222,20 @@ MYSQLND_METHOD(mysqlnd_conn_data, change_user)(MYSQLND_CONN_DATA * const conn,
}
if (!db) {
db = "";
- }
-
- {
- zend_bool first_call = TRUE;
- char * switch_to_auth_protocol = NULL;
- size_t switch_to_auth_protocol_len = 0;
- char * requested_protocol = NULL;
- zend_uchar * plugin_data;
- size_t plugin_data_len;
-
- plugin_data_len = conn->auth_plugin_data_len;
- plugin_data = mnd_emalloc(plugin_data_len);
- if (!plugin_data) {
- ret = FAIL;
- goto end;
- }
- memcpy(plugin_data, conn->auth_plugin_data, plugin_data_len);
-
- requested_protocol = mnd_pestrdup(conn->options->auth_protocol? conn->options->auth_protocol:"mysql_native_password", FALSE);
- if (!requested_protocol) {
- ret = FAIL;
- goto end;
- }
-
- do {
- struct st_mysqlnd_authentication_plugin * auth_plugin;
- {
- char * plugin_name = NULL;
-
- mnd_sprintf(&plugin_name, 0, "auth_plugin_%s", requested_protocol);
-
- DBG_INF_FMT("looking for %s auth plugin", plugin_name);
- auth_plugin = mysqlnd_plugin_find(plugin_name);
- mnd_sprintf_free(plugin_name);
-
- if (!auth_plugin) {
- php_error_docref(NULL TSRMLS_CC, E_WARNING, "The server requested authentication method unknown to the client [%s]", requested_protocol);
- SET_CLIENT_ERROR(*conn->error_info, CR_NOT_IMPLEMENTED, UNKNOWN_SQLSTATE, "The server requested authentication method umknown to the client");
- break;
- }
- }
- DBG_INF("plugin found");
-
- {
- zend_uchar * switch_to_auth_protocol_data = NULL;
- size_t switch_to_auth_protocol_data_len = 0;
- zend_uchar * scrambled_data = NULL;
- size_t scrambled_data_len = 0;
-
- switch_to_auth_protocol = NULL;
- switch_to_auth_protocol_len = 0;
-
- if (conn->auth_plugin_data) {
- mnd_pefree(conn->auth_plugin_data, conn->persistent);
- conn->auth_plugin_data = NULL;
- }
- conn->auth_plugin_data_len = plugin_data_len;
- conn->auth_plugin_data = mnd_pemalloc(conn->auth_plugin_data_len, conn->persistent);
- if (!conn->auth_plugin_data) {
- SET_OOM_ERROR(*conn->error_info);
- ret = FAIL;
- goto end;
- }
- memcpy(conn->auth_plugin_data, plugin_data, plugin_data_len);
-
- DBG_INF_FMT("salt=[%*s]", plugin_data_len - 1, plugin_data);
-
- /* The data should be allocated with malloc() */
- scrambled_data =
- auth_plugin->methods.get_auth_data(NULL, &scrambled_data_len, conn, user, passwd, passwd_len,
- plugin_data, plugin_data_len, 0, conn->server_capabilities TSRMLS_CC);
+ }
- ret = mysqlnd_auth_change_user(conn, user, strlen(user), passwd, passwd_len, db, strlen(db), silent,
- first_call,
- requested_protocol,
- scrambled_data, scrambled_data_len,
- &switch_to_auth_protocol, &switch_to_auth_protocol_len,
- &switch_to_auth_protocol_data, &switch_to_auth_protocol_data_len
- TSRMLS_CC);
-
- first_call = FALSE;
- free(scrambled_data);
+ /* XXX: passwords that have \0 inside work during auth, but in this case won't work with change user */
+ ret = mysqlnd_run_authentication(conn, user, passwd, strlen(passwd), db, strlen(db),
+ conn->auth_plugin_data, conn->auth_plugin_data_len, conn->options->auth_protocol,
+ 0 /*charset not used*/, conn->options, conn->server_capabilities, silent, TRUE/*is_change*/ TSRMLS_CC);
- DBG_INF_FMT("switch_to_auth_protocol=%s", switch_to_auth_protocol? switch_to_auth_protocol:"n/a");
- if (requested_protocol) {
- mnd_efree(requested_protocol);
- }
- requested_protocol = switch_to_auth_protocol;
-
- if (plugin_data) {
- mnd_efree(plugin_data);
- }
- plugin_data_len = switch_to_auth_protocol_data_len;
- plugin_data = switch_to_auth_protocol_data;
- }
- DBG_INF_FMT("conn->error_info->error_no = %d", conn->error_info->error_no);
- } while (ret == FAIL && conn->error_info->error_no == 0 && switch_to_auth_protocol != NULL);
- if (plugin_data) {
- mnd_efree(plugin_data);
- }
- if (ret == PASS) {
- conn->m->set_client_option(conn, MYSQLND_OPT_AUTH_PROTOCOL, requested_protocol TSRMLS_CC);
- }
- if (requested_protocol) {
- mnd_efree(requested_protocol);
- }
- }
/*
Here we should close all statements. Unbuffered queries should not be a
problem as we won't allow sending COM_CHANGE_USER.
*/
+ conn->m->local_tx_end(conn, this_func, ret TSRMLS_CC);
end:
- if (TRUE == local_tx_started) {
- conn->m->local_tx_end(conn, this_func, ret TSRMLS_CC);
- }
DBG_INF(ret == PASS? "PASS":"FAIL");
DBG_RETURN(ret);
}
@@ -2264,7 +2272,7 @@ 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->net->m.set_client_option(conn->net, option, value TSRMLS_CC);
+ ret = conn->net->data->m.set_client_option(conn->net, option, value TSRMLS_CC);
break;
#if MYSQLND_UNICODE
case MYSQLND_OPT_NUMERIC_AND_DATETIME_AS_UNICODE:
@@ -2643,7 +2651,12 @@ MYSQLND_CLASS_METHODS_START(mysqlnd_conn_data)
MYSQLND_METHOD(mysqlnd_conn_data, tx_commit),
MYSQLND_METHOD(mysqlnd_conn_data, tx_rollback),
MYSQLND_METHOD(mysqlnd_conn_data, local_tx_start),
- MYSQLND_METHOD(mysqlnd_conn_data, local_tx_end)
+ MYSQLND_METHOD(mysqlnd_conn_data, local_tx_end),
+ MYSQLND_METHOD(mysqlnd_conn_data, execute_init_commands),
+ MYSQLND_METHOD(mysqlnd_conn_data, get_updated_connect_flags),
+ MYSQLND_METHOD(mysqlnd_conn_data, connect_handshake),
+ MYSQLND_METHOD(mysqlnd_conn_data, simple_command_send_request),
+ MYSQLND_METHOD(mysqlnd_conn_data, fetch_auth_plugin_by_name)
MYSQLND_CLASS_METHODS_END;
diff --git a/ext/mysqlnd/mysqlnd.h b/ext/mysqlnd/mysqlnd.h
index b0b3b15c69..33338cfc80 100644
--- a/ext/mysqlnd/mysqlnd.h
+++ b/ext/mysqlnd/mysqlnd.h
@@ -22,10 +22,10 @@
#ifndef MYSQLND_H
#define MYSQLND_H
-#define MYSQLND_VERSION "mysqlnd 5.0.10 - 20111026 - $Id$"
-#define MYSQLND_VERSION_ID 50010
+#define MYSQLND_VERSION "mysqlnd 5.0.11-dev - 20120503 - $Id$"
+#define MYSQLND_VERSION_ID 50011
-#define MYSQLND_PLUGIN_API_VERSION 1
+#define MYSQLND_PLUGIN_API_VERSION 2
#define MYSQLND_STRING_TO_INT_CONVERSION
/*
diff --git a/ext/mysqlnd/mysqlnd_alloc.c b/ext/mysqlnd/mysqlnd_alloc.c
index 06e979a6e1..f156137cd9 100644
--- a/ext/mysqlnd/mysqlnd_alloc.c
+++ b/ext/mysqlnd/mysqlnd_alloc.c
@@ -65,8 +65,8 @@ const char * mysqlnd_debug_std_no_trace_funcs[] =
#if ZEND_DEBUG
#else
-#define __zend_filename "/unknown/unknown"
-#define __zend_lineno 0
+#define __zend_orig_filename "/unknown/unknown"
+#define __zend_orig_lineno 0
#endif
#define REAL_SIZE(s) (collect_memory_statistics? (s) + sizeof(size_t) : (s))
@@ -83,13 +83,13 @@ void * _mysqlnd_emalloc(size_t size MYSQLND_MEM_D)
#endif
DBG_ENTER(mysqlnd_emalloc_name);
- DBG_INF_FMT("file=%-15s line=%4d", strrchr(__zend_filename, PHP_DIR_SEPARATOR) + 1, __zend_lineno);
+ DBG_INF_FMT("file=%-15s line=%4d", strrchr(__zend_orig_filename, PHP_DIR_SEPARATOR) + 1, __zend_orig_lineno);
#if PHP_DEBUG
/* -1 is also "true" */
if (*threshold) {
#endif
- ret = emalloc(REAL_SIZE(size));
+ ret = _emalloc(REAL_SIZE(size) ZEND_FILE_LINE_CC ZEND_FILE_LINE_ORIG_RELAY_CC);
#if PHP_DEBUG
--*threshold;
} else if (*threshold == 0) {
@@ -117,13 +117,13 @@ void * _mysqlnd_pemalloc(size_t size, zend_bool persistent MYSQLND_MEM_D)
long * threshold = persistent? &MYSQLND_G(debug_malloc_fail_threshold):&MYSQLND_G(debug_emalloc_fail_threshold);
#endif
DBG_ENTER(mysqlnd_pemalloc_name);
- DBG_INF_FMT("file=%-15s line=%4d", strrchr(__zend_filename, PHP_DIR_SEPARATOR) + 1, __zend_lineno);
+ DBG_INF_FMT("file=%-15s line=%4d", strrchr(__zend_orig_filename, PHP_DIR_SEPARATOR) + 1, __zend_orig_lineno);
#if PHP_DEBUG
/* -1 is also "true" */
if (*threshold) {
#endif
- ret = pemalloc(REAL_SIZE(size), persistent);
+ ret = (persistent) ? __zend_malloc(REAL_SIZE(size)) : _emalloc(REAL_SIZE(size) ZEND_FILE_LINE_CC ZEND_FILE_LINE_ORIG_RELAY_CC);
#if PHP_DEBUG
--*threshold;
} else if (*threshold == 0) {
@@ -154,14 +154,14 @@ void * _mysqlnd_ecalloc(unsigned int nmemb, size_t size MYSQLND_MEM_D)
long * threshold = &MYSQLND_G(debug_ecalloc_fail_threshold);
#endif
DBG_ENTER(mysqlnd_ecalloc_name);
- DBG_INF_FMT("file=%-15s line=%4d", strrchr(__zend_filename, PHP_DIR_SEPARATOR) + 1, __zend_lineno);
+ DBG_INF_FMT("file=%-15s line=%4d", strrchr(__zend_orig_filename, PHP_DIR_SEPARATOR) + 1, __zend_orig_lineno);
DBG_INF_FMT("before: %lu", zend_memory_usage(FALSE TSRMLS_CC));
#if PHP_DEBUG
/* -1 is also "true" */
if (*threshold) {
#endif
- ret = ecalloc(nmemb, REAL_SIZE(size));
+ ret = _ecalloc(nmemb, REAL_SIZE(size) ZEND_FILE_LINE_CC ZEND_FILE_LINE_ORIG_RELAY_CC);
#if PHP_DEBUG
--*threshold;
} else if (*threshold == 0) {
@@ -189,13 +189,13 @@ void * _mysqlnd_pecalloc(unsigned int nmemb, size_t size, zend_bool persistent M
long * threshold = persistent? &MYSQLND_G(debug_calloc_fail_threshold):&MYSQLND_G(debug_ecalloc_fail_threshold);
#endif
DBG_ENTER(mysqlnd_pecalloc_name);
- DBG_INF_FMT("file=%-15s line=%4d", strrchr(__zend_filename, PHP_DIR_SEPARATOR) + 1, __zend_lineno);
+ DBG_INF_FMT("file=%-15s line=%4d", strrchr(__zend_orig_filename, PHP_DIR_SEPARATOR) + 1, __zend_orig_lineno);
#if PHP_DEBUG
/* -1 is also "true" */
if (*threshold) {
#endif
- ret = pecalloc(nmemb, REAL_SIZE(size), persistent);
+ ret = (persistent) ? __zend_calloc(nmemb, REAL_SIZE(size)) : _ecalloc(nmemb, REAL_SIZE(size) ZEND_FILE_LINE_CC ZEND_FILE_LINE_ORIG_RELAY_CC);
#if PHP_DEBUG
--*threshold;
} else if (*threshold == 0) {
@@ -227,14 +227,14 @@ void * _mysqlnd_erealloc(void *ptr, size_t new_size MYSQLND_MEM_D)
long * threshold = &MYSQLND_G(debug_erealloc_fail_threshold);
#endif
DBG_ENTER(mysqlnd_erealloc_name);
- DBG_INF_FMT("file=%-15s line=%4d", strrchr(__zend_filename, PHP_DIR_SEPARATOR) + 1, __zend_lineno);
+ DBG_INF_FMT("file=%-15s line=%4d", strrchr(__zend_orig_filename, PHP_DIR_SEPARATOR) + 1, __zend_orig_lineno);
DBG_INF_FMT("ptr=%p old_size=%lu, new_size=%lu", ptr, old_size, new_size);
#if PHP_DEBUG
/* -1 is also "true" */
if (*threshold) {
#endif
- ret = erealloc(REAL_PTR(ptr), REAL_SIZE(new_size));
+ ret = _erealloc(REAL_PTR(ptr), REAL_SIZE(new_size), 0 ZEND_FILE_LINE_CC ZEND_FILE_LINE_ORIG_RELAY_CC);
#if PHP_DEBUG
--*threshold;
} else if (*threshold == 0) {
@@ -262,7 +262,7 @@ void * _mysqlnd_perealloc(void *ptr, size_t new_size, zend_bool persistent MYSQL
long * threshold = persistent? &MYSQLND_G(debug_realloc_fail_threshold):&MYSQLND_G(debug_erealloc_fail_threshold);
#endif
DBG_ENTER(mysqlnd_perealloc_name);
- DBG_INF_FMT("file=%-15s line=%4d", strrchr(__zend_filename, PHP_DIR_SEPARATOR) + 1, __zend_lineno);
+ DBG_INF_FMT("file=%-15s line=%4d", strrchr(__zend_orig_filename, PHP_DIR_SEPARATOR) + 1, __zend_orig_lineno);
DBG_INF_FMT("ptr=%p old_size=%lu new_size=%lu persistent=%u", ptr, old_size, new_size, persistent);
#if PHP_DEBUG
@@ -296,7 +296,7 @@ void _mysqlnd_efree(void *ptr MYSQLND_MEM_D)
size_t free_amount = 0;
zend_bool collect_memory_statistics = MYSQLND_G(collect_memory_statistics);
DBG_ENTER(mysqlnd_efree_name);
- DBG_INF_FMT("file=%-15s line=%4d", strrchr(__zend_filename, PHP_DIR_SEPARATOR) + 1, __zend_lineno);
+ DBG_INF_FMT("file=%-15s line=%4d", strrchr(__zend_orig_filename, PHP_DIR_SEPARATOR) + 1, __zend_orig_lineno);
DBG_INF_FMT("ptr=%p", ptr);
if (ptr) {
@@ -304,7 +304,7 @@ void _mysqlnd_efree(void *ptr MYSQLND_MEM_D)
free_amount = *(size_t *)(((char*)ptr) - sizeof(size_t));
DBG_INF_FMT("ptr=%p size=%u", ((char*)ptr) - sizeof(size_t), (unsigned int) free_amount);
}
- efree(REAL_PTR(ptr));
+ _efree(REAL_PTR(ptr) ZEND_FILE_LINE_CC ZEND_FILE_LINE_ORIG_RELAY_CC);
}
if (collect_memory_statistics) {
@@ -321,7 +321,7 @@ void _mysqlnd_pefree(void *ptr, zend_bool persistent MYSQLND_MEM_D)
size_t free_amount = 0;
zend_bool collect_memory_statistics = MYSQLND_G(collect_memory_statistics);
DBG_ENTER(mysqlnd_pefree_name);
- DBG_INF_FMT("file=%-15s line=%4d", strrchr(__zend_filename, PHP_DIR_SEPARATOR) + 1, __zend_lineno);
+ DBG_INF_FMT("file=%-15s line=%4d", strrchr(__zend_orig_filename, PHP_DIR_SEPARATOR) + 1, __zend_orig_lineno);
DBG_INF_FMT("ptr=%p persistent=%u", ptr, persistent);
if (ptr) {
@@ -329,7 +329,7 @@ void _mysqlnd_pefree(void *ptr, zend_bool persistent MYSQLND_MEM_D)
free_amount = *(size_t *)(((char*)ptr) - sizeof(size_t));
DBG_INF_FMT("ptr=%p size=%u", ((char*)ptr) - sizeof(size_t), (unsigned int) free_amount);
}
- pefree(REAL_PTR(ptr), persistent);
+ (persistent) ? free(REAL_PTR(ptr)) : _efree(REAL_PTR(ptr) ZEND_FILE_LINE_CC ZEND_FILE_LINE_ORIG_RELAY_CC);
}
if (collect_memory_statistics) {
@@ -338,6 +338,7 @@ void _mysqlnd_pefree(void *ptr, zend_bool persistent MYSQLND_MEM_D)
}
DBG_VOID_RETURN;
}
+/* }}} */
/* {{{ _mysqlnd_malloc */
@@ -349,7 +350,7 @@ void * _mysqlnd_malloc(size_t size MYSQLND_MEM_D)
long * threshold = &MYSQLND_G(debug_malloc_fail_threshold);
#endif
DBG_ENTER(mysqlnd_malloc_name);
- DBG_INF_FMT("file=%-15s line=%4d", strrchr(__zend_filename, PHP_DIR_SEPARATOR) + 1, __zend_lineno);
+ DBG_INF_FMT("file=%-15s line=%4d", strrchr(__zend_orig_filename, PHP_DIR_SEPARATOR) + 1, __zend_orig_lineno);
#if PHP_DEBUG
/* -1 is also "true" */
@@ -382,7 +383,7 @@ void * _mysqlnd_calloc(unsigned int nmemb, size_t size MYSQLND_MEM_D)
long * threshold = &MYSQLND_G(debug_calloc_fail_threshold);
#endif
DBG_ENTER(mysqlnd_calloc_name);
- DBG_INF_FMT("file=%-15s line=%4d", strrchr(__zend_filename, PHP_DIR_SEPARATOR) + 1, __zend_lineno);
+ DBG_INF_FMT("file=%-15s line=%4d", strrchr(__zend_orig_filename, PHP_DIR_SEPARATOR) + 1, __zend_orig_lineno);
#if PHP_DEBUG
/* -1 is also "true" */
@@ -415,7 +416,7 @@ void * _mysqlnd_realloc(void *ptr, size_t new_size MYSQLND_MEM_D)
long * threshold = &MYSQLND_G(debug_realloc_fail_threshold);
#endif
DBG_ENTER(mysqlnd_realloc_name);
- DBG_INF_FMT("file=%-15s line=%4d", strrchr(__zend_filename, PHP_DIR_SEPARATOR) + 1, __zend_lineno);
+ DBG_INF_FMT("file=%-15s line=%4d", strrchr(__zend_orig_filename, PHP_DIR_SEPARATOR) + 1, __zend_orig_lineno);
DBG_INF_FMT("ptr=%p new_size=%lu ", new_size, ptr);
DBG_INF_FMT("before: %lu", zend_memory_usage(TRUE TSRMLS_CC));
@@ -448,7 +449,7 @@ void _mysqlnd_free(void *ptr MYSQLND_MEM_D)
size_t free_amount = 0;
zend_bool collect_memory_statistics = MYSQLND_G(collect_memory_statistics);
DBG_ENTER(mysqlnd_free_name);
- DBG_INF_FMT("file=%-15s line=%4d", strrchr(__zend_filename, PHP_DIR_SEPARATOR) + 1, __zend_lineno);
+ DBG_INF_FMT("file=%-15s line=%4d", strrchr(__zend_orig_filename, PHP_DIR_SEPARATOR) + 1, __zend_orig_lineno);
DBG_INF_FMT("ptr=%p", ptr);
if (ptr) {
@@ -477,10 +478,10 @@ char * _mysqlnd_pestrndup(const char * const ptr, size_t length, zend_bool persi
char * ret;
zend_bool collect_memory_statistics = MYSQLND_G(collect_memory_statistics);
DBG_ENTER(mysqlnd_pestrndup_name);
- DBG_INF_FMT("file=%-15s line=%4d", strrchr(__zend_filename, PHP_DIR_SEPARATOR) + 1, __zend_lineno);
+ DBG_INF_FMT("file=%-15s line=%4d", strrchr(__zend_orig_filename, PHP_DIR_SEPARATOR) + 1, __zend_orig_lineno);
DBG_INF_FMT("ptr=%p", ptr);
- ret = pemalloc(REAL_SIZE(length) + 1, persistent);
+ ret = (persistent) ? __zend_malloc(REAL_SIZE(length + 1)) : _emalloc(REAL_SIZE(length + 1) ZEND_FILE_LINE_CC ZEND_FILE_LINE_ORIG_RELAY_CC);
{
size_t l = length;
char * p = (char *) ptr;
@@ -509,13 +510,13 @@ char * _mysqlnd_pestrdup(const char * const ptr, zend_bool persistent MYSQLND_ME
const char * p = ptr;
zend_bool collect_memory_statistics = MYSQLND_G(collect_memory_statistics);
DBG_ENTER(mysqlnd_pestrdup_name);
- DBG_INF_FMT("file=%-15s line=%4d", strrchr(__zend_filename, PHP_DIR_SEPARATOR) + 1, __zend_lineno);
+ DBG_INF_FMT("file=%-15s line=%4d", strrchr(__zend_orig_filename, PHP_DIR_SEPARATOR) + 1, __zend_orig_lineno);
DBG_INF_FMT("ptr=%p", ptr);
do {
smart_str_appendc(&tmp_str, *p);
} while (*p++);
- ret = pemalloc(tmp_str.len + sizeof(size_t), persistent);
+ ret = (persistent) ? __zend_malloc(tmp_str.len + sizeof(size_t)) : _emalloc(REAL_SIZE(tmp_str.len + sizeof(size_t)) ZEND_FILE_LINE_CC ZEND_FILE_LINE_ORIG_RELAY_CC);
memcpy(FAKE_PTR(ret), tmp_str.c, tmp_str.len);
if (ret && collect_memory_statistics) {
@@ -549,7 +550,7 @@ PHPAPI void _mysqlnd_sprintf_free(char * p)
}
/* }}} */
-
+/* {{{ _mysqlnd_vsprintf */
PHPAPI int _mysqlnd_vsprintf(char ** pbuf, size_t max_len, const char * format, va_list ap)
{
return vspprintf(pbuf, max_len, format, ap);
diff --git a/ext/mysqlnd/mysqlnd_alloc.h b/ext/mysqlnd/mysqlnd_alloc.h
index 673d4f6dae..8d0e3bfacc 100644
--- a/ext/mysqlnd/mysqlnd_alloc.h
+++ b/ext/mysqlnd/mysqlnd_alloc.h
@@ -26,8 +26,8 @@
extern const char * mysqlnd_debug_std_no_trace_funcs[];
-#define MYSQLND_MEM_D TSRMLS_DC ZEND_FILE_LINE_DC ZEND_FILE_LINE_ORIG_DC
-#define MYSQLND_MEM_C TSRMLS_CC ZEND_FILE_LINE_CC ZEND_FILE_LINE_EMPTY_CC
+#define MYSQLND_MEM_D TSRMLS_DC ZEND_FILE_LINE_ORIG_DC
+#define MYSQLND_MEM_C TSRMLS_CC ZEND_FILE_LINE_CC
struct st_mysqlnd_allocator_methods
{
diff --git a/ext/mysqlnd/mysqlnd_debug.h b/ext/mysqlnd/mysqlnd_debug.h
index d805178e26..5d2d1d2867 100644
--- a/ext/mysqlnd/mysqlnd_debug.h
+++ b/ext/mysqlnd/mysqlnd_debug.h
@@ -117,6 +117,7 @@ PHPAPI char * mysqlnd_get_backtrace(uint max_levels, size_t * length TSRMLS_DC);
if ((dbg_obj)) { \
dbg_skip_trace = !(dbg_obj)->m->func_enter((dbg_obj), __LINE__, __FILE__, func_name, strlen(func_name)); \
} \
+ if (dbg_skip_trace); /* shut compiler's mouth */ \
do { \
if ((dbg_obj) && (dbg_obj)->flags & MYSQLND_DEBUG_PROFILE_CALLS) { \
DBG_PROFILE_START_TIME(); \
@@ -141,7 +142,7 @@ PHPAPI char * mysqlnd_get_backtrace(uint max_levels, size_t * length TSRMLS_DC);
-#else
+#else /* defined(__GNUC__) || (defined(_MSC_VER) && (_MSC_VER >= 1400)) */
static inline void DBG_INF_EX(MYSQLND_DEBUG * dbg_obj, const char * const msg) {}
static inline void DBG_ERR_EX(MYSQLND_DEBUG * dbg_obj, const char * const msg) {}
static inline void DBG_INF_FMT_EX(MYSQLND_DEBUG * dbg_obj, ...) {}
diff --git a/ext/mysqlnd/mysqlnd_driver.c b/ext/mysqlnd/mysqlnd_driver.c
index aeb34a66ef..e55a0bc2ee 100644
--- a/ext/mysqlnd/mysqlnd_driver.c
+++ b/ext/mysqlnd/mysqlnd_driver.c
@@ -91,6 +91,7 @@ PHPAPI void mysqlnd_library_init(TSRMLS_D)
/* }}} */
+
/* {{{ mysqlnd_error_list_pdtor */
static void
mysqlnd_error_list_pdtor(void * pDest)
@@ -248,17 +249,29 @@ MYSQLND_METHOD(mysqlnd_object_factory, get_prepared_statement)(MYSQLND_CONN_DATA
PHPAPI MYSQLND_NET *
MYSQLND_METHOD(mysqlnd_object_factory, get_io_channel)(zend_bool persistent, MYSQLND_STATS * stats, MYSQLND_ERROR_INFO * error_info TSRMLS_DC)
{
- size_t alloc_size = sizeof(MYSQLND_NET) + mysqlnd_plugin_count() * sizeof(void *);
- MYSQLND_NET * net = mnd_pecalloc(1, alloc_size, persistent);
+ 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_INF_FMT("persistent=%u", persistent);
- if (net) {
- net->persistent = persistent;
- net->m = *mysqlnd_net_get_methods();
+ if (net && net_data) {
+ net->data = net_data;
+ net->persistent = net->data->persistent = persistent;
+ net->data->m = *mysqlnd_net_get_methods();
- if (PASS != net->m.init(net, stats, error_info TSRMLS_CC)) {
- net->m.dtor(net, stats, error_info TSRMLS_CC);
+ if (PASS != net->data->m.init(net, stats, error_info TSRMLS_CC)) {
+ net->data->m.dtor(net, stats, error_info TSRMLS_CC);
+ net = NULL;
+ }
+ } else {
+ if (net_data) {
+ mnd_pefree(net_data, persistent);
+ net_data = NULL;
+ }
+ if (net) {
+ mnd_pefree(net, persistent);
net = NULL;
}
}
@@ -268,7 +281,7 @@ MYSQLND_METHOD(mysqlnd_object_factory, get_io_channel)(zend_bool persistent, MYS
/* {{{ mysqlnd_object_factory::get_protocol_decoder */
-PHPAPI MYSQLND_PROTOCOL *
+static MYSQLND_PROTOCOL *
MYSQLND_METHOD(mysqlnd_object_factory, get_protocol_decoder)(zend_bool persistent TSRMLS_DC)
{
size_t alloc_size = sizeof(MYSQLND_PROTOCOL) + mysqlnd_plugin_count() * sizeof(void *);
@@ -286,7 +299,7 @@ MYSQLND_METHOD(mysqlnd_object_factory, get_protocol_decoder)(zend_bool persisten
/* }}} */
-MYSQLND_CLASS_METHODS_START(mysqlnd_object_factory)
+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),
diff --git a/ext/mysqlnd/mysqlnd_enum_n_def.h b/ext/mysqlnd/mysqlnd_enum_n_def.h
index b0fe88648e..c8daa0c79b 100644
--- a/ext/mysqlnd/mysqlnd_enum_n_def.h
+++ b/ext/mysqlnd/mysqlnd_enum_n_def.h
@@ -37,6 +37,8 @@
#define MYSQLND_ASSEMBLED_PACKET_MAX_SIZE 3UL*1024UL*1024UL*1024UL
+#define MYSQLND_DEFAULT_AUTH_PROTOCOL "mysql_native_password"
+
#define MYSQLND_ERRMSG_SIZE 512
#define MYSQLND_SQLSTATE_LENGTH 5
#define MYSQLND_SQLSTATE_NULL "00000"
diff --git a/ext/mysqlnd/mysqlnd_ext_plugin.c b/ext/mysqlnd/mysqlnd_ext_plugin.c
index 02cd9a891f..2eacac5286 100644
--- a/ext/mysqlnd/mysqlnd_ext_plugin.c
+++ b/ext/mysqlnd/mysqlnd_ext_plugin.c
@@ -215,7 +215,6 @@ mysqlnd_net_set_methods(struct st_mysqlnd_net_methods * methods)
/* }}} */
-
/*
* Local variables:
* tab-width: 4
diff --git a/ext/mysqlnd/mysqlnd_loaddata.c b/ext/mysqlnd/mysqlnd_loaddata.c
index 8e8622e540..61cf235988 100644
--- a/ext/mysqlnd/mysqlnd_loaddata.c
+++ b/ext/mysqlnd/mysqlnd_loaddata.c
@@ -172,7 +172,7 @@ mysqlnd_handle_local_infile(MYSQLND_CONN_DATA * conn, const char * filename, zen
if (!(conn->options->flags & CLIENT_LOCAL_FILES)) {
php_error_docref(NULL TSRMLS_CC, E_WARNING, "LOAD DATA LOCAL INFILE forbidden");
/* write empty packet to server */
- ret = net->m.send_ex(net, empty_packet, 0, conn->stats, conn->error_info TSRMLS_CC);
+ ret = net->data->m.send_ex(net, empty_packet, 0, conn->stats, conn->error_info TSRMLS_CC);
*is_warning = TRUE;
goto infile_error;
}
@@ -192,13 +192,13 @@ mysqlnd_handle_local_infile(MYSQLND_CONN_DATA * conn, const char * filename, zen
tmp_error_no = infile.local_infile_error(info, tmp_buf, sizeof(tmp_buf) TSRMLS_CC);
SET_CLIENT_ERROR(*conn->error_info, tmp_error_no, UNKNOWN_SQLSTATE, tmp_buf);
/* write empty packet to server */
- ret = net->m.send_ex(net, empty_packet, 0, conn->stats, conn->error_info TSRMLS_CC);
+ ret = net->data->m.send_ex(net, empty_packet, 0, conn->stats, conn->error_info TSRMLS_CC);
goto infile_error;
}
/* read data */
while ((bufsize = infile.local_infile_read (info, buf + MYSQLND_HEADER_SIZE, buflen - MYSQLND_HEADER_SIZE TSRMLS_CC)) > 0) {
- if ((ret = net->m.send_ex(net, buf, bufsize, conn->stats, conn->error_info TSRMLS_CC)) == 0) {
+ if ((ret = net->data->m.send_ex(net, buf, bufsize, conn->stats, conn->error_info TSRMLS_CC)) == 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;
@@ -206,7 +206,7 @@ mysqlnd_handle_local_infile(MYSQLND_CONN_DATA * conn, const char * filename, zen
}
/* send empty packet for eof */
- if ((ret = net->m.send_ex(net, empty_packet, 0, conn->stats, conn->error_info TSRMLS_CC)) == 0) {
+ if ((ret = net->data->m.send_ex(net, empty_packet, 0, conn->stats, conn->error_info TSRMLS_CC)) == 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 800f577332..7458f76528 100644
--- a/ext/mysqlnd/mysqlnd_net.c
+++ b/ext/mysqlnd/mysqlnd_net.c
@@ -67,16 +67,17 @@ MYSQLND_METHOD(mysqlnd_net, network_read_ex)(MYSQLND_NET * const net, zend_uchar
MYSQLND_STATS * const stats, MYSQLND_ERROR_INFO * const error_info TSRMLS_DC)
{
enum_func_status return_value = PASS;
+ php_stream * net_stream = net->data->m.get_stream(net TSRMLS_CC);
+ size_t old_chunk_size = net_stream->chunk_size;
size_t to_read = count, ret;
- size_t old_chunk_size = net->stream->chunk_size;
zend_uchar * p = buffer;
DBG_ENTER("mysqlnd_net::network_read_ex");
DBG_INF_FMT("count="MYSQLND_SZ_T_SPEC, count);
- net->stream->chunk_size = MIN(to_read, net->options.net_read_buffer_size);
+ net_stream->chunk_size = MIN(to_read, net->data->options.net_read_buffer_size);
while (to_read) {
- if (!(ret = php_stream_read(net->stream, (char *) p, to_read))) {
+ if (!(ret = php_stream_read(net_stream, (char *) p, to_read))) {
DBG_ERR_FMT("Error while reading header from socket");
return_value = FAIL;
break;
@@ -85,7 +86,7 @@ MYSQLND_METHOD(mysqlnd_net, network_read_ex)(MYSQLND_NET * const net, zend_uchar
to_read -= ret;
}
MYSQLND_INC_CONN_STATISTIC_W_VALUE(stats, STAT_BYTES_RECEIVED, count - to_read);
- net->stream->chunk_size = old_chunk_size;
+ net_stream->chunk_size = old_chunk_size;
DBG_RETURN(return_value);
}
/* }}} */
@@ -98,13 +99,13 @@ MYSQLND_METHOD(mysqlnd_net, network_write_ex)(MYSQLND_NET * const net, const zen
{
size_t ret;
DBG_ENTER("mysqlnd_net::network_write_ex");
- ret = php_stream_write(net->stream, (char *)buffer, count);
+ ret = php_stream_write(net->data->m.get_stream(net TSRMLS_CC), (char *)buffer, count);
DBG_RETURN(ret);
}
/* }}} */
/* {{{ mysqlnd_net::open_pipe */
-static enum_func_status
+static php_stream *
MYSQLND_METHOD(mysqlnd_net, open_pipe)(MYSQLND_NET * const net, const char * const scheme, const size_t scheme_len,
const zend_bool persistent,
MYSQLND_STATS * const conn_stats, MYSQLND_ERROR_INFO * const error_info TSRMLS_DC)
@@ -114,32 +115,35 @@ MYSQLND_METHOD(mysqlnd_net, open_pipe)(MYSQLND_NET * const net, const char * con
#else
unsigned int streams_options = 0;
#endif
+ php_stream * net_stream = NULL;
+
DBG_ENTER("mysqlnd_net::open_pipe");
if (persistent) {
streams_options |= STREAM_OPEN_PERSISTENT;
}
streams_options |= IGNORE_URL;
- net->stream = php_stream_open_wrapper((char*) scheme + sizeof("pipe://") - 1, "r+", streams_options, NULL);
- if (!net->stream) {
+ net_stream = php_stream_open_wrapper((char*) scheme + sizeof("pipe://") - 1, "r+", streams_options, NULL);
+ if (!net_stream) {
SET_CLIENT_ERROR(*error_info, CR_CONNECTION_ERROR, UNKNOWN_SQLSTATE, "Unknown errror while connecting");
- DBG_RETURN(FAIL);
+ DBG_RETURN(NULL);
}
/*
Streams are not meant for C extensions! Thus we need a hack. Every connected stream will
be registered as resource (in EG(regular_list). So far, so good. However, it won't be
unregistered yntil the script ends. So, we need to take care of that.
*/
- net->stream->in_free = 1;
- zend_hash_index_del(&EG(regular_list), net->stream->rsrc_id);
- net->stream->in_free = 0;
+ net_stream->in_free = 1;
+ zend_hash_index_del(&EG(regular_list), net_stream->rsrc_id);
+ net_stream->in_free = 0;
- DBG_RETURN(PASS);
+
+ DBG_RETURN(net_stream);
}
/* }}} */
/* {{{ mysqlnd_net::open_tcp_or_unix */
-static enum_func_status
+static php_stream *
MYSQLND_METHOD(mysqlnd_net, open_tcp_or_unix)(MYSQLND_NET * const net, const char * const scheme, const size_t scheme_len,
const zend_bool persistent,
MYSQLND_STATS * const conn_stats, MYSQLND_ERROR_INFO * const error_info TSRMLS_DC)
@@ -155,24 +159,27 @@ MYSQLND_METHOD(mysqlnd_net, open_tcp_or_unix)(MYSQLND_NET * const net, const cha
char * errstr = NULL;
int errcode = 0;
struct timeval tv;
+ php_stream * net_stream = NULL;
DBG_ENTER("mysqlnd_net::open_tcp_or_unix");
+ net->data->stream = NULL;
+
if (persistent) {
hashed_details_len = mnd_sprintf(&hashed_details, 0, "%p", net);
DBG_INF_FMT("hashed_details=%s", hashed_details);
}
- if (net->options.timeout_connect) {
- tv.tv_sec = net->options.timeout_connect;
+ if (net->data->options.timeout_connect) {
+ tv.tv_sec = net->data->options.timeout_connect;
tv.tv_usec = 0;
}
DBG_INF_FMT("calling php_stream_xport_create");
- net->stream = php_stream_xport_create(scheme, scheme_len, streams_options, streams_flags,
- hashed_details, (net->options.timeout_connect) ? &tv : NULL,
+ net_stream = php_stream_xport_create(scheme, scheme_len, streams_options, streams_flags,
+ hashed_details, (net->data->options.timeout_connect) ? &tv : NULL,
NULL /*ctx*/, &errstr, &errcode);
- if (errstr || !net->stream) {
+ if (errstr || !net_stream) {
DBG_ERR("Error");
if (hashed_details) {
mnd_sprintf_free(hashed_details);
@@ -183,7 +190,7 @@ MYSQLND_METHOD(mysqlnd_net, open_tcp_or_unix)(MYSQLND_NET * const net, const cha
/* no mnd_ since we don't allocate it */
efree(errstr);
}
- DBG_RETURN(FAIL);
+ DBG_RETURN(NULL);
}
if (hashed_details) {
/*
@@ -199,13 +206,13 @@ MYSQLND_METHOD(mysqlnd_net, open_tcp_or_unix)(MYSQLND_NET * const net, const cha
but STREAMS suck big time regarding persistent streams.
Just not compatible for extensions that need persistency.
*/
- net->stream->in_free = 1;
+ net_stream->in_free = 1;
zend_hash_del(&EG(persistent_list), hashed_details, hashed_details_len + 1);
- net->stream->in_free = 0;
+ net_stream->in_free = 0;
}
#if ZEND_DEBUG
/* Shut-up the streams, they don't know what they are doing */
- net->stream->__exposed = 1;
+ net_stream->__exposed = 1;
#endif
mnd_sprintf_free(hashed_details);
}
@@ -215,33 +222,36 @@ MYSQLND_METHOD(mysqlnd_net, open_tcp_or_unix)(MYSQLND_NET * const net, const cha
be registered as resource (in EG(regular_list). So far, so good. However, it won't be
unregistered yntil the script ends. So, we need to take care of that.
*/
- net->stream->in_free = 1;
- zend_hash_index_del(&EG(regular_list), net->stream->rsrc_id);
- net->stream->in_free = 0;
+ net_stream->in_free = 1;
+ zend_hash_index_del(&EG(regular_list), net_stream->rsrc_id);
+ net_stream->in_free = 0;
- DBG_RETURN(PASS);
+ DBG_RETURN(net_stream);
}
/* }}} */
-/* {{{ mysqlnd_net::connect_ex */
+/* {{{ mysqlnd_net::post_connect_set_opt */
static void
MYSQLND_METHOD(mysqlnd_net, post_connect_set_opt)(MYSQLND_NET * const net,
const char * const scheme, const size_t scheme_len,
MYSQLND_STATS * const conn_stats, MYSQLND_ERROR_INFO * const error_info TSRMLS_DC)
{
+ php_stream * net_stream = net->data->m.get_stream(net TSRMLS_CC);
DBG_ENTER("mysqlnd_net::post_connect_set_opt");
- if (net->options.timeout_read) {
- struct timeval tv;
- DBG_INF_FMT("setting %u as PHP_STREAM_OPTION_READ_TIMEOUT", net->options.timeout_read);
- tv.tv_sec = net->options.timeout_read;
- tv.tv_usec = 0;
- php_stream_set_option(net->stream, PHP_STREAM_OPTION_READ_TIMEOUT, 0, &tv);
- }
+ if (net_stream) {
+ if (net->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;
+ tv.tv_usec = 0;
+ php_stream_set_option(net_stream, PHP_STREAM_OPTION_READ_TIMEOUT, 0, &tv);
+ }
- if (!memcmp(scheme, "tcp://", sizeof("tcp://") - 1)) {
- /* TCP -> Set TCP_NODELAY */
- mysqlnd_set_sock_no_delay(net->stream TSRMLS_CC);
+ if (!memcmp(scheme, "tcp://", sizeof("tcp://") - 1)) {
+ /* TCP -> Set TCP_NODELAY */
+ mysqlnd_set_sock_no_delay(net_stream TSRMLS_CC);
+ }
}
DBG_VOID_RETURN;
@@ -249,6 +259,31 @@ MYSQLND_METHOD(mysqlnd_net, post_connect_set_opt)(MYSQLND_NET * const net,
/* }}} */
+/* {{{ mysqlnd_net::get_open_stream */
+static func_mysqlnd_net__open_stream
+MYSQLND_METHOD(mysqlnd_net, get_open_stream)(MYSQLND_NET * const net, const char * const scheme, const size_t scheme_len,
+ MYSQLND_ERROR_INFO * const error_info TSRMLS_DC)
+{
+ func_mysqlnd_net__open_stream ret = NULL;
+ DBG_ENTER("mysqlnd_net::get_open_stream");
+ if (scheme_len > (sizeof("pipe://") - 1) && !memcmp(scheme, "pipe://", sizeof("pipe://") - 1)) {
+ ret = net->data->m.open_pipe;
+ } else if ((scheme_len > (sizeof("tcp://") - 1) && !memcmp(scheme, "tcp://", sizeof("tcp://") - 1))
+ ||
+ (scheme_len > (sizeof("unix://") - 1) && !memcmp(scheme, "unix://", sizeof("unix://") - 1)))
+ {
+ ret = net->data->m.open_tcp_or_unix;
+ }
+
+ if (!ret) {
+ SET_CLIENT_ERROR(*error_info, CR_CONNECTION_ERROR, UNKNOWN_SQLSTATE, "No handler for this scheme");
+ }
+
+ DBG_RETURN(ret);
+}
+/* }}} */
+
+
/* {{{ mysqlnd_net::connect_ex */
static enum_func_status
MYSQLND_METHOD(mysqlnd_net, connect_ex)(MYSQLND_NET * const net, const char * const scheme, const size_t scheme_len,
@@ -261,13 +296,16 @@ MYSQLND_METHOD(mysqlnd_net, connect_ex)(MYSQLND_NET * const net, const char * co
net->packet_no = net->compressed_envelope_packet_no = 0;
- net->m.close_stream(net, conn_stats, error_info TSRMLS_CC);
+ net->data->m.close_stream(net, conn_stats, error_info TSRMLS_CC);
- open_stream = (scheme_len > (sizeof("pipe://") - 1) && !memcmp(scheme, "pipe://", sizeof("pipe://") - 1))? net->m.open_pipe:
- net->m.open_tcp_or_unix;
-
- if (PASS == (ret = open_stream(net, scheme, scheme_len, persistent, conn_stats, error_info TSRMLS_CC))) {
- net->m.post_connect_set_opt(net, scheme, scheme_len, conn_stats, error_info TSRMLS_CC);
+ open_stream = net->data->m.get_open_stream(net, scheme, scheme_len, error_info TSRMLS_CC);
+ if (open_stream) {
+ php_stream * net_stream = open_stream(net, scheme, scheme_len, persistent, conn_stats, error_info TSRMLS_CC);
+ if (net_stream) {
+ (void) net->data->m.set_stream(net, net_stream TSRMLS_CC);
+ net->data->m.post_connect_set_opt(net, scheme, scheme_len, conn_stats, error_info TSRMLS_CC);
+ ret = PASS;
+ }
}
DBG_RETURN(ret);
@@ -309,9 +347,9 @@ MYSQLND_METHOD(mysqlnd_net, send_ex)(MYSQLND_NET * const net, zend_uchar * const
size_t to_be_sent;
DBG_ENTER("mysqlnd_net::send_ex");
- DBG_INF_FMT("count=" MYSQLND_SZ_T_SPEC " compression=%u", count, net->compressed);
+ DBG_INF_FMT("count=" MYSQLND_SZ_T_SPEC " compression=%u", count, net->data->compressed);
- if (net->compressed == TRUE) {
+ if (net->data->compressed == TRUE) {
size_t comp_buf_size = MYSQLND_HEADER_SIZE + COMPRESSED_HEADER_SIZE + MYSQLND_HEADER_SIZE + MIN(left, MYSQLND_MAX_PACKET_SIZE);
DBG_INF_FMT("compress_buf_size="MYSQLND_SZ_T_SPEC, comp_buf_size);
compress_buf = mnd_emalloc(comp_buf_size);
@@ -320,7 +358,7 @@ MYSQLND_METHOD(mysqlnd_net, send_ex)(MYSQLND_NET * const net, zend_uchar * const
do {
to_be_sent = MIN(left, MYSQLND_MAX_PACKET_SIZE);
#ifdef MYSQLND_COMPRESSION_ENABLED
- if (net->compressed == TRUE) {
+ if (net->data->compressed == TRUE) {
/* here we need to compress the data and then write it, first comes the compressed header */
size_t tmp_complen = to_be_sent;
size_t payload_size;
@@ -329,7 +367,7 @@ MYSQLND_METHOD(mysqlnd_net, send_ex)(MYSQLND_NET * const net, zend_uchar * const
STORE_HEADER_SIZE(safe_storage, uncompressed_payload);
int3store(uncompressed_payload, to_be_sent);
int1store(uncompressed_payload + 3, net->packet_no);
- if (PASS == net->m.encode((compress_buf + COMPRESSED_HEADER_SIZE + MYSQLND_HEADER_SIZE), &tmp_complen,
+ if (PASS == net->data->m.encode((compress_buf + COMPRESSED_HEADER_SIZE + MYSQLND_HEADER_SIZE), &tmp_complen,
uncompressed_payload, to_be_sent + MYSQLND_HEADER_SIZE TSRMLS_CC))
{
int3store(compress_buf + MYSQLND_HEADER_SIZE, to_be_sent + MYSQLND_HEADER_SIZE);
@@ -344,14 +382,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->m.network_write_ex(net, compress_buf, 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 TSRMLS_CC);
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->m.decode(decompressed_data, decompressed_size,
+ int error = net->data->m.decode(decompressed_data, decompressed_size,
compress_buf + MYSQLND_HEADER_SIZE + COMPRESSED_HEADER_SIZE, payload_size);
if (error == Z_OK) {
int i;
@@ -376,7 +414,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->m.network_write_ex(net, p, to_be_sent + MYSQLND_HEADER_SIZE, conn_stats, error_info TSRMLS_CC);
+ bytes_sent = net->data->m.network_write_ex(net, p, to_be_sent + MYSQLND_HEADER_SIZE, conn_stats, error_info TSRMLS_CC);
RESTORE_HEADER_SIZE(p, safe_storage);
net->compressed_envelope_packet_no++;
}
@@ -486,13 +524,13 @@ MYSQLND_METHOD(mysqlnd_net, read_compressed_packet_from_stream_and_fill_read_buf
(MYSQLND_NET * net, size_t net_payload_size, MYSQLND_STATS * conn_stats, MYSQLND_ERROR_INFO * error_info TSRMLS_DC)
{
size_t decompressed_size;
- enum_func_status ret = PASS;
+ enum_func_status retval = PASS;
zend_uchar * compressed_data = NULL;
zend_uchar comp_header[COMPRESSED_HEADER_SIZE];
DBG_ENTER("mysqlnd_net::read_compressed_packet_from_stream_and_fill_read_buffe");
/* Read the compressed header */
- if (FAIL == net->m.network_read_ex(net, comp_header, COMPRESSED_HEADER_SIZE, conn_stats, error_info TSRMLS_CC)) {
+ if (FAIL == net->data->m.network_read_ex(net, comp_header, COMPRESSED_HEADER_SIZE, conn_stats, error_info TSRMLS_CC)) {
DBG_RETURN(FAIL);
}
decompressed_size = uint3korr(comp_header);
@@ -502,20 +540,20 @@ 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->m.network_read_ex(net, compressed_data, net_payload_size, conn_stats, error_info TSRMLS_CC)) {
- ret = FAIL;
+ if (FAIL == net->data->m.network_read_ex(net, compressed_data, net_payload_size, conn_stats, error_info TSRMLS_CC)) {
+ retval = FAIL;
goto end;
}
net->uncompressed_data = mysqlnd_create_read_buffer(decompressed_size TSRMLS_CC);
- ret = net->m.decode(net->uncompressed_data->data, decompressed_size, compressed_data, net_payload_size TSRMLS_CC);
- if (ret == FAIL) {
+ retval = net->data->m.decode(net->uncompressed_data->data, decompressed_size, compressed_data, net_payload_size TSRMLS_CC);
+ if (FAIL == retval) {
goto end;
}
} 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 TSRMLS_CC);
- if (FAIL == net->m.network_read_ex(net, net->uncompressed_data->data, net_payload_size, conn_stats, error_info TSRMLS_CC)) {
- ret = FAIL;
+ if (FAIL == net->data->m.network_read_ex(net, net->uncompressed_data->data, net_payload_size, conn_stats, error_info TSRMLS_CC)) {
+ retval = FAIL;
goto end;
}
}
@@ -523,7 +561,7 @@ end:
if (compressed_data) {
mnd_efree(compressed_data);
}
- DBG_RETURN(ret);
+ DBG_RETURN(retval);
}
/* }}} */
#endif /* MYSQLND_COMPRESSION_ENABLED */
@@ -590,7 +628,7 @@ MYSQLND_METHOD(mysqlnd_net, receive_ex)(MYSQLND_NET * const net, zend_uchar * co
DBG_ENTER("mysqlnd_net::receive_ex");
#ifdef MYSQLND_COMPRESSION_ENABLED
- if (net->compressed) {
+ if (net->data->compressed) {
if (net->uncompressed_data) {
size_t to_read_from_buffer = MIN(net->uncompressed_data->bytes_left(net->uncompressed_data), to_read);
DBG_INF_FMT("reading %u from uncompressed_data buffer", to_read_from_buffer);
@@ -610,7 +648,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->m.network_read_ex(net, net_header, MYSQLND_HEADER_SIZE, conn_stats, error_info TSRMLS_CC)) {
+ if (FAIL == net->data->m.network_read_ex(net, net_header, MYSQLND_HEADER_SIZE, conn_stats, error_info TSRMLS_CC)) {
DBG_RETURN(FAIL);
}
net_payload_size = uint3korr(net_header);
@@ -628,7 +666,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, (unsigned long) net_payload_size);
#endif
/* Now let's read from the wire, decompress it and fill the read buffer */
- net->m.read_compressed_packet_from_stream_and_fill_read_buffer(net, net_payload_size, conn_stats, error_info TSRMLS_CC);
+ net->data->m.read_compressed_packet_from_stream_and_fill_read_buffer(net, net_payload_size, conn_stats, error_info TSRMLS_CC);
/*
Now a bit of recursion - read from the read buffer,
@@ -636,12 +674,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->m.receive_ex(net, p, to_read, conn_stats, error_info TSRMLS_CC));
+ DBG_RETURN(net->data->m.receive_ex(net, p, to_read, conn_stats, error_info TSRMLS_CC));
}
DBG_RETURN(PASS);
}
#endif /* MYSQLND_COMPRESSION_ENABLED */
- DBG_RETURN(net->m.network_read_ex(net, p, to_read, conn_stats, error_info TSRMLS_CC));
+ DBG_RETURN(net->data->m.network_read_ex(net, p, to_read, conn_stats, error_info TSRMLS_CC));
}
/* }}} */
@@ -668,80 +706,80 @@ MYSQLND_METHOD(mysqlnd_net, set_client_option)(MYSQLND_NET * const net, enum mys
break;
case MYSQLND_OPT_NET_READ_BUFFER_SIZE:
DBG_INF("MYSQLND_OPT_NET_READ_BUFFER_SIZE");
- net->options.net_read_buffer_size = *(unsigned int*) value;
- DBG_INF_FMT("new_length=%u", net->options.net_read_buffer_size);
+ net->data->options.net_read_buffer_size = *(unsigned int*) value;
+ DBG_INF_FMT("new_length=%u", net->data->options.net_read_buffer_size);
break;
case MYSQL_OPT_CONNECT_TIMEOUT:
DBG_INF("MYSQL_OPT_CONNECT_TIMEOUT");
- net->options.timeout_connect = *(unsigned int*) value;
+ net->data->options.timeout_connect = *(unsigned int*) value;
break;
case MYSQLND_OPT_SSL_KEY:
{
zend_bool pers = net->persistent;
- if (net->options.ssl_key) {
- mnd_pefree(net->options.ssl_key, pers);
+ if (net->data->options.ssl_key) {
+ mnd_pefree(net->data->options.ssl_key, pers);
}
- net->options.ssl_key = value? mnd_pestrdup(value, pers) : NULL;
+ net->data->options.ssl_key = value? mnd_pestrdup(value, pers) : NULL;
break;
}
case MYSQLND_OPT_SSL_CERT:
{
zend_bool pers = net->persistent;
- if (net->options.ssl_cert) {
- mnd_pefree(net->options.ssl_cert, pers);
+ if (net->data->options.ssl_cert) {
+ mnd_pefree(net->data->options.ssl_cert, pers);
}
- net->options.ssl_cert = value? mnd_pestrdup(value, pers) : NULL;
+ net->data->options.ssl_cert = value? mnd_pestrdup(value, pers) : NULL;
break;
}
case MYSQLND_OPT_SSL_CA:
{
zend_bool pers = net->persistent;
- if (net->options.ssl_ca) {
- mnd_pefree(net->options.ssl_ca, pers);
+ if (net->data->options.ssl_ca) {
+ mnd_pefree(net->data->options.ssl_ca, pers);
}
- net->options.ssl_ca = value? mnd_pestrdup(value, pers) : NULL;
+ net->data->options.ssl_ca = value? mnd_pestrdup(value, pers) : NULL;
break;
}
case MYSQLND_OPT_SSL_CAPATH:
{
zend_bool pers = net->persistent;
- if (net->options.ssl_capath) {
- mnd_pefree(net->options.ssl_capath, pers);
+ if (net->data->options.ssl_capath) {
+ mnd_pefree(net->data->options.ssl_capath, pers);
}
- net->options.ssl_capath = value? mnd_pestrdup(value, pers) : NULL;
+ net->data->options.ssl_capath = value? mnd_pestrdup(value, pers) : NULL;
break;
}
case MYSQLND_OPT_SSL_CIPHER:
{
zend_bool pers = net->persistent;
- if (net->options.ssl_cipher) {
- mnd_pefree(net->options.ssl_cipher, pers);
+ if (net->data->options.ssl_cipher) {
+ mnd_pefree(net->data->options.ssl_cipher, pers);
}
- net->options.ssl_cipher = value? mnd_pestrdup(value, pers) : NULL;
+ net->data->options.ssl_cipher = value? mnd_pestrdup(value, pers) : NULL;
break;
}
case MYSQLND_OPT_SSL_PASSPHRASE:
{
zend_bool pers = net->persistent;
- if (net->options.ssl_passphrase) {
- mnd_pefree(net->options.ssl_passphrase, pers);
+ if (net->data->options.ssl_passphrase) {
+ mnd_pefree(net->data->options.ssl_passphrase, pers);
}
- net->options.ssl_passphrase = value? mnd_pestrdup(value, pers) : NULL;
+ net->data->options.ssl_passphrase = value? mnd_pestrdup(value, pers) : NULL;
break;
}
case MYSQL_OPT_SSL_VERIFY_SERVER_CERT:
- net->options.ssl_verify_peer = value? ((*(zend_bool *)value)? TRUE:FALSE): FALSE;
+ net->data->options.ssl_verify_peer = value? ((*(zend_bool *)value)? TRUE:FALSE): FALSE;
break;
case MYSQL_OPT_READ_TIMEOUT:
- net->options.timeout_read = *(unsigned int*) value;
+ net->data->options.timeout_read = *(unsigned int*) value;
break;
#ifdef WHEN_SUPPORTED_BY_MYSQLI
case MYSQL_OPT_WRITE_TIMEOUT:
- net->options.timeout_write = *(unsigned int*) value;
+ net->data->options.timeout_write = *(unsigned int*) value;
break;
#endif
case MYSQL_OPT_COMPRESS:
- net->options.flags |= MYSQLND_NET_FLAG_USE_COMPRESSION;
+ net->data->options.flags |= MYSQLND_NET_FLAG_USE_COMPRESSION;
break;
default:
DBG_RETURN(FAIL);
@@ -765,7 +803,8 @@ MYSQLND_METHOD(mysqlnd_net, consume_uneaten_data)(MYSQLND_NET * const net, enum
char tmp_buf[256];
size_t skipped_bytes = 0;
int opt = PHP_STREAM_OPTION_BLOCKING;
- int was_blocked = net->stream->ops->set_option(net->stream, opt, 0, NULL TSRMLS_CC);
+ php_stream * net_stream = net->data->get_stream(net TSRMLS_CC);
+ int was_blocked = net_stream->ops->set_option(net_stream, opt, 0, NULL TSRMLS_CC);
DBG_ENTER("mysqlnd_net::consume_uneaten_data");
@@ -774,11 +813,11 @@ MYSQLND_METHOD(mysqlnd_net, consume_uneaten_data)(MYSQLND_NET * const net, enum
int bytes_consumed;
do {
- skipped_bytes += (bytes_consumed = php_stream_read(net->stream, tmp_buf, sizeof(tmp_buf)));
+ skipped_bytes += (bytes_consumed = php_stream_read(net_stream, tmp_buf, sizeof(tmp_buf)));
} while (bytes_consumed == sizeof(tmp_buf));
if (was_blocked) {
- net->stream->ops->set_option(net->stream, opt, 1, NULL TSRMLS_CC);
+ net_stream->ops->set_option(net_stream, opt, 1, NULL TSRMLS_CC);
}
if (bytes_consumed) {
@@ -806,53 +845,55 @@ static enum_func_status
MYSQLND_METHOD(mysqlnd_net, enable_ssl)(MYSQLND_NET * const net TSRMLS_DC)
{
#ifdef MYSQLND_SSL_SUPPORTED
- php_stream_context *context = php_stream_context_alloc(TSRMLS_C);
+ php_stream_context * context = php_stream_context_alloc(TSRMLS_C);
+ php_stream * net_stream = net->data->m.get_stream(net TSRMLS_CC);
+
DBG_ENTER("mysqlnd_net::enable_ssl");
if (!context) {
DBG_RETURN(FAIL);
}
- if (net->options.ssl_key) {
+ if (net->data->options.ssl_key) {
zval key_zval;
- ZVAL_STRING(&key_zval, net->options.ssl_key, 0);
+ ZVAL_STRING(&key_zval, net->data->options.ssl_key, 0);
php_stream_context_set_option(context, "ssl", "local_pk", &key_zval);
}
- if (net->options.ssl_verify_peer) {
+ if (net->data->options.ssl_verify_peer) {
zval verify_peer_zval;
ZVAL_TRUE(&verify_peer_zval);
php_stream_context_set_option(context, "ssl", "verify_peer", &verify_peer_zval);
}
- if (net->options.ssl_cert) {
+ if (net->data->options.ssl_cert) {
zval cert_zval;
- ZVAL_STRING(&cert_zval, net->options.ssl_cert, 0);
+ ZVAL_STRING(&cert_zval, net->data->options.ssl_cert, 0);
php_stream_context_set_option(context, "ssl", "local_cert", &cert_zval);
- if (!net->options.ssl_key) {
+ if (!net->data->options.ssl_key) {
php_stream_context_set_option(context, "ssl", "local_pk", &cert_zval);
}
}
- if (net->options.ssl_ca) {
+ if (net->data->options.ssl_ca) {
zval cafile_zval;
- ZVAL_STRING(&cafile_zval, net->options.ssl_ca, 0);
+ ZVAL_STRING(&cafile_zval, net->data->options.ssl_ca, 0);
php_stream_context_set_option(context, "ssl", "cafile", &cafile_zval);
}
- if (net->options.ssl_capath) {
+ if (net->data->options.ssl_capath) {
zval capath_zval;
- ZVAL_STRING(&capath_zval, net->options.ssl_capath, 0);
+ ZVAL_STRING(&capath_zval, net->data->options.ssl_capath, 0);
php_stream_context_set_option(context, "ssl", "cafile", &capath_zval);
}
- if (net->options.ssl_passphrase) {
+ if (net->data->options.ssl_passphrase) {
zval passphrase_zval;
- ZVAL_STRING(&passphrase_zval, net->options.ssl_passphrase, 0);
+ ZVAL_STRING(&passphrase_zval, net->data->options.ssl_passphrase, 0);
php_stream_context_set_option(context, "ssl", "passphrase", &passphrase_zval);
}
- if (net->options.ssl_cipher) {
+ if (net->data->options.ssl_cipher) {
zval cipher_zval;
- ZVAL_STRING(&cipher_zval, net->options.ssl_cipher, 0);
+ ZVAL_STRING(&cipher_zval, net->data->options.ssl_cipher, 0);
php_stream_context_set_option(context, "ssl", "ciphers", &cipher_zval);
}
- php_stream_context_set(net->stream, context);
- if (php_stream_xport_crypto_setup(net->stream, STREAM_CRYPTO_METHOD_TLS_CLIENT, NULL TSRMLS_CC) < 0 ||
- php_stream_xport_crypto_enable(net->stream, 1 TSRMLS_CC) < 0)
+ php_stream_context_set(net_stream, context);
+ if (php_stream_xport_crypto_setup(net_stream, STREAM_CRYPTO_METHOD_TLS_CLIENT, NULL TSRMLS_CC) < 0 ||
+ php_stream_xport_crypto_enable(net_stream, 1 TSRMLS_CC) < 0)
{
DBG_ERR("Cannot connect to MySQL by using SSL");
php_error_docref(NULL TSRMLS_CC, E_WARNING, "Cannot connect to MySQL by using SSL");
@@ -865,19 +906,20 @@ MYSQLND_METHOD(mysqlnd_net, enable_ssl)(MYSQLND_NET * const net TSRMLS_DC)
of the context, which means usage of already freed memory, bad. Actually we don't need this
context anymore after we have enabled SSL on the connection. Thus it is very simple, we remove it.
*/
- php_stream_context_set(net->stream, NULL);
+ php_stream_context_set(net_stream, NULL);
- if (net->options.timeout_read) {
+ if (net->data->options.timeout_read) {
struct timeval tv;
- DBG_INF_FMT("setting %u as PHP_STREAM_OPTION_READ_TIMEOUT", net->options.timeout_read);
- tv.tv_sec = net->options.timeout_read;
+ DBG_INF_FMT("setting %u as PHP_STREAM_OPTION_READ_TIMEOUT", net->data->options.timeout_read);
+ tv.tv_sec = net->data->options.timeout_read;
tv.tv_usec = 0;
- php_stream_set_option(net->stream, PHP_STREAM_OPTION_READ_TIMEOUT, 0, &tv);
+ php_stream_set_option(net_stream, PHP_STREAM_OPTION_READ_TIMEOUT, 0, &tv);
}
DBG_RETURN(PASS);
#else
DBG_ENTER("mysqlnd_net::enable_ssl");
+ DBG_INFO("MYSQLND_SSL_SUPPORTED is not defined");
DBG_RETURN(PASS);
#endif
}
@@ -906,25 +948,25 @@ MYSQLND_METHOD(mysqlnd_net, free_contents)(MYSQLND_NET * net TSRMLS_DC)
net->uncompressed_data->free_buffer(&net->uncompressed_data TSRMLS_CC);
}
#endif
- if (net->options.ssl_key) {
- mnd_pefree(net->options.ssl_key, pers);
- net->options.ssl_key = NULL;
+ if (net->data->options.ssl_key) {
+ mnd_pefree(net->data->options.ssl_key, pers);
+ net->data->options.ssl_key = NULL;
}
- if (net->options.ssl_cert) {
- mnd_pefree(net->options.ssl_cert, pers);
- net->options.ssl_cert = NULL;
+ if (net->data->options.ssl_cert) {
+ mnd_pefree(net->data->options.ssl_cert, pers);
+ net->data->options.ssl_cert = NULL;
}
- if (net->options.ssl_ca) {
- mnd_pefree(net->options.ssl_ca, pers);
- net->options.ssl_ca = NULL;
+ if (net->data->options.ssl_ca) {
+ mnd_pefree(net->data->options.ssl_ca, pers);
+ net->data->options.ssl_ca = NULL;
}
- if (net->options.ssl_capath) {
- mnd_pefree(net->options.ssl_capath, pers);
- net->options.ssl_capath = NULL;
+ if (net->data->options.ssl_capath) {
+ mnd_pefree(net->data->options.ssl_capath, pers);
+ net->data->options.ssl_capath = NULL;
}
- if (net->options.ssl_cipher) {
- mnd_pefree(net->options.ssl_cipher, pers);
- net->options.ssl_cipher = NULL;
+ if (net->data->options.ssl_cipher) {
+ mnd_pefree(net->data->options.ssl_cipher, pers);
+ net->data->options.ssl_cipher = NULL;
}
DBG_VOID_RETURN;
@@ -936,24 +978,25 @@ MYSQLND_METHOD(mysqlnd_net, free_contents)(MYSQLND_NET * net TSRMLS_DC)
static void
MYSQLND_METHOD(mysqlnd_net, close_stream)(MYSQLND_NET * const net, MYSQLND_STATS * const stats, MYSQLND_ERROR_INFO * const error_info TSRMLS_DC)
{
+ php_stream * net_stream;
DBG_ENTER("mysqlnd_net::close_stream");
- if (net && net->stream) {
+ if (net && (net_stream = net->data->m.get_stream(net TSRMLS_CC))) {
zend_bool pers = net->persistent;
- DBG_INF_FMT("Freeing stream. abstract=%p", net->stream->abstract);
+ DBG_INF_FMT("Freeing stream. abstract=%p", net_stream->abstract);
if (pers) {
if (EG(active)) {
- php_stream_free(net->stream, PHP_STREAM_FREE_CLOSE_PERSISTENT | PHP_STREAM_FREE_RSRC_DTOR);
+ php_stream_free(net_stream, PHP_STREAM_FREE_CLOSE_PERSISTENT | PHP_STREAM_FREE_RSRC_DTOR);
} else {
/*
otherwise we will crash because the EG(persistent_list) has been freed already,
before the modules are shut down
*/
- php_stream_free(net->stream, PHP_STREAM_FREE_CLOSE | PHP_STREAM_FREE_RSRC_DTOR);
+ php_stream_free(net_stream, PHP_STREAM_FREE_CLOSE | PHP_STREAM_FREE_RSRC_DTOR);
}
} else {
- php_stream_free(net->stream, PHP_STREAM_FREE_CLOSE);
+ php_stream_free(net_stream, PHP_STREAM_FREE_CLOSE);
}
- net->stream = NULL;
+ (void) net->data->m.set_stream(net, NULL TSRMLS_CC);
}
DBG_VOID_RETURN;
@@ -969,13 +1012,13 @@ MYSQLND_METHOD(mysqlnd_net, init)(MYSQLND_NET * const net, MYSQLND_STATS * const
DBG_ENTER("mysqlnd_net::init");
buf_size = MYSQLND_G(net_cmd_buffer_size); /* this is long, cast to unsigned int*/
- net->m.set_client_option(net, MYSQLND_OPT_NET_CMD_BUFFER_SIZE, (char *) &buf_size TSRMLS_CC);
+ net->data->m.set_client_option(net, MYSQLND_OPT_NET_CMD_BUFFER_SIZE, (char *) &buf_size TSRMLS_CC);
buf_size = MYSQLND_G(net_read_buffer_size); /* this is long, cast to unsigned int*/
- net->m.set_client_option(net, MYSQLND_OPT_NET_READ_BUFFER_SIZE, (char *)&buf_size TSRMLS_CC);
+ net->data->m.set_client_option(net, MYSQLND_OPT_NET_READ_BUFFER_SIZE, (char *)&buf_size TSRMLS_CC);
buf_size = MYSQLND_G(net_read_timeout); /* this is long, cast to unsigned int*/
- net->m.set_client_option(net, MYSQL_OPT_READ_TIMEOUT, (char *)&buf_size TSRMLS_CC);
+ net->data->m.set_client_option(net, MYSQL_OPT_READ_TIMEOUT, (char *)&buf_size TSRMLS_CC);
DBG_RETURN(PASS);
}
@@ -988,22 +1031,49 @@ MYSQLND_METHOD(mysqlnd_net, dtor)(MYSQLND_NET * const net, MYSQLND_STATS * const
{
DBG_ENTER("mysqlnd_net::dtor");
if (net) {
- zend_bool pers = net->persistent;
-
- net->m.free_contents(net TSRMLS_CC);
- net->m.close_stream(net, stats, error_info TSRMLS_CC);
+ net->data->m.free_contents(net TSRMLS_CC);
+ net->data->m.close_stream(net, stats, error_info TSRMLS_CC);
+
if (net->cmd_buffer.buffer) {
DBG_INF("Freeing cmd buffer");
- mnd_pefree(net->cmd_buffer.buffer, pers);
+ mnd_pefree(net->cmd_buffer.buffer, net->persistent);
net->cmd_buffer.buffer = NULL;
}
- mnd_pefree(net, pers);
+
+ mnd_pefree(net->data, net->data->persistent);
+ mnd_pefree(net, net->persistent);
}
DBG_VOID_RETURN;
}
/* }}} */
+/* {{{ mysqlnd_net::get_stream */
+static php_stream *
+MYSQLND_METHOD(mysqlnd_net, get_stream)(const MYSQLND_NET * const net TSRMLS_DC)
+{
+ DBG_ENTER("mysqlnd_net::get_stream");
+ DBG_INF_FMT("%p", net? net->data->stream:NULL);
+ DBG_RETURN(net? net->data->stream:NULL);
+}
+/* }}} */
+
+
+/* {{{ mysqlnd_net::set_stream */
+static php_stream *
+MYSQLND_METHOD(mysqlnd_net, set_stream)(MYSQLND_NET * const net, php_stream * net_stream TSRMLS_DC)
+{
+ php_stream * ret = NULL;
+ DBG_ENTER("mysqlnd_net::set_stream");
+ if (net) {
+ net->data->stream = net_stream;
+ ret = net->data->stream;
+ }
+ DBG_RETURN(ret);
+}
+/* }}} */
+
+
MYSQLND_CLASS_METHODS_START(mysqlnd_net)
MYSQLND_METHOD(mysqlnd_net, init),
MYSQLND_METHOD(mysqlnd_net, dtor),
@@ -1011,8 +1081,9 @@ MYSQLND_CLASS_METHODS_START(mysqlnd_net)
MYSQLND_METHOD(mysqlnd_net, close_stream),
MYSQLND_METHOD(mysqlnd_net, open_pipe),
MYSQLND_METHOD(mysqlnd_net, open_tcp_or_unix),
- NULL, /* unused 1 */
- NULL, /* unused 2 */
+ 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, set_client_option),
MYSQLND_METHOD(mysqlnd_net, decode),
@@ -1026,10 +1097,15 @@ MYSQLND_CLASS_METHODS_START(mysqlnd_net)
MYSQLND_METHOD(mysqlnd_net, send_ex),
MYSQLND_METHOD(mysqlnd_net, receive_ex),
#ifdef MYSQLND_COMPRESSION_ENABLED
- MYSQLND_METHOD(mysqlnd_net, read_compressed_packet_from_stream_and_fill_read_buffer)
+ MYSQLND_METHOD(mysqlnd_net, read_compressed_packet_from_stream_and_fill_read_buffer),
#else
- NULL
+ NULL,
#endif
+ NULL, /* unused 1 */
+ NULL, /* unused 2 */
+ NULL, /* unused 3 */
+ NULL, /* unused 4 */
+ NULL /* unused 5 */
MYSQLND_CLASS_METHODS_END;
@@ -1051,7 +1127,7 @@ mysqlnd_net_free(MYSQLND_NET * const net, MYSQLND_STATS * stats, MYSQLND_ERROR_I
{
DBG_ENTER("mysqlnd_net_free");
if (net) {
- net->m.dtor(net, stats, error_info TSRMLS_CC);
+ net->data->m.dtor(net, stats, error_info TSRMLS_CC);
}
DBG_VOID_RETURN;
}
diff --git a/ext/mysqlnd/mysqlnd_priv.h b/ext/mysqlnd/mysqlnd_priv.h
index addce670d4..0d5aef55d4 100644
--- a/ext/mysqlnd/mysqlnd_priv.h
+++ b/ext/mysqlnd/mysqlnd_priv.h
@@ -193,12 +193,12 @@ PHPAPI extern const char * const mysqlnd_out_of_sync;
PHPAPI extern const char * const mysqlnd_server_gone;
PHPAPI extern const char * const mysqlnd_out_of_memory;
-extern MYSQLND_CLASS_METHOD_TABLE_NAME_FORWARD(mysqlnd_object_factory);
-extern MYSQLND_CLASS_METHOD_TABLE_NAME_FORWARD(mysqlnd_conn);
-extern MYSQLND_CLASS_METHOD_TABLE_NAME_FORWARD(mysqlnd_conn_data);
-extern MYSQLND_CLASS_METHOD_TABLE_NAME_FORWARD(mysqlnd_res);
-extern MYSQLND_CLASS_METHOD_TABLE_NAME_FORWARD(mysqlnd_protocol);
-extern MYSQLND_CLASS_METHOD_TABLE_NAME_FORWARD(mysqlnd_net);
+PHPAPI extern MYSQLND_CLASS_METHOD_TABLE_NAME_FORWARD(mysqlnd_object_factory);
+PHPAPI extern MYSQLND_CLASS_METHOD_TABLE_NAME_FORWARD(mysqlnd_conn);
+PHPAPI extern MYSQLND_CLASS_METHOD_TABLE_NAME_FORWARD(mysqlnd_conn_data);
+PHPAPI extern MYSQLND_CLASS_METHOD_TABLE_NAME_FORWARD(mysqlnd_res);
+PHPAPI extern MYSQLND_CLASS_METHOD_TABLE_NAME_FORWARD(mysqlnd_protocol);
+PHPAPI extern MYSQLND_CLASS_METHOD_TABLE_NAME_FORWARD(mysqlnd_net);
enum_func_status mysqlnd_handle_local_infile(MYSQLND_CONN_DATA * conn, const char *filename, zend_bool *is_warning TSRMLS_DC);
diff --git a/ext/mysqlnd/mysqlnd_reverse_api.h b/ext/mysqlnd/mysqlnd_reverse_api.h
index 005df5a1ab..7e780edb52 100644
--- a/ext/mysqlnd/mysqlnd_reverse_api.h
+++ b/ext/mysqlnd/mysqlnd_reverse_api.h
@@ -47,4 +47,3 @@ PHPAPI MYSQLND * zval_to_mysqlnd(zval * zv TSRMLS_DC);
* vim600: noet sw=4 ts=4 fdm=marker
* vim<600: noet sw=4 ts=4
*/
-
diff --git a/ext/mysqlnd/mysqlnd_structs.h b/ext/mysqlnd/mysqlnd_structs.h
index 43eba40a20..856ebd2ead 100644
--- a/ext/mysqlnd/mysqlnd_structs.h
+++ b/ext/mysqlnd/mysqlnd_structs.h
@@ -213,6 +213,7 @@ typedef struct st_mysqlnd_net_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_data MYSQLND_NET_DATA;
typedef struct st_mysqlnd_protocol MYSQLND_PROTOCOL;
typedef struct st_mysqlnd_res MYSQLND_RES;
typedef char** MYSQLND_ROW_C; /* return data as array of strings */
@@ -282,7 +283,10 @@ typedef enum_func_status (*func_mysqlnd_net__init)(MYSQLND_NET * const net, MYSQ
typedef void (*func_mysqlnd_net__dtor)(MYSQLND_NET * const net, MYSQLND_STATS * const conn_stats, MYSQLND_ERROR_INFO * const error_info TSRMLS_DC);
typedef enum_func_status (*func_mysqlnd_net__connect_ex)(MYSQLND_NET * const net, const char * const scheme, const size_t scheme_len, const zend_bool persistent, MYSQLND_STATS * const conn_stats, MYSQLND_ERROR_INFO * const error_info TSRMLS_DC);
typedef void (*func_mysqlnd_net__close_stream)(MYSQLND_NET * const net, MYSQLND_STATS * const conn_stats, MYSQLND_ERROR_INFO * const error_info TSRMLS_DC);
-typedef enum_func_status (*func_mysqlnd_net__open_stream)(MYSQLND_NET * const net, const char * const scheme, const size_t scheme_len, const zend_bool persistent, MYSQLND_STATS * const conn_stats, MYSQLND_ERROR_INFO * const error_info TSRMLS_DC);
+typedef php_stream * (*func_mysqlnd_net__open_stream)(MYSQLND_NET * const net, const char * const scheme, const size_t scheme_len, const zend_bool persistent, MYSQLND_STATS * const conn_stats, MYSQLND_ERROR_INFO * const error_info TSRMLS_DC);
+typedef php_stream * (*func_mysqlnd_net__get_stream)(const MYSQLND_NET * const net TSRMLS_DC);
+typedef php_stream * (*func_mysqlnd_net__set_stream)(MYSQLND_NET * const net, php_stream * net_stream TSRMLS_DC);
+typedef func_mysqlnd_net__open_stream (*func_mysqlnd_net__get_open_stream)(MYSQLND_NET * const net, const char * const scheme, const size_t scheme_len, MYSQLND_ERROR_INFO * const error_info TSRMLS_DC);
typedef void (*func_mysqlnd_net__post_connect_set_opt)(MYSQLND_NET * const net, const char * const scheme, const size_t scheme_len, MYSQLND_STATS * const conn_stats, MYSQLND_ERROR_INFO * const error_info TSRMLS_DC);
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 TSRMLS_DC);
@@ -295,8 +299,10 @@ struct st_mysqlnd_net_methods
func_mysqlnd_net__open_stream open_pipe;
func_mysqlnd_net__open_stream open_tcp_or_unix;
- void * unused1;
- void * unused2;
+ 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__set_client_option set_client_option;
@@ -314,11 +320,11 @@ struct st_mysqlnd_net_methods
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;
- void * unused6;
- void * unused7;
};
@@ -467,7 +473,11 @@ typedef enum_func_status (*func_mysqlnd_conn_data__tx_rollback)(MYSQLND_CONN_DAT
typedef enum_func_status (*func_mysqlnd_conn_data__local_tx_start)(MYSQLND_CONN_DATA * conn, size_t this_func TSRMLS_DC);
typedef enum_func_status (*func_mysqlnd_conn_data__local_tx_end)(MYSQLND_CONN_DATA * conn, size_t this_func, enum_func_status status TSRMLS_DC);
-
+typedef enum_func_status (*func_mysqlnd_conn_data__execute_init_commands)(MYSQLND_CONN_DATA * conn TSRMLS_DC);
+typedef unsigned int (*func_mysqlnd_conn_data__get_updated_connect_flags)(MYSQLND_CONN_DATA * conn, unsigned int mysql_flags TSRMLS_DC);
+typedef enum_func_status (*func_mysqlnd_conn_data__connect_handshake)(MYSQLND_CONN_DATA * conn, const char * const host, const char * const user, const char * const passwd, const unsigned int passwd_len, const char * const db, const unsigned int db_len, const unsigned int mysql_flags TSRMLS_DC);
+typedef enum_func_status (*func_mysqlnd_conn_data__simple_command_send_request)(MYSQLND_CONN_DATA * conn, enum php_mysqlnd_server_command command, const zend_uchar * const arg, size_t arg_len, zend_bool silent, zend_bool ignore_upsert_status TSRMLS_DC);
+typedef struct st_mysqlnd_authentication_plugin * (*func_mysqlnd_conn_data__fetch_auth_plugin_by_name)(const char * const requested_protocol TSRMLS_DC);
struct st_mysqlnd_conn_data_methods
{
@@ -547,6 +557,12 @@ struct st_mysqlnd_conn_data_methods
func_mysqlnd_conn_data__local_tx_start local_tx_start;
func_mysqlnd_conn_data__local_tx_end local_tx_end;
+
+ func_mysqlnd_conn_data__execute_init_commands execute_init_commands;
+ func_mysqlnd_conn_data__get_updated_connect_flags get_updated_connect_flags;
+ func_mysqlnd_conn_data__connect_handshake connect_handshake;
+ func_mysqlnd_conn_data__simple_command_send_request simple_command_send_request;
+ func_mysqlnd_conn_data__fetch_auth_plugin_by_name fetch_auth_plugin_by_name;
};
@@ -768,31 +784,43 @@ struct st_mysqlnd_stmt_methods
};
-struct st_mysqlnd_net
+struct st_mysqlnd_net_data
{
php_stream *stream;
+ zend_bool compressed;
+#ifdef MYSQLND_DO_WIRE_CHECK_BEFORE_COMMAND
+ zend_uchar last_command;
+#else
+ zend_uchar unused_pad1;
+#endif
+ MYSQLND_NET_OPTIONS options;
+
+ unsigned int refcount;
+
+ zend_bool persistent;
+
+ struct st_mysqlnd_net_methods m;
+};
+
+
+struct st_mysqlnd_net
+{
+ struct st_mysqlnd_net_data * data;
+
/* sequence for simple checking of correct packets */
zend_uchar packet_no;
- zend_bool compressed;
zend_uchar compressed_envelope_packet_no;
+
#ifdef MYSQLND_COMPRESSION_ENABLED
MYSQLND_READ_BUFFER * uncompressed_data;
#else
void * unused_pad1;
#endif
-#ifdef MYSQLND_DO_WIRE_CHECK_BEFORE_COMMAND
- zend_uchar last_command;
-#else
- zend_uchar unused_pad2;
-#endif
+
/* cmd buffer */
MYSQLND_CMD_BUFFER cmd_buffer;
- MYSQLND_NET_OPTIONS options;
-
- zend_bool persistent;
-
- struct st_mysqlnd_net_methods m;
+ zend_bool persistent;
};
diff --git a/ext/mysqlnd/mysqlnd_wireprotocol.c b/ext/mysqlnd/mysqlnd_wireprotocol.c
index ce94ad8d8e..3551c027cd 100644
--- a/ext/mysqlnd/mysqlnd_wireprotocol.c
+++ b/ext/mysqlnd/mysqlnd_wireprotocol.c
@@ -47,7 +47,7 @@
(buf_size), (packet)->header.size, (packet)->header.size - (buf_size)); \
DBG_RETURN(FAIL); \
}\
- if (FAIL == conn->net->m.receive_ex((conn)->net, (buf), (packet)->header.size, (conn)->stats, ((conn)->error_info) TSRMLS_CC)) { \
+ if (FAIL == conn->net->data->m.receive_ex((conn)->net, (buf), (packet)->header.size, (conn)->stats, ((conn)->error_info) TSRMLS_CC)) { \
CONN_SET_STATE(conn, CONN_QUIT_SENT); \
SET_CLIENT_ERROR(*conn->error_info, CR_SERVER_GONE_ERROR, UNKNOWN_SQLSTATE, mysqlnd_server_gone);\
php_error_docref(NULL TSRMLS_CC, E_WARNING, "%s", mysqlnd_server_gone); \
@@ -264,8 +264,8 @@ mysqlnd_read_header(MYSQLND_NET * net, MYSQLND_PACKET_HEADER * header,
zend_uchar buffer[MYSQLND_HEADER_SIZE];
DBG_ENTER(mysqlnd_read_header_name);
- DBG_INF_FMT("compressed=%u", net->compressed);
- if (FAIL == net->m.receive_ex(net, buffer, MYSQLND_HEADER_SIZE, conn_stats, error_info TSRMLS_CC)) {
+ DBG_INF_FMT("compressed=%u", net->data->compressed);
+ if (FAIL == net->data->m.receive_ex(net, buffer, MYSQLND_HEADER_SIZE, conn_stats, error_info TSRMLS_CC)) {
DBG_RETURN(FAIL);
}
@@ -279,7 +279,7 @@ mysqlnd_read_header(MYSQLND_NET * net, MYSQLND_PACKET_HEADER * header,
STAT_PROTOCOL_OVERHEAD_IN, MYSQLND_HEADER_SIZE,
STAT_PACKETS_RECEIVED, 1);
- if (net->compressed || net->packet_no == header->packet_no) {
+ if (net->data->compressed || net->packet_no == header->packet_no) {
/*
Have to increase the number, so we can send correct number back. It will
round at 255 as this is unsigned char. The server needs this for simple
@@ -549,7 +549,7 @@ size_t php_mysqlnd_auth_write(void * _packet, MYSQLND_CONN_DATA * conn TSRMLS_DC
}
DBG_RETURN(p - buffer - MYSQLND_HEADER_SIZE);
} else {
- size_t sent = conn->net->m.send_ex(conn->net, buffer, p - buffer - MYSQLND_HEADER_SIZE, conn->stats, conn->error_info TSRMLS_CC);
+ size_t sent = conn->net->data->m.send_ex(conn->net, buffer, p - buffer - MYSQLND_HEADER_SIZE, conn->stats, conn->error_info TSRMLS_CC);
if (!sent) {
CONN_SET_STATE(conn, CONN_QUIT_SENT);
}
@@ -709,7 +709,7 @@ php_mysqlnd_change_auth_response_write(void * _packet, MYSQLND_CONN_DATA * conn
}
{
- size_t sent = conn->net->m.send_ex(conn->net, buffer, p - buffer - MYSQLND_HEADER_SIZE, conn->stats, conn->error_info TSRMLS_CC);
+ size_t sent = conn->net->data->m.send_ex(conn->net, buffer, p - buffer - MYSQLND_HEADER_SIZE, conn->stats, conn->error_info TSRMLS_CC);
if (buffer != conn->net->cmd_buffer.buffer) {
mnd_efree(buffer);
}
@@ -923,14 +923,14 @@ size_t php_mysqlnd_cmd_write(void * _packet, MYSQLND_CONN_DATA * conn TSRMLS_DC)
MYSQLND_INC_CONN_STATISTIC(conn->stats, STAT_PACKETS_SENT_CMD);
#ifdef MYSQLND_DO_WIRE_CHECK_BEFORE_COMMAND
- net->m.consume_uneaten_data(net, packet->command TSRMLS_CC);
+ net->data->m.consume_uneaten_data(net, packet->command TSRMLS_CC);
#endif
if (!packet->argument || !packet->arg_len) {
zend_uchar buffer[MYSQLND_HEADER_SIZE + 1];
int1store(buffer + MYSQLND_HEADER_SIZE, packet->command);
- sent = net->m.send_ex(net, buffer, 1, conn->stats, conn->error_info TSRMLS_CC);
+ sent = net->data->m.send_ex(net, buffer, 1, conn->stats, conn->error_info TSRMLS_CC);
} else {
size_t tmp_len = packet->arg_len + 1 + MYSQLND_HEADER_SIZE;
zend_uchar *tmp, *p;
@@ -945,7 +945,7 @@ size_t php_mysqlnd_cmd_write(void * _packet, MYSQLND_CONN_DATA * conn TSRMLS_DC)
memcpy(p, packet->argument, packet->arg_len);
- sent = net->m.send_ex(net, tmp, tmp_len - MYSQLND_HEADER_SIZE, conn->stats, conn->error_info TSRMLS_CC);
+ sent = net->data->m.send_ex(net, tmp, tmp_len - MYSQLND_HEADER_SIZE, conn->stats, conn->error_info TSRMLS_CC);
if (tmp != net->cmd_buffer.buffer) {
MYSQLND_INC_CONN_STATISTIC(conn->stats, STAT_CMD_BUFFER_TOO_SMALL);
mnd_efree(tmp);
@@ -1388,7 +1388,7 @@ php_mysqlnd_read_row_ex(MYSQLND_CONN_DATA * conn, MYSQLND_MEMORY_POOL * result_s
p = (*buffer)->ptr + (*data_size - header.size);
}
- if (PASS != (ret = conn->net->m.receive_ex(conn->net, p, header.size, conn->stats, conn->error_info TSRMLS_CC))) {
+ if (PASS != (ret = conn->net->data->m.receive_ex(conn->net, p, header.size, conn->stats, conn->error_info TSRMLS_CC))) {
DBG_ERR("Empty row packet body");
php_error(E_WARNING, "Empty row packet body");
break;
@@ -1744,10 +1744,8 @@ php_mysqlnd_rowp_read_text_protocol(MYSQLND_MEMORY_POOL_CHUNK * row_buffer, zval
static enum_func_status
php_mysqlnd_rowp_read(void * _packet, MYSQLND_CONN_DATA * conn TSRMLS_DC)
{
- MYSQLND_NET * net = conn->net;
zend_uchar *p;
enum_func_status ret = PASS;
- size_t old_chunk_size = net->stream->chunk_size;
MYSQLND_PACKET_ROW *packet= (MYSQLND_PACKET_ROW *) _packet;
size_t post_alloc_for_bit_fields = 0;
size_t data_size = 0;
@@ -1829,7 +1827,6 @@ php_mysqlnd_rowp_read(void * _packet, MYSQLND_CONN_DATA * conn TSRMLS_DC)
}
end:
- net->stream->chunk_size = old_chunk_size;
DBG_RETURN(ret);
}
/* }}} */