version 1.1.1.1, 2012/02/21 23:47:58
|
version 1.1.1.2, 2012/05/29 12:34:41
|
Line 12
|
Line 12
|
| obtain it through the world-wide-web, please send a note to | |
| obtain it through the world-wide-web, please send a note to | |
| license@php.net so we can mail you a copy immediately. | |
| license@php.net so we can mail you a copy immediately. | |
+----------------------------------------------------------------------+ |
+----------------------------------------------------------------------+ |
| Authors: Georg Richter <georg@mysql.com> | | | Authors: Andrey Hristov <andrey@mysql.com> | |
| Andrey Hristov <andrey@mysql.com> | | |
| Ulf Wendel <uwendel@mysql.com> | |
| Ulf Wendel <uwendel@mysql.com> | |
|
| Georg Richter <georg@mysql.com> | |
+----------------------------------------------------------------------+ |
+----------------------------------------------------------------------+ |
*/ |
*/ |
|
|
|
/* $Id$ */ |
#include "php.h" |
#include "php.h" |
#include "php_globals.h" |
#include "php_globals.h" |
#include "mysqlnd.h" |
#include "mysqlnd.h" |
Line 24
|
Line 26
|
#include "mysqlnd_wireprotocol.h" |
#include "mysqlnd_wireprotocol.h" |
#include "mysqlnd_statistics.h" |
#include "mysqlnd_statistics.h" |
#include "mysqlnd_debug.h" |
#include "mysqlnd_debug.h" |
#include "ext/standard/sha1.h" | #include "mysqlnd_ext_plugin.h" |
#include "php_network.h" |
#include "php_network.h" |
#include "zend_ini.h" |
#include "zend_ini.h" |
#ifdef MYSQLND_COMPRESSION_ENABLED |
#ifdef MYSQLND_COMPRESSION_ENABLED |
Line 59 mysqlnd_set_sock_no_delay(php_stream * stream TSRMLS_D
|
Line 61 mysqlnd_set_sock_no_delay(php_stream * stream TSRMLS_D
|
/* }}} */ |
/* }}} */ |
|
|
|
|
/* {{{ mysqlnd_net::network_read */ | /* {{{ mysqlnd_net::network_read_ex */ |
static enum_func_status |
static enum_func_status |
MYSQLND_METHOD(mysqlnd_net, network_read)(MYSQLND * conn, zend_uchar * buffer, size_t count TSRMLS_DC) | MYSQLND_METHOD(mysqlnd_net, network_read_ex)(MYSQLND_NET * const net, zend_uchar * const buffer, const size_t count, |
| MYSQLND_STATS * const stats, MYSQLND_ERROR_INFO * const error_info TSRMLS_DC) |
{ |
{ |
enum_func_status return_value = PASS; |
enum_func_status return_value = PASS; |
size_t to_read = count, ret; |
size_t to_read = count, ret; |
size_t old_chunk_size = conn->net->stream->chunk_size; | size_t old_chunk_size = net->stream->chunk_size; |
DBG_ENTER("mysqlnd_net::network_read"); | zend_uchar * p = buffer; |
DBG_INF_FMT("count=%u", count); | |
conn->net->stream->chunk_size = MIN(to_read, conn->net->options.net_read_buffer_size); | 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); |
while (to_read) { |
while (to_read) { |
if (!(ret = php_stream_read(conn->net->stream, (char *) buffer, to_read))) { | if (!(ret = php_stream_read(net->stream, (char *) p, to_read))) { |
DBG_ERR_FMT("Error while reading header from socket"); |
DBG_ERR_FMT("Error while reading header from socket"); |
return_value = FAIL; |
return_value = FAIL; |
break; |
break; |
} |
} |
buffer += ret; | p += ret; |
to_read -= ret; |
to_read -= ret; |
} |
} |
MYSQLND_INC_CONN_STATISTIC_W_VALUE(conn->stats, STAT_BYTES_RECEIVED, count - to_read); | MYSQLND_INC_CONN_STATISTIC_W_VALUE(stats, STAT_BYTES_RECEIVED, count - to_read); |
conn->net->stream->chunk_size = old_chunk_size; | net->stream->chunk_size = old_chunk_size; |
DBG_RETURN(return_value); |
DBG_RETURN(return_value); |
} |
} |
/* }}} */ |
/* }}} */ |
|
|
|
|
/* {{{ mysqlnd_net::network_write */ | /* {{{ mysqlnd_net::network_write_ex */ |
static size_t |
static size_t |
MYSQLND_METHOD(mysqlnd_net, network_write)(MYSQLND * const conn, const zend_uchar * const buf, size_t count TSRMLS_DC) | MYSQLND_METHOD(mysqlnd_net, network_write_ex)(MYSQLND_NET * const net, const zend_uchar * const buffer, const size_t count, |
| MYSQLND_STATS * const stats, MYSQLND_ERROR_INFO * const error_info TSRMLS_DC) |
{ |
{ |
size_t ret; |
size_t ret; |
DBG_ENTER("mysqlnd_net::network_write"); | DBG_ENTER("mysqlnd_net::network_write_ex"); |
ret = php_stream_write(conn->net->stream, (char *)buf, count); | ret = php_stream_write(net->stream, (char *)buffer, count); |
DBG_RETURN(ret); |
DBG_RETURN(ret); |
} |
} |
/* }}} */ |
/* }}} */ |
|
|
|
/* {{{ mysqlnd_net::open_pipe */ |
|
static enum_func_status |
|
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) |
|
{ |
|
#if PHP_API_VERSION < 20100412 |
|
unsigned int streams_options = ENFORCE_SAFE_MODE; |
|
#else |
|
unsigned int streams_options = 0; |
|
#endif |
|
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) { |
|
SET_CLIENT_ERROR(*error_info, CR_CONNECTION_ERROR, UNKNOWN_SQLSTATE, "Unknown errror while connecting"); |
|
DBG_RETURN(FAIL); |
|
} |
|
/* |
|
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; |
|
|
|
DBG_RETURN(PASS); |
|
} |
|
/* }}} */ |
|
|
/* {{{ mysqlnd_net::connect */ | |
| /* {{{ mysqlnd_net::open_tcp_or_unix */ |
static enum_func_status |
static enum_func_status |
MYSQLND_METHOD(mysqlnd_net, connect)(MYSQLND_NET * net, const char * const scheme, size_t scheme_len, zend_bool persistent, char **errstr, int * errcode TSRMLS_DC) | 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) |
{ |
{ |
#if PHP_API_VERSION < 20100412 |
#if PHP_API_VERSION < 20100412 |
unsigned int streams_options = ENFORCE_SAFE_MODE; |
unsigned int streams_options = ENFORCE_SAFE_MODE; |
Line 110 MYSQLND_METHOD(mysqlnd_net, connect)(MYSQLND_NET * net
|
Line 152 MYSQLND_METHOD(mysqlnd_net, connect)(MYSQLND_NET * net
|
unsigned int streams_flags = STREAM_XPORT_CLIENT | STREAM_XPORT_CONNECT; |
unsigned int streams_flags = STREAM_XPORT_CLIENT | STREAM_XPORT_CONNECT; |
char * hashed_details = NULL; |
char * hashed_details = NULL; |
int hashed_details_len = 0; |
int hashed_details_len = 0; |
|
char * errstr = NULL; |
|
int errcode = 0; |
struct timeval tv; |
struct timeval tv; |
DBG_ENTER("mysqlnd_net::connect"); |
|
|
|
|
DBG_ENTER("mysqlnd_net::open_tcp_or_unix"); |
|
|
if (persistent) { |
if (persistent) { |
hashed_details_len = spprintf(&hashed_details, 0, "%p", net); | hashed_details_len = mnd_sprintf(&hashed_details, 0, "%p", net); |
DBG_INF_FMT("hashed_details=%s", hashed_details); |
DBG_INF_FMT("hashed_details=%s", hashed_details); |
} |
} |
|
|
net->packet_no = net->compressed_envelope_packet_no = 0; |
|
|
|
if (net->stream) { |
|
/* close before opening a new one */ |
|
DBG_INF_FMT("Freeing stream. abstract=%p", net->stream->abstract); |
|
if (net->persistent) { |
|
php_stream_free(net->stream, PHP_STREAM_FREE_CLOSE_PERSISTENT | PHP_STREAM_FREE_RSRC_DTOR); |
|
} else { |
|
php_stream_free(net->stream, PHP_STREAM_FREE_CLOSE); |
|
} |
|
net->stream = NULL; |
|
} |
|
|
|
if (net->options.timeout_connect) { |
if (net->options.timeout_connect) { |
tv.tv_sec = net->options.timeout_connect; |
tv.tv_sec = net->options.timeout_connect; |
tv.tv_usec = 0; |
tv.tv_usec = 0; |
Line 139 MYSQLND_METHOD(mysqlnd_net, connect)(MYSQLND_NET * net
|
Line 171 MYSQLND_METHOD(mysqlnd_net, connect)(MYSQLND_NET * net
|
DBG_INF_FMT("calling php_stream_xport_create"); |
DBG_INF_FMT("calling php_stream_xport_create"); |
net->stream = php_stream_xport_create(scheme, scheme_len, streams_options, streams_flags, |
net->stream = php_stream_xport_create(scheme, scheme_len, streams_options, streams_flags, |
hashed_details, (net->options.timeout_connect) ? &tv : NULL, |
hashed_details, (net->options.timeout_connect) ? &tv : NULL, |
NULL /*ctx*/, errstr, errcode); | NULL /*ctx*/, &errstr, &errcode); |
| if (errstr || !net->stream) { |
if (*errstr || !net->stream) { | DBG_ERR("Error"); |
if (hashed_details) { |
if (hashed_details) { |
efree(hashed_details); /* allocated by spprintf */ | mnd_sprintf_free(hashed_details); |
} |
} |
*errcode = CR_CONNECTION_ERROR; | errcode = CR_CONNECTION_ERROR; |
| SET_CLIENT_ERROR(*error_info, errcode? errcode:CR_CONNECTION_ERROR, UNKNOWN_SQLSTATE, errstr); |
| if (errstr) { |
| /* no mnd_ since we don't allocate it */ |
| efree(errstr); |
| } |
DBG_RETURN(FAIL); |
DBG_RETURN(FAIL); |
} |
} |
|
|
if (hashed_details) { |
if (hashed_details) { |
/* |
/* |
If persistent, the streams register it in EG(persistent_list). |
If persistent, the streams register it in EG(persistent_list). |
Line 171 MYSQLND_METHOD(mysqlnd_net, connect)(MYSQLND_NET * net
|
Line 207 MYSQLND_METHOD(mysqlnd_net, connect)(MYSQLND_NET * net
|
/* Shut-up the streams, they don't know what they are doing */ |
/* Shut-up the streams, they don't know what they are doing */ |
net->stream->__exposed = 1; |
net->stream->__exposed = 1; |
#endif |
#endif |
efree(hashed_details); | mnd_sprintf_free(hashed_details); |
} |
} |
|
|
/* |
/* |
Streams are not meant for C extensions! Thus we need a hack. Every connected stream will |
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 |
be registered as resource (in EG(regular_list). So far, so good. However, it won't be |
unregistered till the script ends. So, we need to take care of that. | unregistered yntil the script ends. So, we need to take care of that. |
*/ |
*/ |
net->stream->in_free = 1; |
net->stream->in_free = 1; |
zend_hash_index_del(&EG(regular_list), net->stream->rsrc_id); |
zend_hash_index_del(&EG(regular_list), net->stream->rsrc_id); |
net->stream->in_free = 0; |
net->stream->in_free = 0; |
|
|
if (!net->options.timeout_read) { | DBG_RETURN(PASS); |
/* should always happen because read_timeout cannot be set via API */ | } |
net->options.timeout_read = (unsigned int) MYSQLND_G(net_read_timeout); | /* }}} */ |
} | |
| |
| /* {{{ mysqlnd_net::connect_ex */ |
| 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) |
| { |
| DBG_ENTER("mysqlnd_net::post_connect_set_opt"); |
if (net->options.timeout_read) { |
if (net->options.timeout_read) { |
|
struct timeval tv; |
DBG_INF_FMT("setting %u as PHP_STREAM_OPTION_READ_TIMEOUT", net->options.timeout_read); |
DBG_INF_FMT("setting %u as PHP_STREAM_OPTION_READ_TIMEOUT", net->options.timeout_read); |
tv.tv_sec = net->options.timeout_read; |
tv.tv_sec = net->options.timeout_read; |
tv.tv_usec = 0; |
tv.tv_usec = 0; |
Line 198 MYSQLND_METHOD(mysqlnd_net, connect)(MYSQLND_NET * net
|
Line 244 MYSQLND_METHOD(mysqlnd_net, connect)(MYSQLND_NET * net
|
mysqlnd_set_sock_no_delay(net->stream TSRMLS_CC); |
mysqlnd_set_sock_no_delay(net->stream TSRMLS_CC); |
} |
} |
|
|
{ | DBG_VOID_RETURN; |
unsigned int 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); | /* }}} */ |
} | |
|
|
|
|
DBG_RETURN(PASS); | /* {{{ 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, |
| const zend_bool persistent, |
| MYSQLND_STATS * const conn_stats, MYSQLND_ERROR_INFO * const error_info TSRMLS_DC) |
| { |
| enum_func_status ret = FAIL; |
| func_mysqlnd_net__open_stream open_stream = NULL; |
| DBG_ENTER("mysqlnd_net::connect_ex"); |
| |
| net->packet_no = net->compressed_envelope_packet_no = 0; |
| |
| net->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); |
| } |
| |
| DBG_RETURN(ret); |
} |
} |
/* }}} */ |
/* }}} */ |
|
|
Line 218 MYSQLND_METHOD(mysqlnd_net, connect)(MYSQLND_NET * net
|
Line 284 MYSQLND_METHOD(mysqlnd_net, connect)(MYSQLND_NET * net
|
#define STORE_HEADER_SIZE(safe_storage, buffer) COPY_HEADER((safe_storage), (buffer)) |
#define STORE_HEADER_SIZE(safe_storage, buffer) COPY_HEADER((safe_storage), (buffer)) |
#define RESTORE_HEADER_SIZE(buffer, safe_storage) STORE_HEADER_SIZE((safe_storage), (buffer)) |
#define RESTORE_HEADER_SIZE(buffer, safe_storage) STORE_HEADER_SIZE((safe_storage), (buffer)) |
|
|
/* {{{ mysqlnd_net::send */ | |
| /* {{{ mysqlnd_net::send_ex */ |
/* |
/* |
IMPORTANT : It's expected that buf has place in the beginning for MYSQLND_HEADER_SIZE !!!! | IMPORTANT : It's expected that buffer has place in the beginning for MYSQLND_HEADER_SIZE !!!! |
This is done for performance reasons in the caller of this function. |
This is done for performance reasons in the caller of this function. |
Otherwise we will have to do send two TCP packets, or do new alloc and memcpy. |
Otherwise we will have to do send two TCP packets, or do new alloc and memcpy. |
Neither are quick, thus the clients of this function are obligated to do |
Neither are quick, thus the clients of this function are obligated to do |
what they are asked for. |
what they are asked for. |
|
|
`count` is actually the length of the payload data. Thus : |
`count` is actually the length of the payload data. Thus : |
count + MYSQLND_HEADER_SIZE = sizeof(buf) (not the pointer but the actual buffer) | count + MYSQLND_HEADER_SIZE = sizeof(buffer) (not the pointer but the actual buffer) |
*/ |
*/ |
size_t | static size_t |
MYSQLND_METHOD(mysqlnd_net, send)(MYSQLND * const conn, char * const buf, size_t count TSRMLS_DC) | MYSQLND_METHOD(mysqlnd_net, send_ex)(MYSQLND_NET * const net, zend_uchar * const buffer, const size_t count, |
| MYSQLND_STATS * const conn_stats, MYSQLND_ERROR_INFO * const error_info TSRMLS_DC) |
{ |
{ |
zend_uchar safe_buf[((MYSQLND_HEADER_SIZE) + (sizeof(zend_uchar)) - 1) / (sizeof(zend_uchar))]; |
zend_uchar safe_buf[((MYSQLND_HEADER_SIZE) + (sizeof(zend_uchar)) - 1) / (sizeof(zend_uchar))]; |
zend_uchar *safe_storage = safe_buf; | zend_uchar * safe_storage = safe_buf; |
MYSQLND_NET *net = conn->net; | size_t bytes_sent, packets_sent = 1; |
size_t old_chunk_size = net->stream->chunk_size; | |
size_t ret, packets_sent = 1; | |
size_t left = count; |
size_t left = count; |
zend_uchar *p = (zend_uchar *) buf; | zend_uchar * p = (zend_uchar *) buffer; |
zend_uchar * compress_buf = NULL; |
zend_uchar * compress_buf = NULL; |
size_t to_be_sent; |
size_t to_be_sent; |
|
|
DBG_ENTER("mysqlnd_net::send"); | DBG_ENTER("mysqlnd_net::send_ex"); |
DBG_INF_FMT("conn=%llu count=%lu compression=%u", conn->thread_id, count, net->compressed); | DBG_INF_FMT("count=" MYSQLND_SZ_T_SPEC " compression=%u", count, net->compressed); |
|
|
net->stream->chunk_size = MYSQLND_MAX_PACKET_SIZE; |
|
|
|
if (net->compressed == TRUE) { |
if (net->compressed == TRUE) { |
size_t comp_buf_size = MYSQLND_HEADER_SIZE + COMPRESSED_HEADER_SIZE + MYSQLND_HEADER_SIZE + MIN(left, MYSQLND_MAX_PACKET_SIZE); |
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); |
DBG_INF_FMT("compress_buf_size="MYSQLND_SZ_T_SPEC, comp_buf_size); |
Line 280 MYSQLND_METHOD(mysqlnd_net, send)(MYSQLND * const conn
|
Line 344 MYSQLND_METHOD(mysqlnd_net, send)(MYSQLND * const conn
|
int3store(compress_buf, payload_size); |
int3store(compress_buf, payload_size); |
int1store(compress_buf + 3, net->packet_no); |
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); |
DBG_INF_FMT("writing "MYSQLND_SZ_T_SPEC" bytes to the network", payload_size + MYSQLND_HEADER_SIZE + COMPRESSED_HEADER_SIZE); |
ret = conn->net->m.network_write(conn, compress_buf, payload_size + MYSQLND_HEADER_SIZE + COMPRESSED_HEADER_SIZE TSRMLS_CC); | bytes_sent = net->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++; |
net->compressed_envelope_packet_no++; |
#if WHEN_WE_NEED_TO_CHECK_WHETHER_COMPRESSION_WORKS_CORRECTLY |
#if WHEN_WE_NEED_TO_CHECK_WHETHER_COMPRESSION_WORKS_CORRECTLY |
if (res == Z_OK) { |
if (res == Z_OK) { |
Line 311 MYSQLND_METHOD(mysqlnd_net, send)(MYSQLND * const conn
|
Line 376 MYSQLND_METHOD(mysqlnd_net, send)(MYSQLND * const conn
|
STORE_HEADER_SIZE(safe_storage, p); |
STORE_HEADER_SIZE(safe_storage, p); |
int3store(p, to_be_sent); |
int3store(p, to_be_sent); |
int1store(p + 3, net->packet_no); |
int1store(p + 3, net->packet_no); |
ret = conn->net->m.network_write(conn, p, to_be_sent + MYSQLND_HEADER_SIZE TSRMLS_CC); | bytes_sent = net->m.network_write_ex(net, p, to_be_sent + MYSQLND_HEADER_SIZE, conn_stats, error_info TSRMLS_CC); |
RESTORE_HEADER_SIZE(p, safe_storage); |
RESTORE_HEADER_SIZE(p, safe_storage); |
net->compressed_envelope_packet_no++; |
net->compressed_envelope_packet_no++; |
} |
} |
Line 327 MYSQLND_METHOD(mysqlnd_net, send)(MYSQLND * const conn
|
Line 392 MYSQLND_METHOD(mysqlnd_net, send)(MYSQLND * const conn
|
indeed it then loop once more, then to_be_sent will become 0, left will stay 0. Empty |
indeed it then loop once more, then to_be_sent will become 0, left will stay 0. Empty |
packet will be sent and this loop will end. |
packet will be sent and this loop will end. |
*/ |
*/ |
} while (ret && (left > 0 || to_be_sent == MYSQLND_MAX_PACKET_SIZE)); | } while (bytes_sent && (left > 0 || to_be_sent == MYSQLND_MAX_PACKET_SIZE)); |
|
|
DBG_INF_FMT("packet_size="MYSQLND_SZ_T_SPEC" packet_no=%u", left, net->packet_no); |
DBG_INF_FMT("packet_size="MYSQLND_SZ_T_SPEC" packet_no=%u", left, net->packet_no); |
/* Even for zero size payload we have to send a packet */ |
|
if (!ret) { |
|
DBG_ERR_FMT("Can't %u send bytes", count); |
|
conn->state = CONN_QUIT_SENT; |
|
SET_CLIENT_ERROR(conn->error_info, CR_SERVER_GONE_ERROR, UNKNOWN_SQLSTATE, mysqlnd_server_gone); |
|
} |
|
|
|
MYSQLND_INC_CONN_STATISTIC_W_VALUE3(conn->stats, | MYSQLND_INC_CONN_STATISTIC_W_VALUE3(conn_stats, |
STAT_BYTES_SENT, count + packets_sent * MYSQLND_HEADER_SIZE, |
STAT_BYTES_SENT, count + packets_sent * MYSQLND_HEADER_SIZE, |
STAT_PROTOCOL_OVERHEAD_OUT, packets_sent * MYSQLND_HEADER_SIZE, |
STAT_PROTOCOL_OVERHEAD_OUT, packets_sent * MYSQLND_HEADER_SIZE, |
STAT_PACKETS_SENT, packets_sent); |
STAT_PACKETS_SENT, packets_sent); |
|
|
net->stream->chunk_size = old_chunk_size; |
|
if (compress_buf) { |
if (compress_buf) { |
mnd_efree(compress_buf); |
mnd_efree(compress_buf); |
} |
} |
DBG_RETURN(ret); | |
| /* Even for zero size payload we have to send a packet */ |
| if (!bytes_sent) { |
| DBG_ERR_FMT("Can't %u send bytes", count); |
| SET_CLIENT_ERROR(*error_info, CR_SERVER_GONE_ERROR, UNKNOWN_SQLSTATE, mysqlnd_server_gone); |
| } |
| DBG_RETURN(bytes_sent); |
} |
} |
/* }}} */ |
/* }}} */ |
|
|
Line 416 mysqlnd_create_read_buffer(size_t count TSRMLS_DC)
|
Line 480 mysqlnd_create_read_buffer(size_t count TSRMLS_DC)
|
/* }}} */ |
/* }}} */ |
|
|
|
|
/* {{{ mysqlnd_read_compressed_packet_from_stream_and_fill_read_buffer */ | /* {{{ mysqlnd_net::read_compressed_packet_from_stream_and_fill_read_buffer */ |
static enum_func_status |
static enum_func_status |
mysqlnd_read_compressed_packet_from_stream_and_fill_read_buffer(MYSQLND * conn, size_t net_payload_size TSRMLS_DC) | MYSQLND_METHOD(mysqlnd_net, read_compressed_packet_from_stream_and_fill_read_buffer) |
| (MYSQLND_NET * net, size_t net_payload_size, MYSQLND_STATS * conn_stats, MYSQLND_ERROR_INFO * error_info TSRMLS_DC) |
{ |
{ |
MYSQLND_NET * net = conn->net; |
|
size_t decompressed_size; |
size_t decompressed_size; |
enum_func_status ret = PASS; |
enum_func_status ret = PASS; |
zend_uchar * compressed_data = NULL; |
zend_uchar * compressed_data = NULL; |
zend_uchar comp_header[COMPRESSED_HEADER_SIZE]; |
zend_uchar comp_header[COMPRESSED_HEADER_SIZE]; |
DBG_ENTER("mysqlnd_read_compressed_packet_from_stream_and_fill_read_buffer"); | DBG_ENTER("mysqlnd_net::read_compressed_packet_from_stream_and_fill_read_buffe"); |
|
|
/* Read the compressed header */ |
/* Read the compressed header */ |
if (FAIL == conn->net->m.network_read(conn, comp_header, COMPRESSED_HEADER_SIZE TSRMLS_CC)) { | if (FAIL == net->m.network_read_ex(net, comp_header, COMPRESSED_HEADER_SIZE, conn_stats, error_info TSRMLS_CC)) { |
DBG_RETURN(FAIL); |
DBG_RETURN(FAIL); |
} |
} |
decompressed_size = uint3korr(comp_header); |
decompressed_size = uint3korr(comp_header); |
Line 438 mysqlnd_read_compressed_packet_from_stream_and_fill_re
|
Line 502 mysqlnd_read_compressed_packet_from_stream_and_fill_re
|
|
|
if (decompressed_size) { |
if (decompressed_size) { |
compressed_data = mnd_emalloc(net_payload_size); |
compressed_data = mnd_emalloc(net_payload_size); |
if (FAIL == conn->net->m.network_read(conn, compressed_data, net_payload_size TSRMLS_CC)) { | if (FAIL == net->m.network_read_ex(net, compressed_data, net_payload_size, conn_stats, error_info TSRMLS_CC)) { |
ret = FAIL; |
ret = FAIL; |
goto end; |
goto end; |
} |
} |
Line 450 mysqlnd_read_compressed_packet_from_stream_and_fill_re
|
Line 514 mysqlnd_read_compressed_packet_from_stream_and_fill_re
|
} else { |
} else { |
DBG_INF_FMT("The server decided not to compress the data. Our job is easy. Copying %u bytes", net_payload_size); |
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); |
net->uncompressed_data = mysqlnd_create_read_buffer(net_payload_size TSRMLS_CC); |
if (FAIL == conn->net->m.network_read(conn, net->uncompressed_data->data, 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; |
ret = FAIL; |
goto end; |
goto end; |
} |
} |
Line 467 end:
|
Line 531 end:
|
|
|
/* {{{ mysqlnd_net::decode */ |
/* {{{ mysqlnd_net::decode */ |
static enum_func_status |
static enum_func_status |
MYSQLND_METHOD(mysqlnd_net, decode)(zend_uchar * uncompressed_data, size_t uncompressed_data_len, | MYSQLND_METHOD(mysqlnd_net, decode)(zend_uchar * uncompressed_data, const size_t uncompressed_data_len, |
const zend_uchar * const compressed_data, size_t compressed_data_len TSRMLS_DC) | const zend_uchar * const compressed_data, const size_t compressed_data_len TSRMLS_DC) |
{ |
{ |
#ifdef MYSQLND_COMPRESSION_ENABLED |
#ifdef MYSQLND_COMPRESSION_ENABLED |
int error; |
int error; |
Line 492 MYSQLND_METHOD(mysqlnd_net, decode)(zend_uchar * uncom
|
Line 556 MYSQLND_METHOD(mysqlnd_net, decode)(zend_uchar * uncom
|
/* {{{ mysqlnd_net::encode */ |
/* {{{ mysqlnd_net::encode */ |
static enum_func_status |
static enum_func_status |
MYSQLND_METHOD(mysqlnd_net, encode)(zend_uchar * compress_buffer, size_t * compress_buffer_len, |
MYSQLND_METHOD(mysqlnd_net, encode)(zend_uchar * compress_buffer, size_t * compress_buffer_len, |
const zend_uchar * const uncompressed_data, size_t uncompressed_data_len TSRMLS_DC) | const zend_uchar * const uncompressed_data, const size_t uncompressed_data_len TSRMLS_DC) |
{ |
{ |
#ifdef MYSQLND_COMPRESSION_ENABLED |
#ifdef MYSQLND_COMPRESSION_ENABLED |
int error; |
int error; |
Line 516 MYSQLND_METHOD(mysqlnd_net, encode)(zend_uchar * compr
|
Line 580 MYSQLND_METHOD(mysqlnd_net, encode)(zend_uchar * compr
|
/* }}} */ |
/* }}} */ |
|
|
|
|
/* {{{ mysqlnd_net::receive */ | /* {{{ mysqlnd_net::receive_ex */ |
static enum_func_status |
static enum_func_status |
MYSQLND_METHOD(mysqlnd_net, receive)(MYSQLND * conn, zend_uchar * buffer, size_t count TSRMLS_DC) | MYSQLND_METHOD(mysqlnd_net, receive_ex)(MYSQLND_NET * const net, zend_uchar * const buffer, const size_t count, |
| MYSQLND_STATS * const conn_stats, MYSQLND_ERROR_INFO * const error_info TSRMLS_DC) |
{ |
{ |
size_t to_read = count; |
size_t to_read = count; |
zend_uchar * p = buffer; |
zend_uchar * p = buffer; |
MYSQLND_NET * net = conn->net; |
|
|
|
DBG_ENTER("mysqlnd_net::receive"); | DBG_ENTER("mysqlnd_net::receive_ex"); |
#ifdef MYSQLND_COMPRESSION_ENABLED |
#ifdef MYSQLND_COMPRESSION_ENABLED |
if (net->compressed) { |
if (net->compressed) { |
if (net->uncompressed_data) { |
if (net->uncompressed_data) { |
Line 546 MYSQLND_METHOD(mysqlnd_net, receive)(MYSQLND * conn, z
|
Line 610 MYSQLND_METHOD(mysqlnd_net, receive)(MYSQLND * conn, z
|
size_t net_payload_size; |
size_t net_payload_size; |
zend_uchar packet_no; |
zend_uchar packet_no; |
|
|
if (FAIL == net->m.network_read(conn, net_header, MYSQLND_HEADER_SIZE TSRMLS_CC)) { | if (FAIL == net->m.network_read_ex(net, net_header, MYSQLND_HEADER_SIZE, conn_stats, error_info TSRMLS_CC)) { |
DBG_RETURN(FAIL); |
DBG_RETURN(FAIL); |
} |
} |
net_payload_size = uint3korr(net_header); |
net_payload_size = uint3korr(net_header); |
Line 564 MYSQLND_METHOD(mysqlnd_net, receive)(MYSQLND * conn, z
|
Line 628 MYSQLND_METHOD(mysqlnd_net, receive)(MYSQLND * conn, z
|
DBG_INF_FMT("HEADER: hwd_packet_no=%u size=%3u", packet_no, (unsigned long) net_payload_size); |
DBG_INF_FMT("HEADER: hwd_packet_no=%u size=%3u", packet_no, (unsigned long) net_payload_size); |
#endif |
#endif |
/* Now let's read from the wire, decompress it and fill the read buffer */ |
/* Now let's read from the wire, decompress it and fill the read buffer */ |
mysqlnd_read_compressed_packet_from_stream_and_fill_read_buffer(conn, net_payload_size TSRMLS_CC); | net->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, |
Now a bit of recursion - read from the read buffer, |
Line 572 MYSQLND_METHOD(mysqlnd_net, receive)(MYSQLND * conn, z
|
Line 636 MYSQLND_METHOD(mysqlnd_net, receive)(MYSQLND * conn, z
|
is not enough, then the recursive call will try to |
is not enough, then the recursive call will try to |
satisfy it until it is satisfied. |
satisfy it until it is satisfied. |
*/ |
*/ |
DBG_RETURN(net->m.receive(conn, p, to_read TSRMLS_CC)); | DBG_RETURN(net->m.receive_ex(net, p, to_read, conn_stats, error_info TSRMLS_CC)); |
} |
} |
DBG_RETURN(PASS); |
DBG_RETURN(PASS); |
} |
} |
#endif /* MYSQLND_COMPRESSION_ENABLED */ |
#endif /* MYSQLND_COMPRESSION_ENABLED */ |
DBG_RETURN(net->m.network_read(conn, p, to_read TSRMLS_CC)); | DBG_RETURN(net->m.network_read_ex(net, p, to_read, conn_stats, error_info TSRMLS_CC)); |
} |
} |
/* }}} */ |
/* }}} */ |
|
|
Line 668 MYSQLND_METHOD(mysqlnd_net, set_client_option)(MYSQLND
|
Line 732 MYSQLND_METHOD(mysqlnd_net, set_client_option)(MYSQLND
|
case MYSQL_OPT_SSL_VERIFY_SERVER_CERT: |
case MYSQL_OPT_SSL_VERIFY_SERVER_CERT: |
net->options.ssl_verify_peer = value? ((*(zend_bool *)value)? TRUE:FALSE): FALSE; |
net->options.ssl_verify_peer = value? ((*(zend_bool *)value)? TRUE:FALSE): FALSE; |
break; |
break; |
#ifdef WHEN_SUPPORTED_BY_MYSQLI |
|
case MYSQL_OPT_READ_TIMEOUT: |
case MYSQL_OPT_READ_TIMEOUT: |
DBG_INF("MYSQL_OPT_READ_TIMEOUT"); |
|
net->options.timeout_read = *(unsigned int*) value; |
net->options.timeout_read = *(unsigned int*) value; |
break; |
break; |
|
#ifdef WHEN_SUPPORTED_BY_MYSQLI |
case MYSQL_OPT_WRITE_TIMEOUT: |
case MYSQL_OPT_WRITE_TIMEOUT: |
DBG_INF("MYSQL_OPT_WRITE_TIMEOUT"); |
|
net->options.timeout_write = *(unsigned int*) value; |
net->options.timeout_write = *(unsigned int*) value; |
break; |
break; |
#endif |
#endif |
Line 744 static enum_func_status
|
Line 806 static enum_func_status
|
MYSQLND_METHOD(mysqlnd_net, enable_ssl)(MYSQLND_NET * const net TSRMLS_DC) |
MYSQLND_METHOD(mysqlnd_net, enable_ssl)(MYSQLND_NET * const net TSRMLS_DC) |
{ |
{ |
#ifdef MYSQLND_SSL_SUPPORTED |
#ifdef MYSQLND_SSL_SUPPORTED |
php_stream_context *context = php_stream_context_alloc(); | php_stream_context *context = php_stream_context_alloc(TSRMLS_C); |
DBG_ENTER("mysqlnd_net::enable_ssl"); |
DBG_ENTER("mysqlnd_net::enable_ssl"); |
if (!context) { |
if (!context) { |
DBG_RETURN(FAIL); |
DBG_RETURN(FAIL); |
Line 753 MYSQLND_METHOD(mysqlnd_net, enable_ssl)(MYSQLND_NET *
|
Line 815 MYSQLND_METHOD(mysqlnd_net, enable_ssl)(MYSQLND_NET *
|
if (net->options.ssl_key) { |
if (net->options.ssl_key) { |
zval key_zval; |
zval key_zval; |
ZVAL_STRING(&key_zval, net->options.ssl_key, 0); |
ZVAL_STRING(&key_zval, net->options.ssl_key, 0); |
DBG_INF("key"); |
|
php_stream_context_set_option(context, "ssl", "local_pk", &key_zval); |
php_stream_context_set_option(context, "ssl", "local_pk", &key_zval); |
} |
} |
if (net->options.ssl_verify_peer) { |
if (net->options.ssl_verify_peer) { |
zval verify_peer_zval; |
zval verify_peer_zval; |
ZVAL_TRUE(&verify_peer_zval); |
ZVAL_TRUE(&verify_peer_zval); |
DBG_INF("verify peer"); |
|
php_stream_context_set_option(context, "ssl", "verify_peer", &verify_peer_zval); |
php_stream_context_set_option(context, "ssl", "verify_peer", &verify_peer_zval); |
} |
} |
if (net->options.ssl_cert) { |
if (net->options.ssl_cert) { |
zval cert_zval; |
zval cert_zval; |
ZVAL_STRING(&cert_zval, net->options.ssl_cert, 0); |
ZVAL_STRING(&cert_zval, net->options.ssl_cert, 0); |
DBG_INF_FMT("local_cert=%s", net->options.ssl_cert); |
|
php_stream_context_set_option(context, "ssl", "local_cert", &cert_zval); |
php_stream_context_set_option(context, "ssl", "local_cert", &cert_zval); |
if (!net->options.ssl_key) { |
if (!net->options.ssl_key) { |
php_stream_context_set_option(context, "ssl", "local_pk", &cert_zval); |
php_stream_context_set_option(context, "ssl", "local_pk", &cert_zval); |
Line 774 MYSQLND_METHOD(mysqlnd_net, enable_ssl)(MYSQLND_NET *
|
Line 833 MYSQLND_METHOD(mysqlnd_net, enable_ssl)(MYSQLND_NET *
|
if (net->options.ssl_ca) { |
if (net->options.ssl_ca) { |
zval cafile_zval; |
zval cafile_zval; |
ZVAL_STRING(&cafile_zval, net->options.ssl_ca, 0); |
ZVAL_STRING(&cafile_zval, net->options.ssl_ca, 0); |
DBG_INF_FMT("cafile=%s", net->options.ssl_ca); |
|
php_stream_context_set_option(context, "ssl", "cafile", &cafile_zval); |
php_stream_context_set_option(context, "ssl", "cafile", &cafile_zval); |
} |
} |
if (net->options.ssl_capath) { |
if (net->options.ssl_capath) { |
zval capath_zval; |
zval capath_zval; |
ZVAL_STRING(&capath_zval, net->options.ssl_capath, 0); |
ZVAL_STRING(&capath_zval, net->options.ssl_capath, 0); |
DBG_INF_FMT("capath=%s", net->options.ssl_capath); |
|
php_stream_context_set_option(context, "ssl", "cafile", &capath_zval); |
php_stream_context_set_option(context, "ssl", "cafile", &capath_zval); |
} |
} |
if (net->options.ssl_passphrase) { |
if (net->options.ssl_passphrase) { |
Line 791 MYSQLND_METHOD(mysqlnd_net, enable_ssl)(MYSQLND_NET *
|
Line 848 MYSQLND_METHOD(mysqlnd_net, enable_ssl)(MYSQLND_NET *
|
if (net->options.ssl_cipher) { |
if (net->options.ssl_cipher) { |
zval cipher_zval; |
zval cipher_zval; |
ZVAL_STRING(&cipher_zval, net->options.ssl_cipher, 0); |
ZVAL_STRING(&cipher_zval, net->options.ssl_cipher, 0); |
DBG_INF_FMT("ciphers=%s", net->options.ssl_cipher); |
|
php_stream_context_set_option(context, "ssl", "ciphers", &cipher_zval); |
php_stream_context_set_option(context, "ssl", "ciphers", &cipher_zval); |
} |
} |
php_stream_context_set(net->stream, context); |
php_stream_context_set(net->stream, context); |
Line 838 MYSQLND_METHOD(mysqlnd_net, disable_ssl)(MYSQLND_NET *
|
Line 894 MYSQLND_METHOD(mysqlnd_net, disable_ssl)(MYSQLND_NET *
|
/* }}} */ |
/* }}} */ |
|
|
|
|
/* {{{ mysqlnd_net::set_client_option */ | /* {{{ mysqlnd_net::free_contents */ |
static void |
static void |
MYSQLND_METHOD(mysqlnd_net, free_contents)(MYSQLND_NET * net TSRMLS_DC) |
MYSQLND_METHOD(mysqlnd_net, free_contents)(MYSQLND_NET * net TSRMLS_DC) |
{ |
{ |
Line 875 MYSQLND_METHOD(mysqlnd_net, free_contents)(MYSQLND_NET
|
Line 931 MYSQLND_METHOD(mysqlnd_net, free_contents)(MYSQLND_NET
|
} |
} |
/* }}} */ |
/* }}} */ |
|
|
static |
|
MYSQLND_CLASS_METHODS_START(mysqlnd_net) |
|
MYSQLND_METHOD(mysqlnd_net, connect), |
|
MYSQLND_METHOD(mysqlnd_net, send), |
|
MYSQLND_METHOD(mysqlnd_net, receive), |
|
MYSQLND_METHOD(mysqlnd_net, set_client_option), |
|
MYSQLND_METHOD(mysqlnd_net, network_read), |
|
MYSQLND_METHOD(mysqlnd_net, network_write), |
|
MYSQLND_METHOD(mysqlnd_net, decode), |
|
MYSQLND_METHOD(mysqlnd_net, encode), |
|
MYSQLND_METHOD(mysqlnd_net, consume_uneaten_data), |
|
MYSQLND_METHOD(mysqlnd_net, free_contents), |
|
MYSQLND_METHOD(mysqlnd_net, enable_ssl), |
|
MYSQLND_METHOD(mysqlnd_net, disable_ssl) |
|
MYSQLND_CLASS_METHODS_END; |
|
|
|
| /* {{{ mysqlnd_net::close_stream */ |
/* {{{ mysqlnd_net_init */ | static void |
PHPAPI MYSQLND_NET * | MYSQLND_METHOD(mysqlnd_net, close_stream)(MYSQLND_NET * const net, MYSQLND_STATS * const stats, MYSQLND_ERROR_INFO * const error_info TSRMLS_DC) |
mysqlnd_net_init(zend_bool persistent TSRMLS_DC) | |
{ |
{ |
size_t alloc_size = sizeof(MYSQLND_NET) + mysqlnd_plugin_count() * sizeof(void *); | DBG_ENTER("mysqlnd_net::close_stream"); |
MYSQLND_NET * net = mnd_pecalloc(1, alloc_size, persistent); | if (net && net->stream) { |
| zend_bool pers = net->persistent; |
DBG_ENTER("mysqlnd_net_init"); | DBG_INF_FMT("Freeing stream. abstract=%p", net->stream->abstract); |
DBG_INF_FMT("persistent=%u", persistent); | if (pers) { |
if (net) { | if (EG(active)) { |
net->persistent = persistent; | php_stream_free(net->stream, PHP_STREAM_FREE_CLOSE_PERSISTENT | PHP_STREAM_FREE_RSRC_DTOR); |
net->m = mysqlnd_mysqlnd_net_methods; | } else { |
| /* |
{ | otherwise we will crash because the EG(persistent_list) has been freed already, |
unsigned int buf_size = MYSQLND_G(net_cmd_buffer_size); /* this is long, cast to unsigned int*/ | before the modules are shut down |
net->m.set_client_option(net, MYSQLND_OPT_NET_CMD_BUFFER_SIZE, (char *) &buf_size TSRMLS_CC); | */ |
| php_stream_free(net->stream, PHP_STREAM_FREE_CLOSE | PHP_STREAM_FREE_RSRC_DTOR); |
| } |
| } else { |
| php_stream_free(net->stream, PHP_STREAM_FREE_CLOSE); |
} |
} |
|
net->stream = NULL; |
} |
} |
DBG_RETURN(net); | |
| DBG_VOID_RETURN; |
} |
} |
/* }}} */ |
/* }}} */ |
|
|
|
|
/* {{{ mysqlnd_net_free */ | /* {{{ mysqlnd_net::init */ |
PHPAPI void | static enum_func_status |
mysqlnd_net_free(MYSQLND_NET * const net TSRMLS_DC) | MYSQLND_METHOD(mysqlnd_net, init)(MYSQLND_NET * const net, MYSQLND_STATS * const stats, MYSQLND_ERROR_INFO * const error_info TSRMLS_DC) |
{ |
{ |
DBG_ENTER("mysqlnd_net_free"); | unsigned int buf_size; |
| 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); |
|
|
|
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); |
|
|
|
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); |
|
|
|
DBG_RETURN(PASS); |
|
} |
|
/* }}} */ |
|
|
|
|
|
/* {{{ mysqlnd_net::dtor */ |
|
static void |
|
MYSQLND_METHOD(mysqlnd_net, dtor)(MYSQLND_NET * const net, MYSQLND_STATS * const stats, MYSQLND_ERROR_INFO * const error_info TSRMLS_DC) |
|
{ |
|
DBG_ENTER("mysqlnd_net::dtor"); |
if (net) { |
if (net) { |
zend_bool pers = net->persistent; |
zend_bool pers = net->persistent; |
| |
net->m.free_contents(net TSRMLS_CC); |
net->m.free_contents(net TSRMLS_CC); |
|
net->m.close_stream(net, stats, error_info TSRMLS_CC); |
if (net->cmd_buffer.buffer) { |
if (net->cmd_buffer.buffer) { |
DBG_INF("Freeing cmd buffer"); |
DBG_INF("Freeing cmd buffer"); |
mnd_pefree(net->cmd_buffer.buffer, pers); |
mnd_pefree(net->cmd_buffer.buffer, pers); |
net->cmd_buffer.buffer = NULL; |
net->cmd_buffer.buffer = NULL; |
} |
} |
if (net->stream) { |
|
DBG_INF_FMT("Freeing stream. abstract=%p", net->stream->abstract); |
|
if (pers) { |
|
php_stream_free(net->stream, PHP_STREAM_FREE_CLOSE_PERSISTENT | PHP_STREAM_FREE_RSRC_DTOR); |
|
} else { |
|
php_stream_free(net->stream, PHP_STREAM_FREE_CLOSE); |
|
} |
|
net->stream = NULL; |
|
} |
|
mnd_pefree(net, pers); |
mnd_pefree(net, pers); |
} |
} |
DBG_VOID_RETURN; |
DBG_VOID_RETURN; |
Line 946 mysqlnd_net_free(MYSQLND_NET * const net TSRMLS_DC)
|
Line 1004 mysqlnd_net_free(MYSQLND_NET * const net TSRMLS_DC)
|
/* }}} */ |
/* }}} */ |
|
|
|
|
/* {{{ _mysqlnd_plugin_get_plugin_net_data */ | MYSQLND_CLASS_METHODS_START(mysqlnd_net) |
PHPAPI void ** _mysqlnd_plugin_get_plugin_net_data(const MYSQLND_NET * net, unsigned int plugin_id TSRMLS_DC) | MYSQLND_METHOD(mysqlnd_net, init), |
| MYSQLND_METHOD(mysqlnd_net, dtor), |
| MYSQLND_METHOD(mysqlnd_net, connect_ex), |
| MYSQLND_METHOD(mysqlnd_net, close_stream), |
| MYSQLND_METHOD(mysqlnd_net, open_pipe), |
| MYSQLND_METHOD(mysqlnd_net, open_tcp_or_unix), |
| NULL, /* unused 1 */ |
| NULL, /* unused 2 */ |
| MYSQLND_METHOD(mysqlnd_net, post_connect_set_opt), |
| MYSQLND_METHOD(mysqlnd_net, set_client_option), |
| MYSQLND_METHOD(mysqlnd_net, decode), |
| MYSQLND_METHOD(mysqlnd_net, encode), |
| MYSQLND_METHOD(mysqlnd_net, consume_uneaten_data), |
| MYSQLND_METHOD(mysqlnd_net, free_contents), |
| MYSQLND_METHOD(mysqlnd_net, enable_ssl), |
| MYSQLND_METHOD(mysqlnd_net, disable_ssl), |
| MYSQLND_METHOD(mysqlnd_net, network_read_ex), |
| MYSQLND_METHOD(mysqlnd_net, network_write_ex), |
| MYSQLND_METHOD(mysqlnd_net, send_ex), |
| MYSQLND_METHOD(mysqlnd_net, receive_ex), |
| #ifdef MYSQLND_COMPRESSION_ENABLED |
| MYSQLND_METHOD(mysqlnd_net, read_compressed_packet_from_stream_and_fill_read_buffer) |
| #else |
| NULL |
| #endif |
| MYSQLND_CLASS_METHODS_END; |
| |
| |
| /* {{{ mysqlnd_net_init */ |
| PHPAPI MYSQLND_NET * |
| mysqlnd_net_init(zend_bool persistent, MYSQLND_STATS * stats, MYSQLND_ERROR_INFO * error_info TSRMLS_DC) |
{ |
{ |
DBG_ENTER("_mysqlnd_plugin_get_plugin_net_data"); | MYSQLND_NET * net; |
DBG_INF_FMT("plugin_id=%u", plugin_id); | DBG_ENTER("mysqlnd_net_init"); |
if (!net || plugin_id >= mysqlnd_plugin_count()) { | net = MYSQLND_CLASS_METHOD_TABLE_NAME(mysqlnd_object_factory).get_io_channel(persistent, stats, error_info TSRMLS_CC); |
return NULL; | DBG_RETURN(net); |
} | |
DBG_RETURN((void *)((char *)net + sizeof(MYSQLND_NET) + plugin_id * sizeof(void *))); | |
} |
} |
/* }}} */ |
/* }}} */ |
|
|
|
|
/* {{{ mysqlnd_net_get_methods */ | /* {{{ mysqlnd_net_free */ |
PHPAPI struct st_mysqlnd_net_methods * | PHPAPI void |
mysqlnd_net_get_methods() | mysqlnd_net_free(MYSQLND_NET * const net, MYSQLND_STATS * stats, MYSQLND_ERROR_INFO * error_info TSRMLS_DC) |
{ |
{ |
return &mysqlnd_mysqlnd_net_methods; | DBG_ENTER("mysqlnd_net_free"); |
| if (net) { |
| net->m.dtor(net, stats, error_info TSRMLS_CC); |
| } |
| DBG_VOID_RETURN; |
} |
} |
/* }}} */ |
/* }}} */ |
|
|
|
|
|
|
/* |
/* |