26#ifdef MYSQLND_COMPRESSION_ENABLED
35 DBG_ENTER(
"mysqlnd_pfc::reset");
36 pfc->data->packet_no = pfc->data->compressed_envelope_packet_no = 0;
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))
51#ifdef MYSQLND_COMPRESSION_ENABLED
52static ssize_t write_compressed_packet(
56 DBG_ENTER(
"write_compressed_packet");
58 size_t tmp_complen = to_be_sent;
61 uncompressed_payload, to_be_sent))
64 payload_size = tmp_complen;
68 payload_size = to_be_sent;
77#ifdef WHEN_WE_NEED_TO_CHECK_WHETHER_COMPRESSION_WORKS_CORRECTLY
81 int error = pfc->
data->m.decode(decompressed_data, decompressed_size,
85 DBG_INF(
"success decompressing");
86 for (i = 0 ; i < decompressed_size; i++) {
87 if (i && (i % 30 == 0)) {
90 printf(
"%.2X ", (
int)*((
char*)&(decompressed_data[i])));
91 DBG_INF_FMT(
"%.2X ", (
int)*((
char*)&(decompressed_data[i])));
94 DBG_INF(
"error decompressing");
120 size_t packets_sent = 1;
127 DBG_ENTER(
"mysqlnd_pfc::send");
128 DBG_INF_FMT(
"count=%zu compression=%u",
count, pfc->data->compressed);
130 if (pfc->data->compressed ==
TRUE) {
132 DBG_INF_FMT(
"compress_buf_size=%zu", comp_buf_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) {
146 int3store(uncompressed_payload, to_be_sent);
147 int1store(uncompressed_payload + 3, pfc->data->packet_no);
149 bytes_sent = write_compressed_packet(
150 pfc, vio, conn_stats, error_info,
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,
168 DBG_INF(
"no compression");
172 bytes_sent = vio->data->m.network_write(vio,
p, to_be_sent +
MYSQLND_HEADER_SIZE, conn_stats, error_info);
174 pfc->data->compressed_envelope_packet_no++;
176 pfc->data->packet_no++;
190 DBG_INF_FMT(
"packet_size=%zu packet_no=%u",
left, pfc->data->packet_no);
202 if (bytes_sent <= 0) {
203 DBG_ERR_FMT(
"Can't %zu send bytes",
count);
212#ifdef MYSQLND_COMPRESSION_ENABLED
216MYSQLND_METHOD(mysqlnd_pfc, read_compressed_packet_from_stream_and_fill_read_buffer)
219 size_t decompressed_size;
223 DBG_ENTER(
"mysqlnd_pfc::read_compressed_packet_from_stream_and_fill_read_buffer");
229 decompressed_size =
uint3korr(comp_header);
234 if (decompressed_size) {
236 if (
FAIL == vio->data->m.network_read(vio, compressed_data, net_payload_size, conn_stats, error_info)) {
241 retval = pfc->data->m.decode(pfc->data->uncompressed_data->data, decompressed_size, compressed_data, net_payload_size);
246 DBG_INF_FMT(
"The server decided not to compress the data. Our job is easy. Copying %zu bytes", net_payload_size);
248 if (
FAIL == vio->data->m.network_read(vio, pfc->data->uncompressed_data->data, net_payload_size, conn_stats, error_info)) {
254 if (compressed_data) {
266 const zend_uchar *
const compressed_data,
const size_t compressed_data_len)
268#ifdef MYSQLND_COMPRESSION_ENABLED
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);
274 DBG_INF_FMT(
"compressed data: decomp_len=%lu compressed_size=%zu", tmp_complen, compressed_data_len);
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);
280 DBG_ENTER(
"mysqlnd_pfc::decode");
290 const zend_uchar *
const uncompressed_data,
const size_t uncompressed_data_len)
292#ifdef MYSQLND_COMPRESSION_ENABLED
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);
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);
301 *compress_buffer_len = tmp_complen;
302 DBG_INF_FMT(
"compression successful. compressed size=%lu", tmp_complen);
307 DBG_ENTER(
"mysqlnd_pfc::encode");
319 size_t to_read =
count;
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;
333 DBG_INF_FMT(
"left %zu to read", to_read);
334 if (
TRUE == pfc->data->uncompressed_data->is_empty(pfc->data->uncompressed_data)) {
336 pfc->data->uncompressed_data->free_buffer(&pfc->data->uncompressed_data);
341 size_t net_payload_size;
347 net_payload_size =
uint3korr(net_header);
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);
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);
357 pfc->data->compressed_envelope_packet_no++;
359 pfc->data->m.read_compressed_packet_from_stream_and_fill_read_buffer(pfc, vio, net_payload_size, conn_stats, error_info);
367 DBG_RETURN(pfc->data->m.receive(pfc, vio,
p, to_read, conn_stats, error_info));
372 DBG_RETURN(vio->data->m.network_read(vio,
p, to_read, conn_stats, error_info));
381 DBG_ENTER(
"mysqlnd_pfc::set_client_option");
382 DBG_INF_FMT(
"option=%u", option);
388 const bool pers = pfc->persistent;
389 if (pfc->data->sha256_server_public_key) {
390 mnd_pefree(pfc->data->sha256_server_public_key, pers);
396 DBG_INF(
"MYSQLND_OPT_NET_CMD_BUFFER_SIZE");
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);
405 pfc->cmd_buffer.buffer =
mnd_perealloc(pfc->cmd_buffer.buffer, pfc->cmd_buffer.length, pfc->persistent);
421 DBG_ENTER(
"mysqlnd_pfc::free_contents");
423#ifdef MYSQLND_COMPRESSION_ENABLED
424 if (pfc->data->uncompressed_data) {
425 pfc->data->uncompressed_data->free_buffer(&pfc->data->uncompressed_data);
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;
442 unsigned int buf_size;
443 DBG_ENTER(
"mysqlnd_pfc::init");
457 DBG_ENTER(
"mysqlnd_pfc::dtor");
459 pfc->data->m.free_contents(pfc);
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;
487#ifdef MYSQLND_COMPRESSION_ENABLED
488 MYSQLND_METHOD(mysqlnd_pfc, read_compressed_packet_from_stream_and_fill_read_buffer),
503 DBG_ENTER(
"mysqlnd_pfc_init");
514 DBG_ENTER(
"mysqlnd_pfc_free");
516 pfc->
data->m.dtor(pfc, stats, error_info);
printf(string $format, mixed ... $values)
reset(array|object &$array)
count(Countable|array $value, int $mode=COUNT_NORMAL)
const php_stream_filter_factory * factory
#define MYSQLND_INC_CONN_STATISTIC_W_VALUE3(conn_stats, statistic1, value1, statistic2, value2, statistic3, value3)
zend_long net_cmd_buffer_size
#define MYSQLND_METHOD(class, method)
#define mnd_pemalloc(size, pers)
#define mnd_pestrdup(ptr, pers)
#define mnd_perealloc(ptr, new_size, p)
#define mnd_emalloc(size)
#define mnd_pefree(ptr, pers)
PHPAPI const char *const mysqlnd_server_gone
#define DBG_RETURN(value)
#define MYSQLND_PROTOCOL_FLAG_USE_COMPRESSION
#define CR_SERVER_GONE_ERROR
@ MYSQLND_OPT_NET_CMD_BUFFER_SIZE
@ MYSQL_SERVER_PUBLIC_KEY
enum mysqlnd_client_option enum_mysqlnd_client_option
@ STAT_PROTOCOL_OVERHEAD_OUT
#define MYSQLND_MAX_PACKET_SIZE
#define MYSQLND_NET_CMD_BUFFER_MIN_SIZE
enum func_status enum_func_status
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
unsigned const char * end
zend_uchar compressed_envelope_packet_no
struct st_mysqlnd_protocol_frame_codec_data * data
struct st_mysqlnd_vio_data * data