36 #include <my_global.h>
38 #include <mysql_com.h>
39 #include <mysqld_error.h>
46 #include "probes_mysql.h"
53 #ifdef EMBEDDED_LIBRARY
75 #ifdef HAVE_QUERY_CACHE
76 #define USE_QUERY_CACHE
77 extern void query_cache_insert(
const char *packet, ulong length,
80 #define update_statistics(A) A
82 #define update_statistics(A)
83 #define thd_increment_bytes_sent(N)
88 #include "mysql_com_server.h"
91 #define VIO_SOCKET_ERROR ((size_t) -1)
92 #define MAX_PACKET_LENGTH (256L*256L*256L-1)
94 static my_bool net_write_buff(
NET *,
const uchar *, ulong);
100 DBUG_ENTER(
"my_net_init");
102 my_net_local_init(net);
103 if (!(net->buff=(uchar*) my_malloc((
size_t) net->max_packet+
104 NET_HEADER_SIZE + COMP_HEADER_SIZE,
107 net->buff_end=net->buff+net->max_packet;
108 net->error=0; net->return_status=0;
109 net->pkt_nr=net->compress_pkt_nr=0;
110 net->write_pos=net->read_pos = net->buff;
112 net->compress=0; net->reading_or_writing=0;
113 net->where_b = net->remain_in_buf=0;
123 net->fd= vio_fd(vio);
130 void net_end(
NET *net)
132 DBUG_ENTER(
"net_end");
145 DBUG_ENTER(
"net_realloc");
146 DBUG_PRINT(
"enter",(
"length: %lu", (ulong) length));
148 if (length >= net->max_packet_size)
150 DBUG_PRINT(
"error", (
"Packet too large. Max size: %lu",
151 net->max_packet_size));
154 net->last_errno= ER_NET_PACKET_TOO_LARGE;
156 my_error(ER_NET_PACKET_TOO_LARGE, MYF(0));
160 pkt_length = (length+IO_SIZE-1) & ~(IO_SIZE-1);
167 if (!(buff= (uchar*) my_realloc((
char*) net->buff, pkt_length +
168 NET_HEADER_SIZE + COMP_HEADER_SIZE + 1,
173 net->last_errno= ER_OUT_OF_RESOURCES;
177 net->buff=net->write_pos=buff;
178 net->buff_end=buff+(net->max_packet= (ulong) pkt_length);
194 my_bool check_buffer __attribute__((unused)))
196 DBUG_ENTER(
"net_clear");
198 #if !defined(EMBEDDED_LIBRARY)
200 DBUG_ASSERT(!check_buffer || (vio_pending(net->vio) <= 1));
204 net->pkt_nr= net->compress_pkt_nr= 0;
205 net->write_pos= net->buff;
216 DBUG_ENTER(
"net_flush");
217 if (net->buff != net->write_pos)
220 (
size_t) (net->write_pos - net->buff));
221 net->write_pos= net->buff;
225 net->pkt_nr=net->compress_pkt_nr;
241 net_should_retry(
NET *net, uint *retry_count __attribute__((unused)))
245 #if !defined(MYSQL_SERVER) && defined(THREAD_SAFE_CLIENT)
251 retry= vio_should_retry(net->vio);
259 retry= vio_should_retry(net->vio) && ((*retry_count)++ < net->retry_count);
281 uchar buff[NET_HEADER_SIZE];
284 if (unlikely(!net->vio))
287 MYSQL_NET_WRITE_START(len);
294 while (len >= MAX_PACKET_LENGTH)
296 const ulong z_size = MAX_PACKET_LENGTH;
297 int3store(buff, z_size);
298 buff[3]= (uchar) net->pkt_nr++;
299 if (net_write_buff(net, buff, NET_HEADER_SIZE) ||
300 net_write_buff(net, packet, z_size))
302 MYSQL_NET_WRITE_DONE(1);
310 buff[3]= (uchar) net->pkt_nr++;
311 if (net_write_buff(net, buff, NET_HEADER_SIZE))
313 MYSQL_NET_WRITE_DONE(1);
316 #ifndef DEBUG_DATA_PACKETS
317 DBUG_DUMP(
"packet_header", buff, NET_HEADER_SIZE);
319 rc=
test(net_write_buff(net,packet,len));
320 MYSQL_NET_WRITE_DONE(rc);
354 const uchar *header,
size_t head_len,
355 const uchar *packet,
size_t len)
357 size_t length=len+1+head_len;
358 uchar buff[NET_HEADER_SIZE+1];
359 uint header_size=NET_HEADER_SIZE+1;
361 DBUG_ENTER(
"net_write_command");
362 DBUG_PRINT(
"enter",(
"length: %lu", (ulong) len));
364 MYSQL_NET_WRITE_START(length);
368 if (length >= MAX_PACKET_LENGTH)
371 len= MAX_PACKET_LENGTH - 1 - head_len;
374 int3store(buff, MAX_PACKET_LENGTH);
375 buff[3]= (uchar) net->pkt_nr++;
376 if (net_write_buff(net, buff, header_size) ||
377 net_write_buff(net, header, head_len) ||
378 net_write_buff(net, packet, len))
380 MYSQL_NET_WRITE_DONE(1);
384 length-= MAX_PACKET_LENGTH;
385 len= MAX_PACKET_LENGTH;
387 header_size= NET_HEADER_SIZE;
388 }
while (length >= MAX_PACKET_LENGTH);
391 int3store(buff,length);
392 buff[3]= (uchar) net->pkt_nr++;
393 rc=
test(net_write_buff(net, buff, header_size) ||
394 (head_len && net_write_buff(net, header, head_len)) ||
395 net_write_buff(net, packet, len) ||
net_flush(net));
396 MYSQL_NET_WRITE_DONE(rc);
428 net_write_buff(
NET *net,
const uchar *packet, ulong len)
431 if (net->compress && net->max_packet > MAX_PACKET_LENGTH)
432 left_length= (ulong) (MAX_PACKET_LENGTH - (net->write_pos - net->buff));
434 left_length= (ulong) (net->buff_end - net->write_pos);
436 #ifdef DEBUG_DATA_PACKETS
437 DBUG_DUMP(
"data", packet, len);
439 if (len > left_length)
441 if (net->write_pos != net->buff)
444 memcpy(net->write_pos, packet, left_length);
446 (
size_t) (net->write_pos - net->buff) + left_length))
448 net->write_pos= net->buff;
449 packet+= left_length;
458 left_length= MAX_PACKET_LENGTH;
459 while (len > left_length)
463 packet+= left_length;
467 if (len > net->max_packet)
471 memcpy(net->write_pos, packet, len);
472 net->write_pos+= len;
488 net_write_raw_loop(
NET *net,
const uchar *
buf,
size_t count)
490 unsigned int retry_count= 0;
494 size_t sentcnt= vio_write(net->vio, buf, count);
497 if (sentcnt == VIO_SOCKET_ERROR)
500 if (net_should_retry(net, &retry_count))
508 update_statistics(thd_increment_bytes_sent(sentcnt));
518 if (vio_was_timeout(net->vio))
519 net->last_errno= ER_NET_WRITE_INTERRUPTED;
521 net->last_errno= ER_NET_ERROR_ON_WRITE;
524 my_error(net->last_errno, MYF(0));
547 compress_packet(
NET *net,
const uchar *packet,
size_t *length)
551 const uint header_length= NET_HEADER_SIZE + COMP_HEADER_SIZE;
553 compr_packet= (uchar *) my_malloc(*length + header_length, MYF(MY_WME));
555 if (compr_packet == NULL)
558 memcpy(compr_packet + header_length, packet, *length);
561 if (my_compress(compr_packet + header_length, length, &compr_length))
571 int3store(&compr_packet[NET_HEADER_SIZE], compr_length);
573 int3store(compr_packet, *length);
575 compr_packet[3]= (uchar) (net->compress_pkt_nr++);
577 *length+= header_length;
599 DBUG_ENTER(
"net_write_packet");
601 #if defined(MYSQL_SERVER) && defined(USE_QUERY_CACHE)
602 query_cache_insert((
char*) packet, length, net->pkt_nr);
609 net->reading_or_writing= 2;
612 const bool do_compress= net->compress;
615 if ((packet= compress_packet(net, packet, &length)) == NULL)
618 net->last_errno= ER_OUT_OF_RESOURCES;
620 net->reading_or_writing= 0;
626 #ifdef DEBUG_DATA_PACKETS
627 DBUG_DUMP(
"data", packet, length);
630 res= net_write_raw_loop(net, packet, length);
634 my_free((
void *) packet);
637 net->reading_or_writing= 0;
655 static my_bool net_read_raw_loop(
NET *net,
size_t count)
658 unsigned int retry_count= 0;
659 uchar *buf= net->buff + net->where_b;
663 size_t recvcnt= vio_read(net->vio, buf, count);
666 if (recvcnt == VIO_SOCKET_ERROR)
669 if (net_should_retry(net, &retry_count))
683 update_statistics(thd_increment_bytes_received(recvcnt));
693 if (!eof && vio_was_timeout(net->vio))
694 net->last_errno= ER_NET_READ_INTERRUPTED;
696 net->last_errno= ER_NET_READ_ERROR;
699 my_error(net->last_errno, MYF(0));
724 static my_bool net_read_packet_header(
NET *net)
727 size_t count= NET_HEADER_SIZE;
731 count+= COMP_HEADER_SIZE;
738 if (server_extension != NULL)
740 void *user_data= server_extension->m_user_data;
741 DBUG_ASSERT(server_extension->m_before_header != NULL);
742 DBUG_ASSERT(server_extension->m_after_header != NULL);
744 server_extension->m_before_header(net, user_data, count);
745 rc= net_read_raw_loop(net, count);
746 server_extension->m_after_header(net, user_data, count, rc);
751 rc= net_read_raw_loop(net, count);
757 DBUG_DUMP(
"packet_header", net->buff + net->where_b, NET_HEADER_SIZE);
759 pkt_nr= net->buff[net->where_b + 3];
765 if (pkt_nr != (uchar) net->pkt_nr)
768 #if defined(MYSQL_SERVER)
769 my_error(ER_NET_PACKETS_OUT_OF_ORDER, MYF(0));
770 #elif defined(EXTRA_DEBUG)
777 fprintf(stderr,
"Error: packets out of order (found %u, expected %u)\n",
778 (uint) pkt_nr, net->pkt_nr);
779 DBUG_ASSERT(pkt_nr == net->pkt_nr);
801 static ulong net_read_packet(
NET *net,
size_t *complen)
803 size_t pkt_len, pkt_data_len;
807 net->reading_or_writing= 1;
810 if (net_read_packet_header(net))
813 net->compress_pkt_nr= net->pkt_nr;
823 DBUG_ASSERT(net->where_b + NET_HEADER_SIZE +
sizeof(uint32) <=
824 net->max_packet + NET_HEADER_SIZE + COMP_HEADER_SIZE + 1);
830 *complen= uint3korr(&(net->buff[net->where_b + NET_HEADER_SIZE]));
835 pkt_len= uint3korr(net->buff+net->where_b);
841 pkt_data_len = max(pkt_len, *complen) + net->where_b;
844 if ((pkt_data_len >= net->max_packet) &&
net_realloc(net, pkt_data_len))
848 if (net_read_raw_loop(net, pkt_len))
852 net->reading_or_writing= 0;
856 net->reading_or_writing= 0;
882 MYSQL_NET_READ_START();
888 len= net_read_packet(net, &complen);
889 if (len == MAX_PACKET_LENGTH)
892 ulong save_pos = net->where_b;
893 size_t total_length= 0;
898 len= net_read_packet(net, &complen);
899 }
while (len == MAX_PACKET_LENGTH);
900 if (len != packet_error)
902 net->where_b = save_pos;
904 net->read_pos = net->buff + net->where_b;
905 if (len != packet_error)
906 net->read_pos[len]=0;
907 MYSQL_NET_READ_DONE(0, len);
916 ulong start_of_packet;
917 ulong first_packet_offset;
918 uint read_length, multi_byte_packet=0;
920 if (net->remain_in_buf)
922 buf_length= net->buf_length;
923 first_packet_offset= start_of_packet= (net->buf_length -
926 net->buff[start_of_packet]= net->save_char;
931 buf_length= start_of_packet= first_packet_offset= 0;
937 if (buf_length - start_of_packet >= NET_HEADER_SIZE)
939 read_length = uint3korr(net->buff+start_of_packet);
943 start_of_packet += NET_HEADER_SIZE;
946 if (read_length + NET_HEADER_SIZE <= buf_length - start_of_packet)
948 if (multi_byte_packet)
951 memmove(net->buff + first_packet_offset + start_of_packet,
952 net->buff + first_packet_offset + start_of_packet +
954 buf_length - start_of_packet);
955 start_of_packet += read_length;
956 buf_length -= NET_HEADER_SIZE;
959 start_of_packet+= read_length + NET_HEADER_SIZE;
961 if (read_length != MAX_PACKET_LENGTH)
963 multi_byte_packet= 0;
966 multi_byte_packet= NET_HEADER_SIZE;
968 if (first_packet_offset)
970 memmove(net->buff,net->buff+first_packet_offset,
971 buf_length-first_packet_offset);
972 buf_length-=first_packet_offset;
973 start_of_packet -= first_packet_offset;
974 first_packet_offset=0;
980 if (first_packet_offset)
982 memmove(net->buff,net->buff+first_packet_offset,
983 buf_length-first_packet_offset);
984 buf_length-=first_packet_offset;
985 start_of_packet -= first_packet_offset;
986 first_packet_offset=0;
989 net->where_b=buf_length;
990 if ((packet_len= net_read_packet(net, &complen)) == packet_error)
992 MYSQL_NET_READ_DONE(1, 0);
995 if (my_uncompress(net->buff + net->where_b, packet_len,
999 net->last_errno= ER_NET_UNCOMPRESS_ERROR;
1001 my_error(ER_NET_UNCOMPRESS_ERROR, MYF(0));
1003 MYSQL_NET_READ_DONE(1, 0);
1004 return packet_error;
1006 buf_length+= complen;
1009 net->read_pos= net->buff+ first_packet_offset + NET_HEADER_SIZE;
1010 net->buf_length= buf_length;
1011 net->remain_in_buf= (ulong) (buf_length - start_of_packet);
1012 len = ((ulong) (start_of_packet - first_packet_offset) - NET_HEADER_SIZE -
1014 net->save_char= net->read_pos[len];
1015 net->read_pos[len]=0;
1018 MYSQL_NET_READ_DONE(0, len);
1023 void my_net_set_read_timeout(
NET *net, uint timeout)
1025 DBUG_ENTER(
"my_net_set_read_timeout");
1026 DBUG_PRINT(
"enter", (
"timeout: %d", timeout));
1027 net->read_timeout= timeout;
1029 vio_timeout(net->vio, 0, timeout);
1034 void my_net_set_write_timeout(
NET *net, uint timeout)
1036 DBUG_ENTER(
"my_net_set_write_timeout");
1037 DBUG_PRINT(
"enter", (
"timeout: %d", timeout));
1038 net->write_timeout= timeout;
1040 vio_timeout(net->vio, 1, timeout);