xref: /PHP-7.4/ext/mysqlnd/php_mysqlnd.c (revision 6ab04a6e)
1 /*
2   +----------------------------------------------------------------------+
3   | PHP Version 7                                                        |
4   +----------------------------------------------------------------------+
5   | Copyright (c) The PHP Group                                          |
6   +----------------------------------------------------------------------+
7   | This source file is subject to version 3.01 of the PHP license,      |
8   | that is bundled with this package in the file LICENSE, and is        |
9   | available through the world-wide-web at the following url:           |
10   | http://www.php.net/license/3_01.txt                                  |
11   | If you did not receive a copy of the PHP license and are unable to   |
12   | obtain it through the world-wide-web, please send a note to          |
13   | license@php.net so we can mail you a copy immediately.               |
14   +----------------------------------------------------------------------+
15   | Authors: Andrey Hristov <andrey@php.net>                             |
16   |          Ulf Wendel <uw@php.net>                                     |
17   +----------------------------------------------------------------------+
18 */
19 
20 #include "php.h"
21 #include "mysqlnd.h"
22 #include "mysqlnd_priv.h"
23 #include "mysqlnd_debug.h"
24 #include "mysqlnd_statistics.h"
25 #include "mysqlnd_reverse_api.h"
26 #include "ext/standard/info.h"
27 #include "zend_smart_str.h"
28 
29 /* {{{ mysqlnd_functions[]
30  *
31  * Every user visible function must have an entry in mysqlnd_functions[].
32  */
33 static zend_function_entry mysqlnd_functions[] = {
34 	PHP_FE_END
35 };
36 /* }}} */
37 
38 
39 /* {{{ mysqlnd_minfo_print_hash */
40 PHPAPI void
mysqlnd_minfo_print_hash(zval * values)41 mysqlnd_minfo_print_hash(zval *values)
42 {
43 	zval *values_entry;
44 	zend_string	*string_key;
45 
46 	ZEND_HASH_FOREACH_STR_KEY_VAL(Z_ARRVAL_P(values), string_key, values_entry) {
47 		convert_to_string(values_entry);
48 		php_info_print_table_row(2, ZSTR_VAL(string_key), Z_STRVAL_P(values_entry));
49 	} ZEND_HASH_FOREACH_END();
50 }
51 /* }}} */
52 
53 
54 /* {{{ mysqlnd_minfo_dump_loaded_plugins */
55 static int
mysqlnd_minfo_dump_loaded_plugins(zval * el,void * buf)56 mysqlnd_minfo_dump_loaded_plugins(zval *el, void * buf)
57 {
58 	smart_str * buffer = (smart_str *) buf;
59 	struct st_mysqlnd_plugin_header * plugin_header = (struct st_mysqlnd_plugin_header *)Z_PTR_P(el);
60 	if (plugin_header->plugin_name) {
61 		if (buffer->s) {
62 			smart_str_appendc(buffer, ',');
63 		}
64 		smart_str_appends(buffer, plugin_header->plugin_name);
65 	}
66 	return ZEND_HASH_APPLY_KEEP;
67 }
68 /* }}} */
69 
70 
71 /* {{{ mysqlnd_minfo_dump_api_plugins */
72 static void
mysqlnd_minfo_dump_api_plugins(smart_str * buffer)73 mysqlnd_minfo_dump_api_plugins(smart_str * buffer)
74 {
75 	HashTable *ht = mysqlnd_reverse_api_get_api_list();
76 	MYSQLND_REVERSE_API *ext;
77 
78 	ZEND_HASH_FOREACH_PTR(ht, ext) {
79 		if (buffer->s) {
80 			smart_str_appendc(buffer, ',');
81 		}
82 		smart_str_appends(buffer, ext->module->name);
83 	} ZEND_HASH_FOREACH_END();
84 }
85 /* }}} */
86 
87 
88 /* {{{ PHP_MINFO_FUNCTION
89  */
PHP_MINFO_FUNCTION(mysqlnd)90 PHP_MINFO_FUNCTION(mysqlnd)
91 {
92 	char buf[32];
93 
94 	php_info_print_table_start();
95 	php_info_print_table_header(2, "mysqlnd", "enabled");
96 	php_info_print_table_row(2, "Version", mysqlnd_get_client_info());
97 	php_info_print_table_row(2, "Compression",
98 #ifdef MYSQLND_COMPRESSION_ENABLED
99 								"supported");
100 #else
101 								"not supported");
102 #endif
103 	php_info_print_table_row(2, "core SSL",
104 #ifdef MYSQLND_SSL_SUPPORTED
105 								"supported");
106 #else
107 								"not supported");
108 #endif
109 	php_info_print_table_row(2, "extended SSL",
110 #ifdef MYSQLND_HAVE_SSL
111 								"supported");
112 #else
113 								"not supported");
114 #endif
115 	snprintf(buf, sizeof(buf), ZEND_LONG_FMT, MYSQLND_G(net_cmd_buffer_size));
116 	php_info_print_table_row(2, "Command buffer size", buf);
117 	snprintf(buf, sizeof(buf), ZEND_LONG_FMT, MYSQLND_G(net_read_buffer_size));
118 	php_info_print_table_row(2, "Read buffer size", buf);
119 	snprintf(buf, sizeof(buf), ZEND_LONG_FMT, MYSQLND_G(net_read_timeout));
120 	php_info_print_table_row(2, "Read timeout", buf);
121 	php_info_print_table_row(2, "Collecting statistics", MYSQLND_G(collect_statistics)? "Yes":"No");
122 	php_info_print_table_row(2, "Collecting memory statistics", MYSQLND_G(collect_memory_statistics)? "Yes":"No");
123 
124 	php_info_print_table_row(2, "Tracing", MYSQLND_G(debug)? MYSQLND_G(debug):"n/a");
125 
126 	/* loaded plugins */
127 	{
128 		smart_str tmp_str = {0};
129 		mysqlnd_plugin_apply_with_argument(mysqlnd_minfo_dump_loaded_plugins, &tmp_str);
130 		smart_str_0(&tmp_str);
131 		php_info_print_table_row(2, "Loaded plugins", tmp_str.s? ZSTR_VAL(tmp_str.s) : "");
132 		smart_str_free(&tmp_str);
133 
134 		mysqlnd_minfo_dump_api_plugins(&tmp_str);
135 		smart_str_0(&tmp_str);
136 		php_info_print_table_row(2, "API Extensions", tmp_str.s? ZSTR_VAL(tmp_str.s) : "");
137 		smart_str_free(&tmp_str);
138 	}
139 
140 	php_info_print_table_end();
141 }
142 /* }}} */
143 
144 
ZEND_DECLARE_MODULE_GLOBALS(mysqlnd)145 PHPAPI ZEND_DECLARE_MODULE_GLOBALS(mysqlnd)
146 
147 
148 /* {{{ PHP_GINIT_FUNCTION
149  */
150 static PHP_GINIT_FUNCTION(mysqlnd)
151 {
152 #if defined(COMPILE_DL_MYSQLND) && defined(ZTS)
153 	ZEND_TSRMLS_CACHE_UPDATE();
154 #endif
155 	mysqlnd_globals->collect_statistics = TRUE;
156 	mysqlnd_globals->collect_memory_statistics = FALSE;
157 	mysqlnd_globals->debug = NULL;	/* The actual string */
158 	mysqlnd_globals->dbg = NULL;	/* The DBG object*/
159 	mysqlnd_globals->trace_alloc_settings = NULL;
160 	mysqlnd_globals->trace_alloc = NULL;
161 	mysqlnd_globals->net_cmd_buffer_size = MYSQLND_NET_CMD_BUFFER_MIN_SIZE;
162 	mysqlnd_globals->net_read_buffer_size = 32768;
163 	mysqlnd_globals->net_read_timeout = 31536000;
164 	mysqlnd_globals->log_mask = 0;
165 	mysqlnd_globals->mempool_default_size = 16000;
166 	mysqlnd_globals->debug_emalloc_fail_threshold = -1;
167 	mysqlnd_globals->debug_ecalloc_fail_threshold = -1;
168 	mysqlnd_globals->debug_erealloc_fail_threshold = -1;
169 	mysqlnd_globals->debug_malloc_fail_threshold = -1;
170 	mysqlnd_globals->debug_calloc_fail_threshold = -1;
171 	mysqlnd_globals->debug_realloc_fail_threshold = -1;
172 	mysqlnd_globals->sha256_server_public_key = NULL;
173 	mysqlnd_globals->fetch_data_copy = FALSE;
174 }
175 /* }}} */
176 
177 
178 /* {{{ PHP_INI_MH
179  */
PHP_INI_MH(OnUpdateNetCmdBufferSize)180 static PHP_INI_MH(OnUpdateNetCmdBufferSize)
181 {
182 	zend_long long_value;
183 
184 	ZEND_ATOL(long_value, ZSTR_VAL(new_value));
185 	if (long_value < MYSQLND_NET_CMD_BUFFER_MIN_SIZE) {
186 		return FAILURE;
187 	}
188 	MYSQLND_G(net_cmd_buffer_size) = long_value;
189 
190 	return SUCCESS;
191 }
192 /* }}} */
193 
194 
195 /* {{{ PHP_INI_BEGIN
196 */
197 PHP_INI_BEGIN()
198 	STD_PHP_INI_BOOLEAN("mysqlnd.collect_statistics",	"1", 	PHP_INI_ALL,	OnUpdateBool,	collect_statistics, zend_mysqlnd_globals, mysqlnd_globals)
199 	STD_PHP_INI_BOOLEAN("mysqlnd.collect_memory_statistics","0",PHP_INI_SYSTEM, OnUpdateBool,	collect_memory_statistics, zend_mysqlnd_globals, mysqlnd_globals)
200 	STD_PHP_INI_ENTRY("mysqlnd.debug",					NULL, 	PHP_INI_SYSTEM, OnUpdateString,	debug, zend_mysqlnd_globals, mysqlnd_globals)
201 	STD_PHP_INI_ENTRY("mysqlnd.trace_alloc",			NULL, 	PHP_INI_SYSTEM, OnUpdateString,	trace_alloc_settings, zend_mysqlnd_globals, mysqlnd_globals)
202 	STD_PHP_INI_ENTRY("mysqlnd.net_cmd_buffer_size",	MYSQLND_NET_CMD_BUFFER_MIN_SIZE_STR,	PHP_INI_ALL,	OnUpdateNetCmdBufferSize,	net_cmd_buffer_size,	zend_mysqlnd_globals,		mysqlnd_globals)
203 	STD_PHP_INI_ENTRY("mysqlnd.net_read_buffer_size",	"32768",PHP_INI_ALL,	OnUpdateLong,	net_read_buffer_size,	zend_mysqlnd_globals,		mysqlnd_globals)
204 	STD_PHP_INI_ENTRY("mysqlnd.net_read_timeout",		"86400",PHP_INI_ALL,	OnUpdateLong,	net_read_timeout, zend_mysqlnd_globals, mysqlnd_globals)
205 	STD_PHP_INI_ENTRY("mysqlnd.log_mask",				"0", 	PHP_INI_ALL,	OnUpdateLong,	log_mask, zend_mysqlnd_globals, mysqlnd_globals)
206 	STD_PHP_INI_ENTRY("mysqlnd.mempool_default_size","16000",   PHP_INI_ALL,	OnUpdateLong,	mempool_default_size,	zend_mysqlnd_globals,		mysqlnd_globals)
207 	STD_PHP_INI_ENTRY("mysqlnd.sha256_server_public_key",NULL, 	PHP_INI_PERDIR, OnUpdateString,	sha256_server_public_key, zend_mysqlnd_globals, mysqlnd_globals)
208 	STD_PHP_INI_BOOLEAN("mysqlnd.fetch_data_copy",	"0", 		PHP_INI_ALL,	OnUpdateBool,	fetch_data_copy, zend_mysqlnd_globals, mysqlnd_globals)
209 #if PHP_DEBUG
210 	STD_PHP_INI_ENTRY("mysqlnd.debug_emalloc_fail_threshold","-1",   PHP_INI_SYSTEM,	OnUpdateLong,	debug_emalloc_fail_threshold,	zend_mysqlnd_globals,		mysqlnd_globals)
211 	STD_PHP_INI_ENTRY("mysqlnd.debug_ecalloc_fail_threshold","-1",   PHP_INI_SYSTEM,	OnUpdateLong,	debug_ecalloc_fail_threshold,	zend_mysqlnd_globals,		mysqlnd_globals)
212 	STD_PHP_INI_ENTRY("mysqlnd.debug_erealloc_fail_threshold","-1",   PHP_INI_SYSTEM,	OnUpdateLong,	debug_erealloc_fail_threshold,	zend_mysqlnd_globals,		mysqlnd_globals)
213 
214 	STD_PHP_INI_ENTRY("mysqlnd.debug_malloc_fail_threshold","-1",   PHP_INI_SYSTEM,	OnUpdateLong,	debug_malloc_fail_threshold,	zend_mysqlnd_globals,		mysqlnd_globals)
215 	STD_PHP_INI_ENTRY("mysqlnd.debug_calloc_fail_threshold","-1",   PHP_INI_SYSTEM,	OnUpdateLong,	debug_calloc_fail_threshold,	zend_mysqlnd_globals,		mysqlnd_globals)
216 	STD_PHP_INI_ENTRY("mysqlnd.debug_realloc_fail_threshold","-1",   PHP_INI_SYSTEM,	OnUpdateLong,	debug_realloc_fail_threshold,	zend_mysqlnd_globals,		mysqlnd_globals)
217 #endif
PHP_INI_END()218 PHP_INI_END()
219 /* }}} */
220 
221 
222 /* {{{ PHP_MINIT_FUNCTION
223  */
224 static PHP_MINIT_FUNCTION(mysqlnd)
225 {
226 	REGISTER_INI_ENTRIES();
227 
228 	mysqlnd_library_init();
229 	return SUCCESS;
230 }
231 /* }}} */
232 
233 
234 /* {{{ PHP_MSHUTDOWN_FUNCTION
235  */
PHP_MSHUTDOWN_FUNCTION(mysqlnd)236 static PHP_MSHUTDOWN_FUNCTION(mysqlnd)
237 {
238 	mysqlnd_library_end();
239 
240 	UNREGISTER_INI_ENTRIES();
241 	return SUCCESS;
242 }
243 /* }}} */
244 
245 
246 #if PHP_DEBUG
247 /* {{{ PHP_RINIT_FUNCTION
248  */
PHP_RINIT_FUNCTION(mysqlnd)249 static PHP_RINIT_FUNCTION(mysqlnd)
250 {
251 	if (MYSQLND_G(debug)) {
252 		struct st_mysqlnd_plugin_trace_log * trace_log_plugin = mysqlnd_plugin_find("debug_trace");
253 		MYSQLND_G(dbg) = NULL;
254 		if (trace_log_plugin) {
255 			MYSQLND_DEBUG * dbg = trace_log_plugin->methods.trace_instance_init(mysqlnd_debug_std_no_trace_funcs);
256 			MYSQLND_DEBUG * trace_alloc = trace_log_plugin->methods.trace_instance_init(NULL);
257 			if (!dbg || !trace_alloc) {
258 				return FAILURE;
259 			}
260 			dbg->m->set_mode(dbg, MYSQLND_G(debug));
261 			trace_alloc->m->set_mode(trace_alloc, MYSQLND_G(trace_alloc_settings));
262 			MYSQLND_G(dbg) = dbg;
263 			MYSQLND_G(trace_alloc) = trace_alloc;
264 		}
265 	}
266 	return SUCCESS;
267 }
268 /* }}} */
269 #endif
270 
271 
272 #if PHP_DEBUG
273 /* {{{ PHP_RSHUTDOWN_FUNCTION
274  */
PHP_RSHUTDOWN_FUNCTION(mysqlnd)275 static PHP_RSHUTDOWN_FUNCTION(mysqlnd)
276 {
277 	MYSQLND_DEBUG * dbg = MYSQLND_G(dbg);
278 	MYSQLND_DEBUG * trace_alloc = MYSQLND_G(trace_alloc);
279 	DBG_ENTER("RSHUTDOWN");
280 	if (dbg) {
281 		dbg->m->close(dbg);
282 		dbg->m->free_handle(dbg);
283 		MYSQLND_G(dbg) = NULL;
284 	}
285 	if (trace_alloc) {
286 		trace_alloc->m->close(trace_alloc);
287 		trace_alloc->m->free_handle(trace_alloc);
288 		MYSQLND_G(trace_alloc) = NULL;
289 	}
290 	return SUCCESS;
291 }
292 /* }}} */
293 #endif
294 
295 
296 static const zend_module_dep mysqlnd_deps[] = {
297 	ZEND_MOD_REQUIRED("standard")
298 	ZEND_MOD_END
299 };
300 
301 /* {{{ mysqlnd_module_entry
302  */
303 zend_module_entry mysqlnd_module_entry = {
304 	STANDARD_MODULE_HEADER_EX,
305 	NULL,
306 	mysqlnd_deps,
307 	"mysqlnd",
308 	mysqlnd_functions,
309 	PHP_MINIT(mysqlnd),
310 	PHP_MSHUTDOWN(mysqlnd),
311 #if PHP_DEBUG
312 	PHP_RINIT(mysqlnd),
313 #else
314 	NULL,
315 #endif
316 #if PHP_DEBUG
317 	PHP_RSHUTDOWN(mysqlnd),
318 #else
319 	NULL,
320 #endif
321 	PHP_MINFO(mysqlnd),
322 	PHP_MYSQLND_VERSION,
323 	PHP_MODULE_GLOBALS(mysqlnd),
324 	PHP_GINIT(mysqlnd),
325 	NULL,
326 	NULL,
327 	STANDARD_MODULE_PROPERTIES_EX
328 };
329 /* }}} */
330 
331 /* {{{ COMPILE_DL_MYSQLND */
332 #ifdef COMPILE_DL_MYSQLND
333 #ifdef ZTS
334 ZEND_TSRMLS_CACHE_DEFINE()
335 #endif
336 ZEND_GET_MODULE(mysqlnd)
337 #endif
338 /* }}} */
339