php-internal-docs 8.4.8
Unofficial docs for php/php-src
Loading...
Searching...
No Matches
mysqlnd_protocol_frame_codec.c
Go to the documentation of this file.
1/*
2 +----------------------------------------------------------------------+
3 | Copyright (c) The PHP Group |
4 +----------------------------------------------------------------------+
5 | This source file is subject to version 3.01 of the PHP license, |
6 | that is bundled with this package in the file LICENSE, and is |
7 | available through the world-wide-web at the following url: |
8 | https://www.php.net/license/3_01.txt |
9 | If you did not receive a copy of the PHP license and are unable to |
10 | obtain it through the world-wide-web, please send a note to |
11 | license@php.net so we can mail you a copy immediately. |
12 +----------------------------------------------------------------------+
13 | Authors: Andrey Hristov <andrey@php.net> |
14 | Ulf Wendel <uw@php.net> |
15 +----------------------------------------------------------------------+
16*/
17
18#include "php.h"
19#include "mysqlnd.h"
20#include "mysqlnd_connection.h"
21#include "mysqlnd_priv.h"
22#include "mysqlnd_read_buffer.h"
24#include "mysqlnd_statistics.h"
25#include "mysqlnd_debug.h"
26#ifdef MYSQLND_COMPRESSION_ENABLED
27#include <zlib.h>
28#endif
29
30
31/* {{{ mysqlnd_pfc::reset */
32static void
33MYSQLND_METHOD(mysqlnd_pfc, reset)(MYSQLND_PFC * const pfc, MYSQLND_STATS * const conn_stats, MYSQLND_ERROR_INFO * const error_info)
34{
35 DBG_ENTER("mysqlnd_pfc::reset");
36 pfc->data->packet_no = pfc->data->compressed_envelope_packet_no = 0;
38}
39/* }}} */
40
41
42/* We assume that MYSQLND_HEADER_SIZE is 4 bytes !! */
43#define COPY_HEADER(T,A) do { \
44 *(((char *)(T))) = *(((char *)(A)));\
45 *(((char *)(T))+1) = *(((char *)(A))+1);\
46 *(((char *)(T))+2) = *(((char *)(A))+2);\
47 *(((char *)(T))+3) = *(((char *)(A))+3); } while (0)
48#define STORE_HEADER_SIZE(safe_storage, buffer) COPY_HEADER((safe_storage), (buffer))
49#define RESTORE_HEADER_SIZE(buffer, safe_storage) STORE_HEADER_SIZE((safe_storage), (buffer))
50
51#ifdef MYSQLND_COMPRESSION_ENABLED
52static ssize_t write_compressed_packet(
53 const MYSQLND_PFC *pfc, MYSQLND_VIO *vio,
54 MYSQLND_STATS *conn_stats, MYSQLND_ERROR_INFO *error_info,
55 zend_uchar *uncompressed_payload, size_t to_be_sent, zend_uchar *compress_buf) {
56 DBG_ENTER("write_compressed_packet");
57 /* here we need to compress the data and then write it, first comes the compressed header */
58 size_t tmp_complen = to_be_sent;
59 size_t payload_size;
60 if (PASS == pfc->data->m.encode((compress_buf + COMPRESSED_HEADER_SIZE + MYSQLND_HEADER_SIZE), &tmp_complen,
61 uncompressed_payload, to_be_sent))
62 {
63 int3store(compress_buf + MYSQLND_HEADER_SIZE, to_be_sent);
64 payload_size = tmp_complen;
65 } else {
66 int3store(compress_buf + MYSQLND_HEADER_SIZE, 0);
67 memcpy(compress_buf + MYSQLND_HEADER_SIZE + COMPRESSED_HEADER_SIZE, uncompressed_payload, to_be_sent);
68 payload_size = to_be_sent;
69 }
70
71 int3store(compress_buf, payload_size);
72 int1store(compress_buf + 3, pfc->data->compressed_envelope_packet_no);
73 DBG_INF_FMT("writing %zu bytes to the network", payload_size + MYSQLND_HEADER_SIZE + COMPRESSED_HEADER_SIZE);
74
75 ssize_t bytes_sent = vio->data->m.network_write(vio, compress_buf, payload_size + MYSQLND_HEADER_SIZE + COMPRESSED_HEADER_SIZE, conn_stats, error_info);
77#ifdef WHEN_WE_NEED_TO_CHECK_WHETHER_COMPRESSION_WORKS_CORRECTLY
78 if (res == Z_OK) {
79 size_t decompressed_size = left + MYSQLND_HEADER_SIZE;
80 zend_uchar * decompressed_data = mnd_emalloc(decompressed_size);
81 int error = pfc->data->m.decode(decompressed_data, decompressed_size,
82 compress_buf + MYSQLND_HEADER_SIZE + COMPRESSED_HEADER_SIZE, payload_size);
83 if (error == Z_OK) {
84 int i;
85 DBG_INF("success decompressing");
86 for (i = 0 ; i < decompressed_size; i++) {
87 if (i && (i % 30 == 0)) {
88 printf("\n\t\t");
89 }
90 printf("%.2X ", (int)*((char*)&(decompressed_data[i])));
91 DBG_INF_FMT("%.2X ", (int)*((char*)&(decompressed_data[i])));
92 }
93 } else {
94 DBG_INF("error decompressing");
95 }
96 mnd_efree(decompressed_data);
97 }
98#endif /* WHEN_WE_NEED_TO_CHECK_WHETHER_COMPRESSION_WORKS_CORRECTLY */
99 DBG_RETURN(bytes_sent);
100}
101#endif
102
103/* {{{ mysqlnd_pfc::send */
104/*
105 IMPORTANT : It's expected that buffer has place in the beginning for MYSQLND_HEADER_SIZE !!!!
106 This is done for performance reasons in the caller of this function.
107 Otherwise we will have to do send two TCP packets, or do new alloc and memcpy.
108 Neither are quick, thus the clients of this function are obligated to do
109 what they are asked for.
110
111 `count` is actually the length of the payload data. Thus :
112 count + MYSQLND_HEADER_SIZE = sizeof(buffer) (not the pointer but the actual buffer)
113*/
114static size_t
115MYSQLND_METHOD(mysqlnd_pfc, send)(MYSQLND_PFC * const pfc, MYSQLND_VIO * const vio, zend_uchar * const buffer, const size_t count,
116 MYSQLND_STATS * const conn_stats, MYSQLND_ERROR_INFO * const error_info)
117{
118 zend_uchar safe_buf[((MYSQLND_HEADER_SIZE) + (sizeof(zend_uchar)) - 1) / (sizeof(zend_uchar))];
119 zend_uchar * safe_storage = safe_buf;
120 size_t packets_sent = 1;
121 size_t left = count;
123 zend_uchar * compress_buf = NULL;
124 size_t to_be_sent;
125 ssize_t bytes_sent;
126
127 DBG_ENTER("mysqlnd_pfc::send");
128 DBG_INF_FMT("count=%zu compression=%u", count, pfc->data->compressed);
129
130 if (pfc->data->compressed == TRUE) {
132 DBG_INF_FMT("compress_buf_size=%zu", comp_buf_size);
133 compress_buf = mnd_emalloc(comp_buf_size);
134 }
135
136 do {
137 to_be_sent = MIN(left, MYSQLND_MAX_PACKET_SIZE);
138 DBG_INF_FMT("to_be_sent=%zu", to_be_sent);
139 DBG_INF_FMT("packets_sent=%zu", packets_sent);
140 DBG_INF_FMT("compressed_envelope_packet_no=%u", pfc->data->compressed_envelope_packet_no);
141 DBG_INF_FMT("packet_no=%u", pfc->data->packet_no);
142#ifdef MYSQLND_COMPRESSION_ENABLED
143 if (pfc->data->compressed == TRUE) {
144 zend_uchar * uncompressed_payload = p; /* should include the header */
145 STORE_HEADER_SIZE(safe_storage, uncompressed_payload);
146 int3store(uncompressed_payload, to_be_sent);
147 int1store(uncompressed_payload + 3, pfc->data->packet_no);
148 if (to_be_sent <= MYSQLND_MAX_PACKET_SIZE - MYSQLND_HEADER_SIZE) {
149 bytes_sent = write_compressed_packet(
150 pfc, vio, conn_stats, error_info,
151 uncompressed_payload, to_be_sent + MYSQLND_HEADER_SIZE, compress_buf);
152 } else {
153 /* The uncompressed size including the header would overflow. Split into two
154 * compressed packets. The size of the first one is relatively arbitrary here. */
155 const size_t split_off_bytes = 8192;
156 bytes_sent = write_compressed_packet(
157 pfc, vio, conn_stats, error_info,
158 uncompressed_payload, split_off_bytes, compress_buf);
159 bytes_sent = write_compressed_packet(
160 pfc, vio, conn_stats, error_info,
161 uncompressed_payload + split_off_bytes,
162 to_be_sent + MYSQLND_HEADER_SIZE - split_off_bytes, compress_buf);
163 }
164 RESTORE_HEADER_SIZE(uncompressed_payload, safe_storage);
165 } else
166#endif /* MYSQLND_COMPRESSION_ENABLED */
167 {
168 DBG_INF("no compression");
169 STORE_HEADER_SIZE(safe_storage, p);
170 int3store(p, to_be_sent);
171 int1store(p + 3, pfc->data->packet_no);
172 bytes_sent = vio->data->m.network_write(vio, p, to_be_sent + MYSQLND_HEADER_SIZE, conn_stats, error_info);
173 RESTORE_HEADER_SIZE(p, safe_storage);
174 pfc->data->compressed_envelope_packet_no++;
175 }
176 pfc->data->packet_no++;
177
178 p += to_be_sent;
179 left -= to_be_sent;
180 packets_sent++;
181 /*
182 if left is 0 then there is nothing more to send, but if the last packet was exactly
183 with the size MYSQLND_MAX_PACKET_SIZE we need to send additional packet, which has
184 empty payload. Thus if left == 0 we check for to_be_sent being the max size. If it is
185 indeed it then loop once more, then to_be_sent will become 0, left will stay 0. Empty
186 packet will be sent and this loop will end.
187 */
188 } while (bytes_sent > 0 && (left > 0 || to_be_sent == MYSQLND_MAX_PACKET_SIZE));
189
190 DBG_INF_FMT("packet_size=%zu packet_no=%u", left, pfc->data->packet_no);
191
193 STAT_BYTES_SENT, count + packets_sent * MYSQLND_HEADER_SIZE,
195 STAT_PACKETS_SENT, packets_sent);
196
197 if (compress_buf) {
198 mnd_efree(compress_buf);
199 }
200
201 /* Even for zero size payload we have to send a packet */
202 if (bytes_sent <= 0) {
203 DBG_ERR_FMT("Can't %zu send bytes", count);
205 bytes_sent = 0; // the return type is unsigned and 0 represents an error condition
206 }
207 DBG_RETURN(bytes_sent);
208}
209/* }}} */
210
211
212#ifdef MYSQLND_COMPRESSION_ENABLED
213
214/* {{{ mysqlnd_pfc::read_compressed_packet_from_stream_and_fill_read_buffer */
215static enum_func_status
216MYSQLND_METHOD(mysqlnd_pfc, read_compressed_packet_from_stream_and_fill_read_buffer)
217 (MYSQLND_PFC * pfc, MYSQLND_VIO * vio, size_t net_payload_size, MYSQLND_STATS * conn_stats, MYSQLND_ERROR_INFO * error_info)
218{
219 size_t decompressed_size;
221 zend_uchar * compressed_data = NULL;
223 DBG_ENTER("mysqlnd_pfc::read_compressed_packet_from_stream_and_fill_read_buffer");
224
225 /* Read the compressed header */
226 if (FAIL == vio->data->m.network_read(vio, comp_header, COMPRESSED_HEADER_SIZE, conn_stats, error_info)) {
228 }
229 decompressed_size = uint3korr(comp_header);
230
231 /* When decompressed_size is 0, then the data is not compressed, and we have wasted 3 bytes */
232 /* we need to decompress the data */
233
234 if (decompressed_size) {
235 compressed_data = mnd_emalloc(net_payload_size);
236 if (FAIL == vio->data->m.network_read(vio, compressed_data, net_payload_size, conn_stats, error_info)) {
237 retval = FAIL;
238 goto end;
239 }
240 pfc->data->uncompressed_data = mysqlnd_create_read_buffer(decompressed_size);
241 retval = pfc->data->m.decode(pfc->data->uncompressed_data->data, decompressed_size, compressed_data, net_payload_size);
242 if (FAIL == retval) {
243 goto end;
244 }
245 } else {
246 DBG_INF_FMT("The server decided not to compress the data. Our job is easy. Copying %zu bytes", net_payload_size);
247 pfc->data->uncompressed_data = mysqlnd_create_read_buffer(net_payload_size);
248 if (FAIL == vio->data->m.network_read(vio, pfc->data->uncompressed_data->data, net_payload_size, conn_stats, error_info)) {
249 retval = FAIL;
250 goto end;
251 }
252 }
253end:
254 if (compressed_data) {
255 mnd_efree(compressed_data);
256 }
258}
259/* }}} */
260#endif /* MYSQLND_COMPRESSION_ENABLED */
261
262
263/* {{{ mysqlnd_pfc::decode */
264static enum_func_status
265MYSQLND_METHOD(mysqlnd_pfc, decode)(zend_uchar * uncompressed_data, const size_t uncompressed_data_len,
266 const zend_uchar * const compressed_data, const size_t compressed_data_len)
267{
268#ifdef MYSQLND_COMPRESSION_ENABLED
269 int error;
270 uLongf tmp_complen = uncompressed_data_len;
271 DBG_ENTER("mysqlnd_pfc::decode");
272 error = uncompress(uncompressed_data, &tmp_complen, compressed_data, compressed_data_len);
273
274 DBG_INF_FMT("compressed data: decomp_len=%lu compressed_size=%zu", tmp_complen, compressed_data_len);
275 if (error != Z_OK) {
276 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);
277 }
278 DBG_RETURN(error == Z_OK? PASS:FAIL);
279#else
280 DBG_ENTER("mysqlnd_pfc::decode");
282#endif
283}
284/* }}} */
285
286
287/* {{{ mysqlnd_pfc::encode */
288static enum_func_status
289MYSQLND_METHOD(mysqlnd_pfc, encode)(zend_uchar * compress_buffer, size_t * compress_buffer_len,
290 const zend_uchar * const uncompressed_data, const size_t uncompressed_data_len)
291{
292#ifdef MYSQLND_COMPRESSION_ENABLED
293 int error;
294 uLongf tmp_complen = *compress_buffer_len;
295 DBG_ENTER("mysqlnd_pfc::encode");
296 error = compress(compress_buffer, &tmp_complen, uncompressed_data, uncompressed_data_len);
297
298 if (error != Z_OK) {
299 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);
300 } else {
301 *compress_buffer_len = tmp_complen;
302 DBG_INF_FMT("compression successful. compressed size=%lu", tmp_complen);
303 }
304
305 DBG_RETURN(error == Z_OK? PASS:FAIL);
306#else
307 DBG_ENTER("mysqlnd_pfc::encode");
309#endif
310}
311/* }}} */
312
313
314/* {{{ mysqlnd_pfc::receive */
315static enum_func_status
316MYSQLND_METHOD(mysqlnd_pfc, receive)(MYSQLND_PFC * const pfc, MYSQLND_VIO * const vio, zend_uchar * const buffer, const size_t count,
317 MYSQLND_STATS * const conn_stats, MYSQLND_ERROR_INFO * const error_info)
318{
319 size_t to_read = count;
320 zend_uchar * p = buffer;
321
322 DBG_ENTER("mysqlnd_pfc::receive");
323#ifdef MYSQLND_COMPRESSION_ENABLED
324 if (pfc->data->compressed) {
325 if (pfc->data->uncompressed_data) {
326 size_t to_read_from_buffer = MIN(pfc->data->uncompressed_data->bytes_left(pfc->data->uncompressed_data), to_read);
327 DBG_INF_FMT("reading %zu from uncompressed_data buffer", to_read_from_buffer);
328 if (to_read_from_buffer) {
329 pfc->data->uncompressed_data->read(pfc->data->uncompressed_data, to_read_from_buffer, (zend_uchar *) p);
330 p += to_read_from_buffer;
331 to_read -= to_read_from_buffer;
332 }
333 DBG_INF_FMT("left %zu to read", to_read);
334 if (TRUE == pfc->data->uncompressed_data->is_empty(pfc->data->uncompressed_data)) {
335 /* Everything was consumed. This should never happen here, but for security */
336 pfc->data->uncompressed_data->free_buffer(&pfc->data->uncompressed_data);
337 }
338 }
339 if (to_read) {
341 size_t net_payload_size;
342 zend_uchar packet_no;
343
344 if (FAIL == vio->data->m.network_read(vio, net_header, MYSQLND_HEADER_SIZE, conn_stats, error_info)) {
346 }
347 net_payload_size = uint3korr(net_header);
348 packet_no = uint1korr(net_header + 3);
349 if (pfc->data->compressed_envelope_packet_no != packet_no) {
350 DBG_ERR_FMT("Transport level: packets out of order. Expected %u received %u. Packet size=%zu",
351 pfc->data->compressed_envelope_packet_no, packet_no, net_payload_size);
352
353 php_error(E_WARNING, "Packets out of order. Expected %u received %u. Packet size=%zu",
354 pfc->data->compressed_envelope_packet_no, packet_no, net_payload_size);
356 }
357 pfc->data->compressed_envelope_packet_no++;
358 /* Now let's read from the wire, decompress it and fill the read buffer */
359 pfc->data->m.read_compressed_packet_from_stream_and_fill_read_buffer(pfc, vio, net_payload_size, conn_stats, error_info);
360
361 /*
362 Now a bit of recursion - read from the read buffer,
363 if the data which we have just read from the wire
364 is not enough, then the recursive call will try to
365 satisfy it until it is satisfied.
366 */
367 DBG_RETURN(pfc->data->m.receive(pfc, vio, p, to_read, conn_stats, error_info));
368 }
370 }
371#endif /* MYSQLND_COMPRESSION_ENABLED */
372 DBG_RETURN(vio->data->m.network_read(vio, p, to_read, conn_stats, error_info));
373}
374/* }}} */
375
376
377/* {{{ mysqlnd_pfc::set_client_option */
378static enum_func_status
379MYSQLND_METHOD(mysqlnd_pfc, set_client_option)(MYSQLND_PFC * const pfc, enum_mysqlnd_client_option option, const char * const value)
380{
381 DBG_ENTER("mysqlnd_pfc::set_client_option");
382 DBG_INF_FMT("option=%u", option);
383 switch (option) {
385 pfc->data->flags |= MYSQLND_PROTOCOL_FLAG_USE_COMPRESSION;
386 break;
388 const bool pers = pfc->persistent;
389 if (pfc->data->sha256_server_public_key) {
390 mnd_pefree(pfc->data->sha256_server_public_key, pers);
391 }
392 pfc->data->sha256_server_public_key = value? mnd_pestrdup(value, pers) : NULL;
393 break;
394 }
396 DBG_INF("MYSQLND_OPT_NET_CMD_BUFFER_SIZE");
397 if (*(unsigned int*) value < MYSQLND_NET_CMD_BUFFER_MIN_SIZE) {
399 }
400 pfc->cmd_buffer.length = *(unsigned int*) value;
401 DBG_INF_FMT("new_length=%zu", pfc->cmd_buffer.length);
402 if (!pfc->cmd_buffer.buffer) {
403 pfc->cmd_buffer.buffer = mnd_pemalloc(pfc->cmd_buffer.length, pfc->persistent);
404 } else {
405 pfc->cmd_buffer.buffer = mnd_perealloc(pfc->cmd_buffer.buffer, pfc->cmd_buffer.length, pfc->persistent);
406 }
407 break;
408 }
409 default:
411 }
413}
414/* }}} */
415
416
417/* {{{ mysqlnd_pfc::free_contents */
418static void
419MYSQLND_METHOD(mysqlnd_pfc, free_contents)(MYSQLND_PFC * pfc)
420{
421 DBG_ENTER("mysqlnd_pfc::free_contents");
422
423#ifdef MYSQLND_COMPRESSION_ENABLED
424 if (pfc->data->uncompressed_data) {
425 pfc->data->uncompressed_data->free_buffer(&pfc->data->uncompressed_data);
426 }
427#endif
428 if (pfc->data->sha256_server_public_key) {
429 mnd_pefree(pfc->data->sha256_server_public_key, pfc->persistent);
430 pfc->data->sha256_server_public_key = NULL;
431 }
432
434}
435/* }}} */
436
437
438/* {{{ mysqlnd_pfc::init */
439static void
440MYSQLND_METHOD(mysqlnd_pfc, init)(MYSQLND_PFC * const pfc, MYSQLND_STATS * const stats, MYSQLND_ERROR_INFO * const error_info)
441{
442 unsigned int buf_size;
443 DBG_ENTER("mysqlnd_pfc::init");
444
445 buf_size = MYSQLND_G(net_cmd_buffer_size); /* this is long, cast to unsigned int*/
446 pfc->data->m.set_client_option(pfc, MYSQLND_OPT_NET_CMD_BUFFER_SIZE, (char *) &buf_size);
447
449}
450/* }}} */
451
452
453/* {{{ mysqlnd_pfc::dtor */
454static void
455MYSQLND_METHOD(mysqlnd_pfc, dtor)(MYSQLND_PFC * const pfc, MYSQLND_STATS * const stats, MYSQLND_ERROR_INFO * const error_info)
456{
457 DBG_ENTER("mysqlnd_pfc::dtor");
458 if (pfc) {
459 pfc->data->m.free_contents(pfc);
460
461 if (pfc->cmd_buffer.buffer) {
462 DBG_INF("Freeing cmd buffer");
463 mnd_pefree(pfc->cmd_buffer.buffer, pfc->persistent);
464 pfc->cmd_buffer.buffer = NULL;
465 }
466
467 mnd_pefree(pfc, pfc->persistent);
468 }
470}
471/* }}} */
472
473
474MYSQLND_CLASS_METHODS_START(mysqlnd_protocol_packet_frame_codec)
475 MYSQLND_METHOD(mysqlnd_pfc, init),
476 MYSQLND_METHOD(mysqlnd_pfc, dtor),
477 MYSQLND_METHOD(mysqlnd_pfc, reset),
478
479 MYSQLND_METHOD(mysqlnd_pfc, set_client_option),
480
481 MYSQLND_METHOD(mysqlnd_pfc, decode),
482 MYSQLND_METHOD(mysqlnd_pfc, encode),
483
484 MYSQLND_METHOD(mysqlnd_pfc, send),
485 MYSQLND_METHOD(mysqlnd_pfc, receive),
486
487#ifdef MYSQLND_COMPRESSION_ENABLED
488 MYSQLND_METHOD(mysqlnd_pfc, read_compressed_packet_from_stream_and_fill_read_buffer),
489#else
491#endif
492
493 MYSQLND_METHOD(mysqlnd_pfc, free_contents),
495
496
497/* {{{ mysqlnd_pfc_init */
499mysqlnd_pfc_init(const bool persistent, MYSQLND_CLASS_METHODS_TYPE(mysqlnd_object_factory) *object_factory, MYSQLND_STATS * stats, MYSQLND_ERROR_INFO * error_info)
500{
501 MYSQLND_CLASS_METHODS_TYPE(mysqlnd_object_factory) *factory = object_factory? object_factory : &MYSQLND_CLASS_METHOD_TABLE_NAME(mysqlnd_object_factory);
502 MYSQLND_PFC * pfc;
503 DBG_ENTER("mysqlnd_pfc_init");
504 pfc = factory->get_protocol_frame_codec(persistent, stats, error_info);
505 DBG_RETURN(pfc);
506}
507/* }}} */
508
509
510/* {{{ mysqlnd_pfc_free */
511PHPAPI void
513{
514 DBG_ENTER("mysqlnd_pfc_free");
515 if (pfc) {
516 pfc->data->m.dtor(pfc, stats, error_info);
517 }
519}
520/* }}} */
printf(string $format, mixed ... $values)
reset(array|object &$array)
count(Countable|array $value, int $mode=COUNT_NORMAL)
#define int3store(T, A)
Definition config-win.h:60
#define uint3korr(A)
Definition config-win.h:50
error($message)
Definition ext_skel.php:22
zend_string * res
Definition ffi.c:4692
memcpy(ptr1, ptr2, size)
ffi persistent
Definition ffi.c:3633
const php_stream_filter_factory * factory
Definition filters.c:1900
#define TRUE
Definition gd_gd.c:7
#define NULL
Definition gdcache.h:45
#define PASS(tables)
Definition hash_gost.c:193
#define compress(passes)
Definition hash_tiger.c:83
lu_byte left
Definition minilua.c:4266
#define MYSQLND_INC_CONN_STATISTIC_W_VALUE3(conn_stats, statistic1, value1, statistic2, value2, statistic3, value3)
Definition mysqlnd.h:276
#define MYSQLND_G(v)
zend_long net_cmd_buffer_size
Definition mysqlnd.h:302
#define MYSQLND_METHOD(class, method)
Definition mysqlnd.h:294
#define mnd_pemalloc(size, pers)
#define mnd_pestrdup(ptr, pers)
#define mnd_perealloc(ptr, new_size, p)
#define mnd_efree(ptr)
#define mnd_emalloc(size)
#define mnd_pefree(ptr, pers)
PHPAPI const char *const mysqlnd_server_gone
#define DBG_VOID_RETURN
#define DBG_RETURN(value)
#define MYSQLND_PROTOCOL_FLAG_USE_COMPRESSION
#define CR_SERVER_GONE_ERROR
@ MYSQL_OPT_COMPRESS
@ MYSQLND_OPT_NET_CMD_BUFFER_SIZE
@ MYSQL_SERVER_PUBLIC_KEY
enum mysqlnd_client_option enum_mysqlnd_client_option
@ STAT_PACKETS_SENT
@ STAT_PROTOCOL_OVERHEAD_OUT
@ STAT_BYTES_SENT
#define MYSQLND_MAX_PACKET_SIZE
#define MYSQLND_NET_CMD_BUFFER_MIN_SIZE
enum func_status enum_func_status
#define UNKNOWN_SQLSTATE
#define int1store(T, A)
#define uint1korr(A)
PHPAPI void mysqlnd_pfc_free(MYSQLND_PFC *const pfc, MYSQLND_STATS *stats, MYSQLND_ERROR_INFO *error_info)
PHPAPI MYSQLND_PFC * mysqlnd_pfc_init(const bool persistent, MYSQLND_CLASS_METHODS_TYPE(mysqlnd_object_factory) *object_factory, MYSQLND_STATS *stats, MYSQLND_ERROR_INFO *error_info)
#define STORE_HEADER_SIZE(safe_storage, buffer)
#define RESTORE_HEADER_SIZE(buffer, safe_storage)
PHPAPI MYSQLND_READ_BUFFER * mysqlnd_create_read_buffer(const size_t count)
#define MYSQLND_CLASS_METHODS_END
struct st_mysqlnd_vio MYSQLND_VIO
#define MYSQLND_CLASS_METHODS_TYPE(class)
struct st_mysqlnd_stats MYSQLND_STATS
struct st_mysqlnd_protocol_frame_codec MYSQLND_PFC
#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)
#define COMPRESSED_HEADER_SIZE
#define MYSQLND_HEADER_SIZE
#define PHPAPI
Definition php.h:71
#define php_error
Definition php.h:310
unsigned const char * end
Definition php_ffi.h:51
struct _encode encode
Definition php_soap.h:42
p
Definition session.c:1105
#define FAIL(...)
Definition file.h:177
struct st_mysqlnd_protocol_frame_codec_data * data
struct st_mysqlnd_vio_data * data
#define E_WARNING
Definition zend_errors.h:24
#define MIN(a, b)
unsigned char zend_uchar
Definition zend_types.h:57
zval retval
value