27#include <netinet/tcp.h>
40 int result = setsockopt(socketd, IPPROTO_TCP,
TCP_NODELAY, (
char *) &flag,
sizeof(
int));
42 DBG_ENTER(
"mysqlnd_set_sock_no_delay");
62 DBG_ENTER(
"mysqlnd_set_sock_keepalive");
79 php_stream * net_stream = vio->data->m.get_stream(vio);
80 size_t to_read =
count;
83 DBG_ENTER(
"mysqlnd_vio::network_read");
84 DBG_INF_FMT(
"count=%zu",
count);
89 DBG_ERR_FMT(
"Error while reading header from socket");
108 DBG_ENTER(
"mysqlnd_vio::network_write");
109 DBG_INF_FMT(
"sending %zu bytes",
count);
115static void mysqlnd_fixup_regular_list(
php_stream *net_stream)
123 EG(regular_list).pDestructor =
NULL;
125 EG(regular_list).pDestructor = origin_dtor;
135 unsigned int streams_options = 0;
138 DBG_ENTER(
"mysqlnd_vio::open_pipe");
161 if (current_res->
ptr == net_stream) {
163 EG(persistent_list).pDestructor =
NULL;
165 EG(persistent_list).pDestructor = origin_dtor;
175 mysqlnd_fixup_regular_list(net_stream);
187 unsigned int streams_options = 0;
189 char * hashed_details =
NULL;
190 int hashed_details_len = 0;
197 DBG_ENTER(
"mysqlnd_vio::open_tcp_or_unix");
199 vio->data->stream =
NULL;
202 hashed_details_len =
mnd_sprintf(&hashed_details, 0,
"%p", vio);
203 DBG_INF_FMT(
"hashed_details=%s", hashed_details);
206 if (vio->data->options.timeout_connect) {
207 tv.tv_sec = vio->data->options.timeout_connect;
211 DBG_INF_FMT(
"calling php_stream_xport_create");
213 hashed_details, (vio->data->options.timeout_connect) ? &
tv :
NULL,
214 NULL , &errstr, &errcode);
215 if (errstr || !net_stream) {
217 if (hashed_details) {
224 errstr?
ZSTR_VAL(errstr):
"Unknown error while connecting");
230 if (hashed_details) {
238 if ((le = zend_hash_str_find_ptr(&
EG(persistent_list), hashed_details, hashed_details_len))) {
240 origin_dtor =
EG(persistent_list).pDestructor;
246 EG(persistent_list).pDestructor =
NULL;
248 EG(persistent_list).pDestructor = origin_dtor;
258 mysqlnd_fixup_regular_list(net_stream);
269 php_stream * net_stream = vio->data->m.get_stream(vio);
270 DBG_ENTER(
"mysqlnd_vio::post_connect_set_opt");
272 if (vio->data->options.timeout_read) {
274 DBG_INF_FMT(
"setting %u as PHP_STREAM_OPTION_READ_TIMEOUT", vio->data->options.timeout_read);
275 tv.tv_sec = vio->data->options.timeout_read;
280 if (!memcmp(scheme.s,
"tcp://",
sizeof(
"tcp://") - 1)) {
282 mysqlnd_set_sock_no_delay(net_stream);
284 mysqlnd_set_sock_keepalive(net_stream);
287 net_stream->
chunk_size = vio->data->options.net_read_buffer_size;
302 DBG_ENTER(
"mysqlnd_vio::get_open_stream");
303 if (scheme.l > (
sizeof(
"pipe://") - 1) && !memcmp(scheme.s,
"pipe://",
sizeof(
"pipe://") - 1)) {
304 ret = vio->data->m.open_pipe;
305 }
else if ((scheme.l > (
sizeof(
"tcp://") - 1) && !memcmp(scheme.s,
"tcp://",
sizeof(
"tcp://") - 1))
307 (scheme.l > (
sizeof(
"unix://") - 1) && !memcmp(scheme.s,
"unix://",
sizeof(
"unix://") - 1)))
309 ret = vio->data->m.open_tcp_or_unix;
328 DBG_ENTER(
"mysqlnd_vio::connect");
330 vio->data->m.close_stream(vio, conn_stats, error_info);
332 open_stream = vio->data->m.get_open_stream(vio, scheme, error_info);
335 if (net_stream &&
PASS == vio->data->m.set_stream(vio, net_stream)) {
336 vio->data->m.post_connect_set_opt(vio, scheme, conn_stats, error_info);
350 DBG_ENTER(
"mysqlnd_vio::set_client_option");
351 DBG_INF_FMT(
"option=%u", option);
354 DBG_INF(
"MYSQLND_OPT_NET_READ_BUFFER_SIZE");
355 net->data->options.net_read_buffer_size = *(
unsigned int*)
value;
356 DBG_INF_FMT(
"new_length=%zu", net->data->options.net_read_buffer_size);
359 DBG_INF(
"MYSQL_OPT_CONNECT_TIMEOUT");
360 net->data->options.timeout_connect = *(
unsigned int*)
value;
364 bool pers = net->persistent;
365 if (net->data->options.ssl_key) {
373 bool pers = net->persistent;
374 if (net->data->options.ssl_cert) {
375 mnd_pefree(net->data->options.ssl_cert, pers);
382 bool pers = net->persistent;
383 if (net->data->options.ssl_ca) {
391 bool pers = net->persistent;
392 if (net->data->options.ssl_capath) {
393 mnd_pefree(net->data->options.ssl_capath, pers);
400 bool pers = net->persistent;
401 if (net->data->options.ssl_cipher) {
402 mnd_pefree(net->data->options.ssl_cipher, pers);
409 bool pers = net->persistent;
410 if (net->data->options.ssl_passphrase) {
411 mnd_pefree(net->data->options.ssl_passphrase, pers);
418 enum mysqlnd_ssl_peer
val = *((
enum mysqlnd_ssl_peer *)
value);
420 case MYSQLND_SSL_PEER_VERIFY:
421 DBG_INF(
"MYSQLND_SSL_PEER_VERIFY");
423 case MYSQLND_SSL_PEER_DONT_VERIFY:
424 DBG_INF(
"MYSQLND_SSL_PEER_DONT_VERIFY");
426 case MYSQLND_SSL_PEER_DEFAULT:
427 DBG_INF(
"MYSQLND_SSL_PEER_DEFAULT");
428 val = MYSQLND_SSL_PEER_DEFAULT;
431 DBG_INF(
"default = MYSQLND_SSL_PEER_DEFAULT_ACTION");
432 val = MYSQLND_SSL_PEER_DEFAULT;
435 net->data->options.ssl_verify_peer =
val;
439 net->data->options.timeout_read = *(
unsigned int*)
value;
441#ifdef WHEN_SUPPORTED_BY_MYSQLI
443 net->data->options.timeout_write = *(
unsigned int*)
value;
458#ifdef MYSQLND_DO_WIRE_CHECK_BEFORE_COMMAND
467 size_t skipped_bytes = 0;
472 DBG_ENTER(
"mysqlnd_vio::consume_uneaten_data");
476 ssize_t bytes_consumed;
479 bytes_consumed =
php_stream_read(net_stream, tmp_buf,
sizeof(tmp_buf));
480 if (bytes_consumed <= 0) {
483 skipped_bytes += bytes_consumed;
484 }
while (bytes_consumed ==
sizeof(tmp_buf));
490 if (bytes_consumed) {
491 DBG_ERR_FMT(
"Skipped %u bytes. Last command hasn't consumed all the output from the server",
494 "consumed all the output from the server",
498 net->last_command = cmd;
514#ifdef MYSQLND_SSL_SUPPORTED
517 bool any_flag =
FALSE;
519 DBG_ENTER(
"mysqlnd_vio::enable_ssl");
553 zval passphrase_zval;
567 zval verify_peer_zval;
576 DBG_INF_FMT(
"VERIFY=%d", verify);
593 DBG_ERR(
"Cannot connect to MySQL by using SSL");
616 DBG_ENTER(
"mysqlnd_vio::enable_ssl");
617 DBG_INF(
"MYSQLND_SSL_SUPPORTED is not defined");
628 DBG_ENTER(
"mysqlnd_vio::disable_ssl");
639 DBG_ENTER(
"mysqlnd_vio::free_contents");
672 DBG_ENTER(
"mysqlnd_vio::close_stream");
673 if (net && (net_stream = net->data->m.get_stream(net))) {
674 bool pers = net->persistent;
675 DBG_INF_FMT(
"Freeing stream. abstract=%p", net_stream->
abstract);
684 net->data->m.set_stream(net,
NULL);
696 unsigned int buf_size;
697 DBG_ENTER(
"mysqlnd_vio::init");
714 DBG_ENTER(
"mysqlnd_vio::dtor");
716 vio->data->m.free_contents(vio);
717 vio->data->m.close_stream(vio, stats, error_info);
730 DBG_ENTER(
"mysqlnd_vio::get_stream");
731 DBG_INF_FMT(
"%p", net? net->data->stream:
NULL);
741 DBG_ENTER(
"mysqlnd_vio::set_stream");
743 vio->data->stream = net_stream;
755 DBG_ENTER(
"mysqlnd_vio::has_valid_stream");
756 DBG_INF_FMT(
"%p %p", vio, vio? vio->data->stream:
NULL);
798 DBG_ENTER(
"mysqlnd_vio_init");
809 DBG_ENTER(
"mysqlnd_vio_free");
811 vio->
data->m.dtor(vio, stats, error_info);
count(Countable|array $value, int $mode=COUNT_NORMAL)
const php_stream_filter_factory * factory
PHPAPI ZEND_COLD void php_error_docref(const char *docref, int type, const char *format,...)
zend_long net_read_timeout
zend_long net_read_buffer_size
#define MYSQLND_INC_CONN_STATISTIC_W_VALUE(conn_stats, statistic, value)
#define MYSQLND_METHOD(class, method)
#define mnd_pestrdup(ptr, pers)
#define mnd_sprintf_free(p)
#define mnd_sprintf(p, mx_len, fmt,...)
#define mnd_pefree(ptr, pers)
#define DBG_RETURN(value)
@ MYSQL_OPT_CONNECT_TIMEOUT
@ MYSQLND_OPT_SSL_PASSPHRASE
@ MYSQL_OPT_WRITE_TIMEOUT
@ MYSQL_OPT_SSL_VERIFY_SERVER_CERT
@ MYSQLND_OPT_NET_READ_BUFFER_SIZE
enum mysqlnd_client_option enum_mysqlnd_client_option
#define CR_CONNECTION_ERROR
php_mysqlnd_server_command
enum func_status enum_func_status
#define MYSQLND_SSL_PEER_DEFAULT_ACTION
#define MYSQLND_CLASS_METHODS_END
struct st_mysqlnd_vio MYSQLND_VIO
struct st_mysqlnd_const_string MYSQLND_CSTRING
#define MYSQLND_CLASS_METHODS_TYPE(class)
struct st_mysqlnd_stats MYSQLND_STATS
php_stream *(* func_mysqlnd_vio__open_stream)(MYSQLND_VIO *const vio, const MYSQLND_CSTRING scheme, const bool persistent, MYSQLND_STATS *const conn_stats, MYSQLND_ERROR_INFO *const error_info)
#define SET_CLIENT_ERROR(info, err_no, sqlstate, error)
#define MYSQLND_CLASS_METHODS_START(class)
struct st_mysqlnd_error_info MYSQLND_ERROR_INFO
#define MYSQLND_CLASS_METHOD_TABLE_NAME(class)
PHPAPI void mysqlnd_vio_free(MYSQLND_VIO *const vio, MYSQLND_STATS *stats, MYSQLND_ERROR_INFO *error_info)
PHPAPI MYSQLND_VIO * mysqlnd_vio_init(bool persistent, MYSQLND_CLASS_METHODS_TYPE(mysqlnd_object_factory) *object_factory, MYSQLND_STATS *stats, MYSQLND_ERROR_INFO *error_info)
const char *const mysqlnd_command_to_text[COM_END]
struct _php_netstream_data_t php_netstream_data_t
PHPAPI php_stream_context * php_stream_context_set(php_stream *stream, php_stream_context *context)
PHPAPI php_stream_context * php_stream_context_alloc(void)
PHPAPI void php_stream_context_set_option(php_stream_context *context, const char *wrappername, const char *optionname, zval *optionvalue)
#define php_stream_xport_create(name, namelen, options, flags, persistent_id, timeout, context, estr, ecode)
PHPAPI int php_stream_xport_crypto_enable(php_stream *stream, int activate)
@ STREAM_CRYPTO_METHOD_TLS_CLIENT
#define STREAM_XPORT_CONNECT
PHPAPI int php_stream_xport_crypto_setup(php_stream *stream, php_stream_xport_crypt_method_t crypto_method, php_stream *session_stream)
#define STREAM_XPORT_CLIENT
struct _php_stream php_stream
struct _php_stream_context php_stream_context
#define php_stream_read(stream, buf, count)
#define PHP_STREAM_OPTION_BLOCKING
#define PHP_STREAM_FREE_CLOSE_PERSISTENT
#define php_stream_auto_cleanup(stream)
#define php_stream_free(stream, close_options)
#define PHP_STREAM_FLAG_SUPPRESS_ERRORS
#define PHP_STREAM_FREE_CLOSE
#define STREAM_OPEN_PERSISTENT
#define PHP_STREAM_OPTION_READ_TIMEOUT
#define php_stream_open_wrapper(path, mode, options, opened)
#define PHP_STREAM_OPTION_RETURN_ERR
#define PHP_STREAM_FREE_RSRC_DTOR
#define php_stream_set_option(stream, option, value, ptrvalue)
#define php_stream_write(stream, buf, count)
int(* set_option)(php_stream *stream, int option, int value, void *ptrparam)
const php_stream_ops * ops
MYSQLND_VIO_OPTIONS options
enum st_mysqlnd_vio_options::mysqlnd_ssl_peer ssl_verify_peer
unsigned int timeout_read
struct st_mysqlnd_vio_data * data
#define ZVAL_STRING(z, s)
#define pefree(ptr, persistent)
zend_string_release_ex(func->internal_function.function_name, 0)
ZEND_API void ZEND_FASTCALL zend_hash_del_bucket(HashTable *ht, Bucket *p)
ZEND_API zend_result ZEND_FASTCALL zend_hash_index_del(HashTable *ht, zend_ulong h)
ZEND_API zend_result ZEND_FASTCALL zend_hash_str_del(HashTable *ht, const char *str, size_t len)
#define ZEND_HASH_MAP_REVERSE_FOREACH_BUCKET(ht, _bucket)
#define ZEND_HASH_FOREACH_END()
struct _zend_string zend_string
struct _zend_resource zend_resource
void(* dtor_func_t)(zval *pDest)
ZEND_API void zval_ptr_dtor(zval *zval_ptr)