diff options
Diffstat (limited to 'ext/mysqlnd/mysqlnd_net.c')
-rw-r--r-- | ext/mysqlnd/mysqlnd_net.c | 317 |
1 files changed, 270 insertions, 47 deletions
diff --git a/ext/mysqlnd/mysqlnd_net.c b/ext/mysqlnd/mysqlnd_net.c index 8f4c46e9d..207fa53f0 100644 --- a/ext/mysqlnd/mysqlnd_net.c +++ b/ext/mysqlnd/mysqlnd_net.c @@ -1,8 +1,8 @@ /* +----------------------------------------------------------------------+ - | PHP Version 6 | + | PHP Version 5 | +----------------------------------------------------------------------+ - | Copyright (c) 2006-2009 The PHP Group | + | Copyright (c) 2006-2010 The PHP Group | +----------------------------------------------------------------------+ | This source file is subject to version 3.01 of the PHP license, | | that is bundled with this package in the file LICENSE, and is | @@ -102,7 +102,11 @@ MYSQLND_METHOD(mysqlnd_net, network_write)(MYSQLND * const conn, const zend_ucha 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) { +#if PHP_API_VERSION < 20100412 unsigned int streams_options = ENFORCE_SAFE_MODE; +#else + unsigned int streams_options = 0; +#endif unsigned int streams_flags = STREAM_XPORT_CLIENT | STREAM_XPORT_CONNECT; char * hashed_details = NULL; int hashed_details_len = 0; @@ -121,14 +125,14 @@ MYSQLND_METHOD(mysqlnd_net, connect)(MYSQLND_NET * net, const char * const schem 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, NULL /*ctx*/, errstr, errcode); - if (*errstr || !net->stream) { if (hashed_details) { - efree(hashed_details); + efree(hashed_details); /* allocated by spprintf */ } *errcode = CR_CONNECTION_ERROR; DBG_RETURN(FAIL); @@ -142,8 +146,7 @@ MYSQLND_METHOD(mysqlnd_net, connect)(MYSQLND_NET * net, const char * const schem */ zend_rsrc_list_entry *le; - if (zend_hash_find(&EG(persistent_list), hashed_details, hashed_details_len + 1, - (void*) &le) == SUCCESS) { + if (zend_hash_find(&EG(persistent_list), hashed_details, hashed_details_len + 1, (void*) &le) == SUCCESS) { /* in_free will let streams code skip destructing - big HACK, but STREAMS suck big time regarding persistent streams. @@ -159,13 +162,21 @@ MYSQLND_METHOD(mysqlnd_net, connect)(MYSQLND_NET * net, const char * const schem #endif efree(hashed_details); } + /* + 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 till 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; if (!net->options.timeout_read) { /* should always happen because read_timeout cannot be set via API */ net->options.timeout_read = (unsigned int) MYSQLND_G(net_read_timeout); } - if (net->options.timeout_read) - { + if (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_usec = 0; php_stream_set_option(net->stream, PHP_STREAM_OPTION_READ_TIMEOUT, 0, &tv); @@ -188,13 +199,18 @@ MYSQLND_METHOD(mysqlnd_net, connect)(MYSQLND_NET * net, const char * const schem /* We assume that MYSQLND_HEADER_SIZE is 4 bytes !! */ -#define STORE_HEADER_SIZE(safe_storage, buffer) int4store((safe_storage), (*(uint32_t *)(buffer))) +#define COPY_HEADER(T,A) do { \ + *(((char *)(T))) = *(((char *)(A)));\ + *(((char *)(T))+1) = *(((char *)(A))+1);\ + *(((char *)(T))+2) = *(((char *)(A))+2);\ + *(((char *)(T))+3) = *(((char *)(A))+3); } while (0) +#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)) /* {{{ mysqlnd_net::send */ /* IMPORTANT : It's expected that buf 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. Neither are quick, thus the clients of this function are obligated to do what they are asked for. @@ -216,14 +232,14 @@ MYSQLND_METHOD(mysqlnd_net, send)(MYSQLND * const conn, char * const buf, size_t size_t to_be_sent; DBG_ENTER("mysqlnd_net::send"); - DBG_INF_FMT("conn=%llu count=%lu compression=%d", conn->thread_id, count, net->compressed); + DBG_INF_FMT("conn=%llu count=%lu compression=%u", conn->thread_id, count, net->compressed); net->stream->chunk_size = MYSQLND_MAX_PACKET_SIZE; if (net->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=%d", comp_buf_size); - compress_buf = emalloc(comp_buf_size); + DBG_INF_FMT("compress_buf_size="MYSQLND_SZ_T_SPEC, comp_buf_size); + compress_buf = mnd_emalloc(comp_buf_size); } do { @@ -238,7 +254,9 @@ MYSQLND_METHOD(mysqlnd_net, send)(MYSQLND * const conn, char * const buf, size_t 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, uncompressed_payload, to_be_sent + MYSQLND_HEADER_SIZE TSRMLS_CC)) { + if (PASS == net->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); payload_size = tmp_complen; } else { @@ -250,14 +268,15 @@ MYSQLND_METHOD(mysqlnd_net, send)(MYSQLND * const conn, char * const buf, size_t int3store(compress_buf, payload_size); int1store(compress_buf + 3, net->packet_no); - DBG_INF_FMT("writing %d 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); 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 = malloc(decompressed_size); - int error = net->m.decode(decompressed_data, decompressed_size, compress_buf + MYSQLND_HEADER_SIZE + COMPRESSED_HEADER_SIZE, payload_size); + zend_uchar * decompressed_data = mnd_malloc(decompressed_size); + int error = net->m.decode(decompressed_data, decompressed_size, + compress_buf + MYSQLND_HEADER_SIZE + COMPRESSED_HEADER_SIZE, payload_size); if (error == Z_OK) { int i; DBG_INF("success decompressing"); @@ -271,7 +290,7 @@ MYSQLND_METHOD(mysqlnd_net, send)(MYSQLND * const conn, char * const buf, size_t } else { DBG_INF("error decompressing"); } - free(decompressed_data); + mnd_free(decompressed_data); } #endif /* WHEN_WE_NEED_TO_CHECK_WHETHER_COMPRESSION_WORKS_CORRECTLY */ } else @@ -299,7 +318,7 @@ MYSQLND_METHOD(mysqlnd_net, send)(MYSQLND * const conn, char * const buf, size_t */ } while (ret && (left > 0 || to_be_sent == MYSQLND_MAX_PACKET_SIZE)); - DBG_INF_FMT("packet_size=%d packet_no=%d", 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); @@ -314,7 +333,7 @@ MYSQLND_METHOD(mysqlnd_net, send)(MYSQLND * const conn, char * const buf, size_t net->stream->chunk_size = old_chunk_size; if (compress_buf) { - efree(compress_buf); + mnd_efree(compress_buf); } DBG_RETURN(ret); } @@ -407,7 +426,7 @@ mysqlnd_read_compressed_packet_from_stream_and_fill_read_buffer(MYSQLND * conn, /* we need to decompress the data */ if (decompressed_size) { - compressed_data = 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)) { ret = FAIL; goto end; @@ -427,7 +446,7 @@ mysqlnd_read_compressed_packet_from_stream_and_fill_read_buffer(MYSQLND * conn, } end: if (compressed_data) { - efree(compressed_data); + mnd_efree(compressed_data); } DBG_RETURN(ret); } @@ -440,16 +459,21 @@ static enum_func_status MYSQLND_METHOD(mysqlnd_net, decode)(zend_uchar * uncompressed_data, size_t uncompressed_data_len, const zend_uchar * const compressed_data, size_t compressed_data_len TSRMLS_DC) { +#ifdef MYSQLND_COMPRESSION_ENABLED int error; uLongf tmp_complen = uncompressed_data_len; DBG_ENTER("mysqlnd_net::decode"); error = uncompress(uncompressed_data, &tmp_complen, compressed_data, compressed_data_len); - DBG_INF_FMT("compressed data: decomp_len=%d compressed_size=%d", tmp_complen, compressed_data_len); + DBG_INF_FMT("compressed data: decomp_len=%lu compressed_size="MYSQLND_SZ_T_SPEC, tmp_complen, compressed_data_len); if (error != Z_OK) { DBG_INF_FMT("decompression NOT successful. error=%d Z_OK=%d Z_BUF_ERROR=%d Z_MEM_ERROR=%d", error, Z_OK, Z_BUF_ERROR, Z_MEM_ERROR); } DBG_RETURN(error == Z_OK? PASS:FAIL); +#else + DBG_ENTER("mysqlnd_net::decode"); + DBG_RETURN(FAIL); +#endif } /* }}} */ @@ -459,6 +483,7 @@ static enum_func_status 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) { +#ifdef MYSQLND_COMPRESSION_ENABLED int error; uLongf tmp_complen = compress_buffer_len; DBG_ENTER("mysqlnd_net::encode"); @@ -467,15 +492,19 @@ MYSQLND_METHOD(mysqlnd_net, encode)(zend_uchar * compress_buffer, size_t compres if (error != Z_OK) { DBG_INF_FMT("compression NOT successful. error=%d Z_OK=%d Z_BUF_ERROR=%d Z_MEM_ERROR=%d", error, Z_OK, Z_BUF_ERROR, Z_MEM_ERROR); } else { - DBG_INF_FMT("compression successful. compressed size=%d", tmp_complen); + DBG_INF_FMT("compression successful. compressed size=%lu", tmp_complen); } DBG_RETURN(error == Z_OK? PASS:FAIL); +#else + DBG_ENTER("mysqlnd_net::encode"); + DBG_RETURN(FAIL); +#endif } /* }}} */ /* {{{ mysqlnd_net::receive */ -static size_t +static enum_func_status MYSQLND_METHOD(mysqlnd_net, receive)(MYSQLND * conn, zend_uchar * buffer, size_t count TSRMLS_DC) { size_t to_read = count; @@ -510,16 +539,16 @@ MYSQLND_METHOD(mysqlnd_net, receive)(MYSQLND * conn, zend_uchar * buffer, size_t net_payload_size = uint3korr(net_header); packet_no = uint1korr(net_header + 3); if (net->compressed_envelope_packet_no != packet_no) { - DBG_ERR_FMT("Transport level: packets out of order. Expected %d received %d. Packet size=%d", + DBG_ERR_FMT("Transport level: packets out of order. Expected %u received %u. Packet size="MYSQLND_SZ_T_SPEC, net->compressed_envelope_packet_no, packet_no, net_payload_size); - php_error(E_WARNING, "Packets out of order. Expected %d received %d. Packet size="MYSQLND_SZ_T_SPEC, + php_error(E_WARNING, "Packets out of order. Expected %u received %u. Packet size="MYSQLND_SZ_T_SPEC, net->compressed_envelope_packet_no, packet_no, net_payload_size); DBG_RETURN(FAIL); } net->compressed_envelope_packet_no++; #ifdef MYSQLND_DUMP_HEADER_N_BODY - DBG_INF_FMT("HEADER: hwd_packet_no=%d size=%3d", packet_no, net_payload_size); + 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 */ mysqlnd_read_compressed_packet_from_stream_and_fill_read_buffer(conn, net_payload_size TSRMLS_CC); @@ -545,7 +574,7 @@ static enum_func_status MYSQLND_METHOD(mysqlnd_net, set_client_option)(MYSQLND_NET * const net, enum mysqlnd_option option, const char * const value TSRMLS_DC) { DBG_ENTER("mysqlnd_net::set_client_option"); - DBG_INF_FMT("option=%d", option); + DBG_INF_FMT("option=%u", option); switch (option) { case MYSQLND_OPT_NET_CMD_BUFFER_SIZE: DBG_INF("MYSQLND_OPT_NET_CMD_BUFFER_SIZE"); @@ -569,6 +598,63 @@ MYSQLND_METHOD(mysqlnd_net, set_client_option)(MYSQLND_NET * const net, enum mys DBG_INF("MYSQL_OPT_CONNECT_TIMEOUT"); net->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); + } + net->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); + } + net->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); + } + net->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); + } + net->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); + } + net->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); + } + net->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; + break; #ifdef WHEN_SUPPORTED_BY_MYSQLI case MYSQL_OPT_READ_TIMEOUT: DBG_INF("MYSQL_OPT_READ_TIMEOUT"); @@ -639,12 +725,113 @@ MYSQLND_METHOD(mysqlnd_net, consume_uneaten_data)(MYSQLND_NET * const net, enum } /* }}} */ +/* + in libmyusql, if cert and !key then key=cert +*/ +/* {{{ mysqlnd_net::enable_ssl */ +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(); + DBG_ENTER("mysqlnd_net::enable_ssl"); + if (!context) { + DBG_RETURN(FAIL); + } + + if (net->options.ssl_key) { + zval key_zval; + ZVAL_STRING(&key_zval, net->options.ssl_key, 0); + DBG_INF("key"); + php_stream_context_set_option(context, "ssl", "local_pk", &key_zval); + } + if (net->options.ssl_verify_peer) { + zval verify_peer_zval; + ZVAL_TRUE(&verify_peer_zval); + DBG_INF("verify peer"); + php_stream_context_set_option(context, "ssl", "verify_peer", &verify_peer_zval); + } + if (net->options.ssl_cert) { + zval cert_zval; + 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); + if (!net->options.ssl_key) { + php_stream_context_set_option(context, "ssl", "local_pk", &cert_zval); + } + } + if (net->options.ssl_ca) { + zval cafile_zval; + 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); + } + if (net->options.ssl_capath) { + zval capath_zval; + 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); + } + if (net->options.ssl_passphrase) { + zval passphrase_zval; + ZVAL_STRING(&passphrase_zval, net->options.ssl_passphrase, 0); + php_stream_context_set_option(context, "ssl", "passphrase", &passphrase_zval); + } + if (net->options.ssl_cipher) { + zval cipher_zval; + 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(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"); + DBG_RETURN(FAIL); + } + /* + get rid of the context. we are persistent and if this is a real pconn used by mysql/mysqli, + then the context would not survive cleaning of EG(regular_list), where it is registered, as a + resource. What happens is that after this destruction any use of the network will mean usage + 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); + + 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); + } + + DBG_RETURN(PASS); +#else + DBG_ENTER("mysqlnd_net::enable_ssl"); + DBG_RETURN(PASS); +#endif +} +/* }}} */ + + +/* {{{ mysqlnd_net::disable_ssl */ +static enum_func_status +MYSQLND_METHOD(mysqlnd_net, disable_ssl)(MYSQLND_NET * const net TSRMLS_DC) +{ + DBG_ENTER("mysqlnd_net::disable_ssl"); + DBG_RETURN(PASS); +} +/* }}} */ /* {{{ mysqlnd_net::set_client_option */ static void MYSQLND_METHOD(mysqlnd_net, free_contents)(MYSQLND_NET * net TSRMLS_DC) { + zend_bool pers = net->persistent; DBG_ENTER("mysqlnd_net::free_contents"); #ifdef MYSQLND_COMPRESSION_ENABLED @@ -652,10 +839,47 @@ 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->options.ssl_cert) { + mnd_pefree(net->options.ssl_cert, pers); + net->options.ssl_cert = NULL; + } + if (net->options.ssl_ca) { + mnd_pefree(net->options.ssl_ca, pers); + net->options.ssl_ca = NULL; + } + if (net->options.ssl_capath) { + mnd_pefree(net->options.ssl_capath, pers); + net->options.ssl_capath = NULL; + } + if (net->options.ssl_cipher) { + mnd_pefree(net->options.ssl_cipher, pers); + net->options.ssl_cipher = NULL; + } + DBG_VOID_RETURN; } /* }}} */ +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_init */ PHPAPI MYSQLND_NET * @@ -665,23 +889,15 @@ mysqlnd_net_init(zend_bool persistent TSRMLS_DC) MYSQLND_NET * net = mnd_pecalloc(1, alloc_size, persistent); DBG_ENTER("mysqlnd_net_init"); - DBG_INF_FMT("persistent=%d", persistent); - net->persistent = persistent; - - net->m.connect = MYSQLND_METHOD(mysqlnd_net, connect); - net->m.send = MYSQLND_METHOD(mysqlnd_net, send); - net->m.receive = MYSQLND_METHOD(mysqlnd_net, receive); - net->m.set_client_option = MYSQLND_METHOD(mysqlnd_net, set_client_option); - net->m.network_read = MYSQLND_METHOD(mysqlnd_net, network_read); - net->m.network_write = MYSQLND_METHOD(mysqlnd_net, network_write); - net->m.decode = MYSQLND_METHOD(mysqlnd_net, decode); - net->m.encode = MYSQLND_METHOD(mysqlnd_net, encode); - net->m.consume_uneaten_data = MYSQLND_METHOD(mysqlnd_net, consume_uneaten_data); - net->m.free_contents = MYSQLND_METHOD(mysqlnd_net, free_contents); + DBG_INF_FMT("persistent=%u", persistent); + if (net) { + net->persistent = persistent; + net->m = mysqlnd_mysqlnd_net_methods; - { - 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_CMD_BUFFER_SIZE, (char *) &buf_size TSRMLS_CC); + { + unsigned int 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); + } } DBG_RETURN(net); } @@ -703,13 +919,12 @@ mysqlnd_net_free(MYSQLND_NET * const net TSRMLS_DC) mnd_pefree(net->cmd_buffer.buffer, pers); 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); + php_stream_free(net->stream, PHP_STREAM_FREE_CLOSE); } net->stream = NULL; } @@ -733,6 +948,14 @@ PHPAPI void ** _mysqlnd_plugin_get_plugin_net_data(const MYSQLND_NET * net, unsi /* }}} */ +/* {{{ mysqlnd_net_get_methods */ +PHPAPI struct st_mysqlnd_net_methods * +mysqlnd_net_get_methods() +{ + return &mysqlnd_mysqlnd_net_methods; +} +/* }}} */ + /* * Local variables: |