mySQL 5.0.11 sources for tomato
[tomato.git] / release / src / router / mysql / sql / net_serv.cc
blobd7c2401c68be9080d68fe41d2ee69888c7a1d1cf
1 /* Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved.
3 This program is free software; you can redistribute it and/or modify
4 it under the terms of the GNU General Public License as published by
5 the Free Software Foundation; version 2 of the License.
7 This program is distributed in the hope that it will be useful,
8 but WITHOUT ANY WARRANTY; without even the implied warranty of
9 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10 GNU General Public License for more details.
12 You should have received a copy of the GNU General Public License
13 along with this program; if not, write to the Free Software
14 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */
16 /**
17 @file
19 This file is the net layer API for the MySQL client/server protocol.
21 Write and read of logical packets to/from socket.
23 Writes are cached into net_buffer_length big packets.
24 Read packets are reallocated dynamicly when reading big packets.
25 Each logical packet has the following pre-info:
26 3 byte length & 1 byte package-number.
28 This file needs to be written in C as it's used by the libmysql client as a
29 C file.
33 HFTODO this must be hidden if we don't want client capabilities in
34 embedded library
36 #include <my_global.h>
37 #include <mysql.h>
38 #include <mysql_embed.h>
39 #include <mysql_com.h>
40 #include <mysqld_error.h>
41 #include <my_sys.h>
42 #include <m_string.h>
43 #include <my_net.h>
44 #include <violite.h>
45 #include <signal.h>
46 #include <errno.h>
47 #ifdef __NETWARE__
48 #include <sys/select.h>
49 #endif
51 #ifdef EMBEDDED_LIBRARY
52 #undef MYSQL_SERVER
53 #undef MYSQL_CLIENT
54 #define MYSQL_CLIENT
55 #endif /*EMBEDDED_LIBRARY */
59 The following handles the differences when this is linked between the
60 client and the server.
62 This gives an error if a too big packet is found
63 The server can change this with the -O switch, but because the client
64 can't normally do this the client should have a bigger max_allowed_packet.
67 #if defined(__WIN__) || !defined(MYSQL_SERVER)
68 /* The following is because alarms doesn't work on windows. */
69 #define NO_ALARM
70 #endif
72 #ifndef NO_ALARM
73 #include "my_pthread.h"
74 void sql_print_error(const char *format,...);
75 #else
76 #define DONT_USE_THR_ALARM
77 #endif /* NO_ALARM */
79 #include "thr_alarm.h"
81 #ifdef MYSQL_SERVER
83 The following variables/functions should really not be declared
84 extern, but as it's hard to include mysql_priv.h here, we have to
85 live with this for a while.
87 extern uint test_flags;
88 extern ulong bytes_sent, bytes_received, net_big_packet_count;
89 extern pthread_mutex_t LOCK_bytes_sent , LOCK_bytes_received;
90 #ifndef MYSQL_INSTANCE_MANAGER
91 #ifdef HAVE_QUERY_CACHE
92 #define USE_QUERY_CACHE
93 extern void query_cache_init_query(NET *net);
94 extern void query_cache_insert(NET *net, const char *packet, ulong length);
95 #endif // HAVE_QUERY_CACHE
96 #define update_statistics(A) A
97 #endif /* MYSQL_INSTANCE_MANGER */
98 #endif /* defined(MYSQL_SERVER) && !defined(MYSQL_INSTANCE_MANAGER) */
100 #if !defined(MYSQL_SERVER) || defined(MYSQL_INSTANCE_MANAGER)
101 #define update_statistics(A)
102 #define thd_increment_bytes_sent(N)
103 #endif
105 #define TEST_BLOCKING 8
106 #define MAX_PACKET_LENGTH (256L*256L*256L-1)
108 static my_bool net_write_buff(NET *net,const uchar *packet,ulong len);
111 /** Init with packet info. */
113 my_bool my_net_init(NET *net, Vio* vio)
115 DBUG_ENTER("my_net_init");
116 net->vio = vio;
117 my_net_local_init(net); /* Set some limits */
118 if (!(net->buff=(uchar*) my_malloc((size_t) net->max_packet+
119 NET_HEADER_SIZE + COMP_HEADER_SIZE,
120 MYF(MY_WME))))
121 DBUG_RETURN(1);
122 net->buff_end=net->buff+net->max_packet;
123 net->error=0; net->return_errno=0; net->return_status=0;
124 net->pkt_nr=net->compress_pkt_nr=0;
125 net->write_pos=net->read_pos = net->buff;
126 net->last_error[0]=0;
127 net->compress=0; net->reading_or_writing=0;
128 net->where_b = net->remain_in_buf=0;
129 net->last_errno=0;
130 #ifdef USE_QUERY_CACHE
131 query_cache_init_query(net);
132 #else
133 net->query_cache_query= 0;
134 #endif
135 #if defined(MYSQL_SERVER) && !defined(EMBEDDED_LIBRARY)
136 net->skip_big_packet= FALSE;
137 #endif
139 if (vio != 0) /* If real connection */
141 net->fd = vio_fd(vio); /* For perl DBI/DBD */
142 #if defined(MYSQL_SERVER) && !defined(__WIN__)
143 if (!(test_flags & TEST_BLOCKING))
145 my_bool old_mode;
146 vio_blocking(vio, FALSE, &old_mode);
148 #endif
149 vio_fastsend(vio);
151 DBUG_RETURN(0);
155 void net_end(NET *net)
157 DBUG_ENTER("net_end");
158 my_free(net->buff,MYF(MY_ALLOW_ZERO_PTR));
159 net->buff=0;
160 DBUG_VOID_RETURN;
164 /** Realloc the packet buffer. */
166 my_bool net_realloc(NET *net, size_t length)
168 uchar *buff;
169 size_t pkt_length;
170 DBUG_ENTER("net_realloc");
171 DBUG_PRINT("enter",("length: %lu", (ulong) length));
173 if (length >= net->max_packet_size)
175 DBUG_PRINT("error", ("Packet too large. Max size: %lu",
176 net->max_packet_size));
177 /* @todo: 1 and 2 codes are identical. */
178 net->error= 1;
179 net->last_errno= ER_NET_PACKET_TOO_LARGE;
180 #ifdef MYSQL_SERVER
181 my_error(ER_NET_PACKET_TOO_LARGE, MYF(0));
182 #endif
183 DBUG_RETURN(1);
185 pkt_length = (length+IO_SIZE-1) & ~(IO_SIZE-1);
187 We must allocate some extra bytes for the end 0 and to be able to
188 read big compressed blocks + 1 safety byte since uint3korr() in
189 my_real_read() may actually read 4 bytes depending on build flags and
190 platform.
192 if (!(buff= (uchar*) my_realloc((char*) net->buff, pkt_length +
193 NET_HEADER_SIZE + COMP_HEADER_SIZE + 1,
194 MYF(MY_WME))))
196 /* @todo: 1 and 2 codes are identical. */
197 net->error= 1;
198 net->last_errno= ER_OUT_OF_RESOURCES;
199 /* In the server the error is reported by MY_WME flag. */
200 DBUG_RETURN(1);
202 net->buff=net->write_pos=buff;
203 net->buff_end=buff+(net->max_packet= (ulong) pkt_length);
204 DBUG_RETURN(0);
209 Check if there is any data to be read from the socket.
211 @param sd socket descriptor
213 @retval
214 0 No data to read
215 @retval
216 1 Data or EOF to read
217 @retval
218 -1 Don't know if data is ready or not
221 #if !defined(EMBEDDED_LIBRARY)
223 static int net_data_is_ready(my_socket sd)
225 #ifdef HAVE_POLL
226 struct pollfd ufds;
227 int res;
229 ufds.fd= sd;
230 ufds.events= POLLIN | POLLPRI;
231 if (!(res= poll(&ufds, 1, 0)))
232 return 0;
233 if (res < 0 || !(ufds.revents & (POLLIN | POLLPRI)))
234 return 0;
235 return 1;
236 #else
237 fd_set sfds;
238 struct timeval tv;
239 int res;
241 #ifndef __WIN__
242 /* Windows uses an _array_ of 64 fd's as default, so it's safe */
243 if (sd >= FD_SETSIZE)
244 return -1;
245 #define NET_DATA_IS_READY_CAN_RETURN_MINUS_ONE
246 #endif
248 FD_ZERO(&sfds);
249 FD_SET(sd, &sfds);
251 tv.tv_sec= tv.tv_usec= 0;
253 if ((res= select((int) (sd + 1), &sfds, NULL, NULL, &tv)) < 0)
254 return 0;
255 else
256 return test(res ? FD_ISSET(sd, &sfds) : 0);
257 #endif /* HAVE_POLL */
260 #endif /* EMBEDDED_LIBRARY */
263 Remove unwanted characters from connection
264 and check if disconnected.
266 Read from socket until there is nothing more to read. Discard
267 what is read.
269 If there is anything when to read 'net_clear' is called this
270 normally indicates an error in the protocol.
272 When connection is properly closed (for TCP it means with
273 a FIN packet), then select() considers a socket "ready to read",
274 in the sense that there's EOF to read, but read() returns 0.
276 @param net NET handler
277 @param clear_buffer if <> 0, then clear all data from comm buff
280 void net_clear(NET *net, my_bool clear_buffer)
282 #if !defined(EMBEDDED_LIBRARY)
283 size_t count;
284 int ready;
285 #endif
286 DBUG_ENTER("net_clear");
288 #if !defined(EMBEDDED_LIBRARY)
289 if (clear_buffer)
291 while ((ready= net_data_is_ready(net->vio->sd)) > 0)
293 /* The socket is ready */
294 if ((long) (count= vio_read(net->vio, net->buff,
295 (size_t) net->max_packet)) > 0)
297 DBUG_PRINT("info",("skipped %ld bytes from file: %s",
298 (long) count, vio_description(net->vio)));
299 #if defined(EXTRA_DEBUG)
300 fprintf(stderr,"Note: net_clear() skipped %ld bytes from file: %s\n",
301 (long) count, vio_description(net->vio));
302 #endif
304 else
306 DBUG_PRINT("info",("socket ready but only EOF to read - disconnected"));
307 net->error= 2;
308 break;
311 #ifdef NET_DATA_IS_READY_CAN_RETURN_MINUS_ONE
312 /* 'net_data_is_ready' returned "don't know" */
313 if (ready == -1)
315 /* Read unblocking to clear net */
316 my_bool old_mode;
317 if (!vio_blocking(net->vio, FALSE, &old_mode))
319 while ((long) (count= vio_read(net->vio, net->buff,
320 (size_t) net->max_packet)) > 0)
321 DBUG_PRINT("info",("skipped %ld bytes from file: %s",
322 (long) count, vio_description(net->vio)));
323 vio_blocking(net->vio, TRUE, &old_mode);
326 #endif /* NET_DATA_IS_READY_CAN_RETURN_MINUS_ONE */
328 #endif /* EMBEDDED_LIBRARY */
329 net->pkt_nr=net->compress_pkt_nr=0; /* Ready for new command */
330 net->write_pos=net->buff;
331 DBUG_VOID_RETURN;
335 /** Flush write_buffer if not empty. */
337 my_bool net_flush(NET *net)
339 my_bool error= 0;
340 DBUG_ENTER("net_flush");
341 if (net->buff != net->write_pos)
343 error=test(net_real_write(net, net->buff,
344 (size_t) (net->write_pos - net->buff)));
345 net->write_pos=net->buff;
347 /* Sync packet number if using compression */
348 if (net->compress)
349 net->pkt_nr=net->compress_pkt_nr;
350 DBUG_RETURN(error);
354 /*****************************************************************************
355 ** Write something to server/client buffer
356 *****************************************************************************/
359 Write a logical packet with packet header.
361 Format: Packet length (3 bytes), packet number(1 byte)
362 When compression is used a 3 byte compression length is added
364 @note
365 If compression is used the original package is modified!
368 my_bool
369 my_net_write(NET *net,const uchar *packet,size_t len)
371 uchar buff[NET_HEADER_SIZE];
372 if (unlikely(!net->vio)) /* nowhere to write */
373 return 0;
375 Big packets are handled by splitting them in packets of MAX_PACKET_LENGTH
376 length. The last packet is always a packet that is < MAX_PACKET_LENGTH.
377 (The last packet may even have a length of 0)
379 while (len >= MAX_PACKET_LENGTH)
381 const ulong z_size = MAX_PACKET_LENGTH;
382 int3store(buff, z_size);
383 buff[3]= (uchar) net->pkt_nr++;
384 if (net_write_buff(net, buff, NET_HEADER_SIZE) ||
385 net_write_buff(net, packet, z_size))
386 return 1;
387 packet += z_size;
388 len-= z_size;
390 /* Write last packet */
391 int3store(buff,len);
392 buff[3]= (uchar) net->pkt_nr++;
393 if (net_write_buff(net, buff, NET_HEADER_SIZE))
394 return 1;
395 #ifndef DEBUG_DATA_PACKETS
396 DBUG_DUMP("packet_header", buff, NET_HEADER_SIZE);
397 #endif
398 return test(net_write_buff(net,packet,len));
402 Send a command to the server.
404 The reason for having both header and packet is so that libmysql
405 can easy add a header to a special command (like prepared statements)
406 without having to re-alloc the string.
408 As the command is part of the first data packet, we have to do some data
409 juggling to put the command in there, without having to create a new
410 packet.
412 This function will split big packets into sub-packets if needed.
413 (Each sub packet can only be 2^24 bytes)
415 @param net NET handler
416 @param command Command in MySQL server (enum enum_server_command)
417 @param header Header to write after command
418 @param head_len Length of header
419 @param packet Query or parameter to query
420 @param len Length of packet
422 @retval
423 0 ok
424 @retval
425 1 error
428 my_bool
429 net_write_command(NET *net,uchar command,
430 const uchar *header, size_t head_len,
431 const uchar *packet, size_t len)
433 size_t length=len+1+head_len; /* 1 extra byte for command */
434 uchar buff[NET_HEADER_SIZE+1];
435 uint header_size=NET_HEADER_SIZE+1;
436 DBUG_ENTER("net_write_command");
437 DBUG_PRINT("enter",("length: %lu", (ulong) len));
439 buff[4]=command; /* For first packet */
441 if (length >= MAX_PACKET_LENGTH)
443 /* Take into account that we have the command in the first header */
444 len= MAX_PACKET_LENGTH - 1 - head_len;
447 int3store(buff, MAX_PACKET_LENGTH);
448 buff[3]= (uchar) net->pkt_nr++;
449 if (net_write_buff(net, buff, header_size) ||
450 net_write_buff(net, header, head_len) ||
451 net_write_buff(net, packet, len))
452 DBUG_RETURN(1);
453 packet+= len;
454 length-= MAX_PACKET_LENGTH;
455 len= MAX_PACKET_LENGTH;
456 head_len= 0;
457 header_size= NET_HEADER_SIZE;
458 } while (length >= MAX_PACKET_LENGTH);
459 len=length; /* Data left to be written */
461 int3store(buff,length);
462 buff[3]= (uchar) net->pkt_nr++;
463 DBUG_RETURN(test(net_write_buff(net, buff, header_size) ||
464 (head_len && net_write_buff(net, header, head_len)) ||
465 net_write_buff(net, packet, len) || net_flush(net)));
469 Caching the data in a local buffer before sending it.
471 Fill up net->buffer and send it to the client when full.
473 If the rest of the to-be-sent-packet is bigger than buffer,
474 send it in one big block (to avoid copying to internal buffer).
475 If not, copy the rest of the data to the buffer and return without
476 sending data.
478 @param net Network handler
479 @param packet Packet to send
480 @param len Length of packet
482 @note
483 The cached buffer can be sent as it is with 'net_flush()'.
484 In this code we have to be careful to not send a packet longer than
485 MAX_PACKET_LENGTH to net_real_write() if we are using the compressed
486 protocol as we store the length of the compressed packet in 3 bytes.
488 @retval
489 0 ok
490 @retval
494 static my_bool
495 net_write_buff(NET *net, const uchar *packet, ulong len)
497 ulong left_length;
498 if (net->compress && net->max_packet > MAX_PACKET_LENGTH)
499 left_length= (ulong) (MAX_PACKET_LENGTH - (net->write_pos - net->buff));
500 else
501 left_length= (ulong) (net->buff_end - net->write_pos);
503 #ifdef DEBUG_DATA_PACKETS
504 DBUG_DUMP("data", packet, len);
505 #endif
506 if (len > left_length)
508 if (net->write_pos != net->buff)
510 /* Fill up already used packet and write it */
511 memcpy((char*) net->write_pos,packet,left_length);
512 if (net_real_write(net, net->buff,
513 (size_t) (net->write_pos - net->buff) + left_length))
514 return 1;
515 net->write_pos= net->buff;
516 packet+= left_length;
517 len-= left_length;
519 if (net->compress)
522 We can't have bigger packets than 16M with compression
523 Because the uncompressed length is stored in 3 bytes
525 left_length= MAX_PACKET_LENGTH;
526 while (len > left_length)
528 if (net_real_write(net, packet, left_length))
529 return 1;
530 packet+= left_length;
531 len-= left_length;
534 if (len > net->max_packet)
535 return net_real_write(net, packet, len) ? 1 : 0;
536 /* Send out rest of the blocks as full sized blocks */
538 memcpy((char*) net->write_pos,packet,len);
539 net->write_pos+= len;
540 return 0;
545 Read and write one packet using timeouts.
546 If needed, the packet is compressed before sending.
548 @todo
549 - TODO is it needed to set this variable if we have no socket
553 net_real_write(NET *net,const uchar *packet, size_t len)
555 size_t length;
556 const uchar *pos,*end;
557 thr_alarm_t alarmed;
558 #ifndef NO_ALARM
559 ALARM alarm_buff;
560 #endif
561 uint retry_count=0;
562 my_bool net_blocking = vio_is_blocking(net->vio);
563 DBUG_ENTER("net_real_write");
565 #if defined(MYSQL_SERVER) && defined(USE_QUERY_CACHE)
566 query_cache_insert(net, (char*) packet, len);
567 #endif
569 if (net->error == 2)
570 DBUG_RETURN(-1); /* socket can't be used */
572 net->reading_or_writing=2;
573 #ifdef HAVE_COMPRESS
574 if (net->compress)
576 size_t complen;
577 uchar *b;
578 uint header_length=NET_HEADER_SIZE+COMP_HEADER_SIZE;
579 if (!(b= (uchar*) my_malloc(len + NET_HEADER_SIZE +
580 COMP_HEADER_SIZE, MYF(MY_WME))))
582 net->error= 2;
583 net->last_errno= ER_OUT_OF_RESOURCES;
584 /* In the server, the error is reported by MY_WME flag. */
585 net->reading_or_writing= 0;
586 DBUG_RETURN(1);
588 memcpy(b+header_length,packet,len);
590 if (my_compress(b+header_length, &len, &complen))
591 complen=0;
592 int3store(&b[NET_HEADER_SIZE],complen);
593 int3store(b,len);
594 b[3]=(uchar) (net->compress_pkt_nr++);
595 len+= header_length;
596 packet= b;
598 #endif /* HAVE_COMPRESS */
600 #ifdef DEBUG_DATA_PACKETS
601 DBUG_DUMP("data", packet, len);
602 #endif
604 #ifndef NO_ALARM
605 thr_alarm_init(&alarmed);
606 if (net_blocking)
607 thr_alarm(&alarmed, net->write_timeout, &alarm_buff);
608 #else
609 alarmed=0;
610 /* Write timeout is set in my_net_set_write_timeout */
611 #endif /* NO_ALARM */
613 pos= packet;
614 end=pos+len;
615 while (pos != end)
617 if ((long) (length= vio_write(net->vio,pos,(size_t) (end-pos))) <= 0)
619 my_bool interrupted = vio_should_retry(net->vio);
620 #if !defined(__WIN__)
621 if ((interrupted || length == 0) && !thr_alarm_in_use(&alarmed))
623 if (!thr_alarm(&alarmed, net->write_timeout, &alarm_buff))
624 { /* Always true for client */
625 my_bool old_mode;
626 while (vio_blocking(net->vio, TRUE, &old_mode) < 0)
628 if (vio_should_retry(net->vio) && retry_count++ < net->retry_count)
629 continue;
630 #ifdef EXTRA_DEBUG
631 fprintf(stderr,
632 "%s: my_net_write: fcntl returned error %d, aborting thread\n",
633 my_progname,vio_errno(net->vio));
634 #endif /* EXTRA_DEBUG */
635 net->error= 2; /* Close socket */
636 net->last_errno= ER_NET_PACKET_TOO_LARGE;
637 #ifdef MYSQL_SERVER
638 my_error(ER_NET_PACKET_TOO_LARGE, MYF(0));
639 #endif
640 goto end;
642 retry_count=0;
643 continue;
646 else
647 #endif /* !defined(__WIN__) */
648 if (thr_alarm_in_use(&alarmed) && !thr_got_alarm(&alarmed) &&
649 interrupted)
651 if (retry_count++ < net->retry_count)
652 continue;
653 #ifdef EXTRA_DEBUG
654 fprintf(stderr, "%s: write looped, aborting thread\n",
655 my_progname);
656 #endif /* EXTRA_DEBUG */
658 #if defined(THREAD_SAFE_CLIENT) && !defined(MYSQL_SERVER)
659 if (vio_errno(net->vio) == SOCKET_EINTR)
661 DBUG_PRINT("warning",("Interrupted write. Retrying..."));
662 continue;
664 #endif /* defined(THREAD_SAFE_CLIENT) && !defined(MYSQL_SERVER) */
665 net->error= 2; /* Close socket */
666 net->last_errno= (interrupted ? ER_NET_WRITE_INTERRUPTED :
667 ER_NET_ERROR_ON_WRITE);
668 #ifdef MYSQL_SERVER
669 my_error(net->last_errno, MYF(0));
670 #endif /* MYSQL_SERVER */
671 break;
673 pos+=length;
674 update_statistics(thd_increment_bytes_sent(length));
676 #ifndef __WIN__
677 end:
678 #endif
679 #ifdef HAVE_COMPRESS
680 if (net->compress)
681 my_free((char*) packet,MYF(0));
682 #endif
683 if (thr_alarm_in_use(&alarmed))
685 my_bool old_mode;
686 thr_end_alarm(&alarmed);
687 vio_blocking(net->vio, net_blocking, &old_mode);
689 net->reading_or_writing=0;
690 DBUG_RETURN(((int) (pos != end)));
694 /*****************************************************************************
695 ** Read something from server/clinet
696 *****************************************************************************/
698 #ifndef NO_ALARM
700 static my_bool net_safe_read(NET *net, uchar *buff, size_t length,
701 thr_alarm_t *alarmed)
703 uint retry_count=0;
704 while (length > 0)
706 size_t tmp;
707 if ((long) (tmp= vio_read(net->vio, buff, length)) <= 0)
709 my_bool interrupted = vio_should_retry(net->vio);
710 if (!thr_got_alarm(alarmed) && interrupted)
711 { /* Probably in MIT threads */
712 if (retry_count++ < net->retry_count)
713 continue;
715 return 1;
717 length-= tmp;
718 buff+= tmp;
720 return 0;
724 Help function to clear the commuication buffer when we get a too big packet.
726 @param net Communication handle
727 @param remain Bytes to read
728 @param alarmed Parameter for thr_alarm()
729 @param alarm_buff Parameter for thr_alarm()
731 @retval
732 0 Was able to read the whole packet
733 @retval
734 1 Got mailformed packet from client
737 static my_bool my_net_skip_rest(NET *net, uint32 remain, thr_alarm_t *alarmed,
738 ALARM *alarm_buff)
740 uint32 old=remain;
741 DBUG_ENTER("my_net_skip_rest");
742 DBUG_PRINT("enter",("bytes_to_skip: %u", (uint) remain));
744 /* The following is good for debugging */
745 update_statistics(thd_increment_net_big_packet_count(1));
747 if (!thr_alarm_in_use(alarmed))
749 my_bool old_mode;
750 if (thr_alarm(alarmed,net->read_timeout, alarm_buff) ||
751 vio_blocking(net->vio, TRUE, &old_mode) < 0)
752 DBUG_RETURN(1); /* Can't setup, abort */
754 for (;;)
756 while (remain > 0)
758 size_t length= min(remain, net->max_packet);
759 if (net_safe_read(net, net->buff, length, alarmed))
760 DBUG_RETURN(1);
761 update_statistics(thd_increment_bytes_received(length));
762 remain -= (uint32) length;
764 if (old != MAX_PACKET_LENGTH)
765 break;
766 if (net_safe_read(net, net->buff, NET_HEADER_SIZE, alarmed))
767 DBUG_RETURN(1);
768 old=remain= uint3korr(net->buff);
769 net->pkt_nr++;
771 DBUG_RETURN(0);
773 #endif /* NO_ALARM */
777 Reads one packet to net->buff + net->where_b.
778 Long packets are handled by my_net_read().
779 This function reallocates the net->buff buffer if necessary.
781 @return
782 Returns length of packet.
785 static ulong
786 my_real_read(NET *net, size_t *complen)
788 uchar *pos;
789 size_t length;
790 uint i,retry_count=0;
791 ulong len=packet_error;
792 thr_alarm_t alarmed;
793 #ifndef NO_ALARM
794 ALARM alarm_buff;
795 #endif
796 my_bool net_blocking=vio_is_blocking(net->vio);
797 uint32 remain= (net->compress ? NET_HEADER_SIZE+COMP_HEADER_SIZE :
798 NET_HEADER_SIZE);
799 *complen = 0;
801 net->reading_or_writing=1;
802 thr_alarm_init(&alarmed);
803 #ifndef NO_ALARM
804 if (net_blocking)
805 thr_alarm(&alarmed,net->read_timeout,&alarm_buff);
806 #else
807 /* Read timeout is set in my_net_set_read_timeout */
808 #endif /* NO_ALARM */
810 pos = net->buff + net->where_b; /* net->packet -4 */
811 for (i=0 ; i < 2 ; i++)
813 while (remain > 0)
815 /* First read is done with non blocking mode */
816 if ((long) (length= vio_read(net->vio, pos, remain)) <= 0L)
818 my_bool interrupted = vio_should_retry(net->vio);
820 DBUG_PRINT("info",("vio_read returned %ld errno: %d",
821 (long) length, vio_errno(net->vio)));
822 #if !defined(__WIN__) || defined(MYSQL_SERVER)
824 We got an error that there was no data on the socket. We now set up
825 an alarm to not 'read forever', change the socket to non blocking
826 mode and try again
828 if ((interrupted || length == 0) && !thr_alarm_in_use(&alarmed))
830 if (!thr_alarm(&alarmed,net->read_timeout,&alarm_buff)) /* Don't wait too long */
832 my_bool old_mode;
833 while (vio_blocking(net->vio, TRUE, &old_mode) < 0)
835 if (vio_should_retry(net->vio) &&
836 retry_count++ < net->retry_count)
837 continue;
838 DBUG_PRINT("error",
839 ("fcntl returned error %d, aborting thread",
840 vio_errno(net->vio)));
841 #ifdef EXTRA_DEBUG
842 fprintf(stderr,
843 "%s: read: fcntl returned error %d, aborting thread\n",
844 my_progname,vio_errno(net->vio));
845 #endif /* EXTRA_DEBUG */
846 len= packet_error;
847 net->error= 2; /* Close socket */
848 net->last_errno= ER_NET_FCNTL_ERROR;
849 #ifdef MYSQL_SERVER
850 my_error(ER_NET_FCNTL_ERROR, MYF(0));
851 #endif
852 goto end;
854 retry_count=0;
855 continue;
858 #endif /* (!defined(__WIN__) || defined(MYSQL_SERVER) */
859 if (thr_alarm_in_use(&alarmed) && !thr_got_alarm(&alarmed) &&
860 interrupted)
861 { /* Probably in MIT threads */
862 if (retry_count++ < net->retry_count)
863 continue;
864 #ifdef EXTRA_DEBUG
865 fprintf(stderr, "%s: read looped with error %d, aborting thread\n",
866 my_progname,vio_errno(net->vio));
867 #endif /* EXTRA_DEBUG */
869 #if defined(THREAD_SAFE_CLIENT) && !defined(MYSQL_SERVER)
870 if (vio_errno(net->vio) == SOCKET_EINTR)
872 DBUG_PRINT("warning",("Interrupted read. Retrying..."));
873 continue;
875 #endif
876 DBUG_PRINT("error",("Couldn't read packet: remain: %u errno: %d length: %ld",
877 remain, vio_errno(net->vio), (long) length));
878 len= packet_error;
879 net->error= 2; /* Close socket */
880 net->last_errno= (vio_was_interrupted(net->vio) ?
881 ER_NET_READ_INTERRUPTED :
882 ER_NET_READ_ERROR);
883 #ifdef MYSQL_SERVER
884 my_error(net->last_errno, MYF(0));
885 #endif
886 goto end;
888 remain -= (uint32) length;
889 pos+= length;
890 update_statistics(thd_increment_bytes_received(length));
892 if (i == 0)
893 { /* First parts is packet length */
894 ulong helping;
895 DBUG_DUMP("packet_header", net->buff+net->where_b,
896 NET_HEADER_SIZE);
897 if (net->buff[net->where_b + 3] != (uchar) net->pkt_nr)
899 if (net->buff[net->where_b] != (uchar) 255)
901 DBUG_PRINT("error",
902 ("Packets out of order (Found: %d, expected %u)",
903 (int) net->buff[net->where_b + 3],
904 net->pkt_nr));
906 We don't make noise server side, since the client is expected
907 to break the protocol for e.g. --send LOAD DATA .. LOCAL where
908 the server expects the client to send a file, but the client
909 may reply with a new command instead.
911 #if defined (EXTRA_DEBUG) && !defined (MYSQL_SERVER)
912 fflush(stdout);
913 fprintf(stderr,"Error: Packets out of order (Found: %d, expected %d)\n",
914 (int) net->buff[net->where_b + 3],
915 (uint) (uchar) net->pkt_nr);
916 fflush(stderr);
917 DBUG_ASSERT(0);
918 #endif
920 len= packet_error;
921 /* Not a NET error on the client. XXX: why? */
922 #ifdef MYSQL_SERVER
923 my_error(ER_NET_PACKETS_OUT_OF_ORDER, MYF(0));
924 #endif
925 goto end;
927 net->compress_pkt_nr= ++net->pkt_nr;
928 #ifdef HAVE_COMPRESS
929 if (net->compress)
932 The following uint3korr() may read 4 bytes, so make sure we don't
933 read unallocated or uninitialized memory. The right-hand expression
934 must match the size of the buffer allocated in net_realloc().
936 DBUG_ASSERT(net->where_b + NET_HEADER_SIZE + sizeof(uint32) <=
937 net->max_packet + NET_HEADER_SIZE + COMP_HEADER_SIZE + 1);
939 If the packet is compressed then complen > 0 and contains the
940 number of bytes in the uncompressed packet
942 *complen=uint3korr(&(net->buff[net->where_b + NET_HEADER_SIZE]));
944 #endif
946 len=uint3korr(net->buff+net->where_b);
947 if (!len) /* End of big multi-packet */
948 goto end;
949 helping = max(len,*complen) + net->where_b;
950 /* The necessary size of net->buff */
951 if (helping >= net->max_packet)
953 if (net_realloc(net,helping))
955 #if defined(MYSQL_SERVER) && !defined(NO_ALARM)
956 if (!net->compress &&
957 net->skip_big_packet &&
958 !my_net_skip_rest(net, (uint32) len, &alarmed, &alarm_buff))
959 net->error= 3; /* Successfully skiped packet */
960 #endif
961 len= packet_error; /* Return error and close connection */
962 goto end;
965 pos=net->buff + net->where_b;
966 remain = (uint32) len;
970 end:
971 if (thr_alarm_in_use(&alarmed))
973 my_bool old_mode;
974 thr_end_alarm(&alarmed);
975 vio_blocking(net->vio, net_blocking, &old_mode);
977 net->reading_or_writing=0;
978 #ifdef DEBUG_DATA_PACKETS
979 if (len != packet_error)
980 DBUG_DUMP("data", net->buff+net->where_b, len);
981 #endif
982 return(len);
987 Read a packet from the client/server and return it without the internal
988 package header.
990 If the packet is the first packet of a multi-packet packet
991 (which is indicated by the length of the packet = 0xffffff) then
992 all sub packets are read and concatenated.
994 If the packet was compressed, its uncompressed and the length of the
995 uncompressed packet is returned.
997 @return
998 The function returns the length of the found packet or packet_error.
999 net->read_pos points to the read data.
1002 ulong
1003 my_net_read(NET *net)
1005 size_t len, complen;
1007 #ifdef HAVE_COMPRESS
1008 if (!net->compress)
1010 #endif
1011 len = my_real_read(net,&complen);
1012 if (len == MAX_PACKET_LENGTH)
1014 /* First packet of a multi-packet. Concatenate the packets */
1015 ulong save_pos = net->where_b;
1016 size_t total_length= 0;
1019 net->where_b += len;
1020 total_length += len;
1021 len = my_real_read(net,&complen);
1022 } while (len == MAX_PACKET_LENGTH);
1023 if (len != packet_error)
1024 len+= total_length;
1025 net->where_b = save_pos;
1027 net->read_pos = net->buff + net->where_b;
1028 if (len != packet_error)
1029 net->read_pos[len]=0; /* Safeguard for mysql_use_result */
1030 return len;
1031 #ifdef HAVE_COMPRESS
1033 else
1035 /* We are using the compressed protocol */
1037 ulong buf_length;
1038 ulong start_of_packet;
1039 ulong first_packet_offset;
1040 uint read_length, multi_byte_packet=0;
1042 if (net->remain_in_buf)
1044 buf_length= net->buf_length; /* Data left in old packet */
1045 first_packet_offset= start_of_packet= (net->buf_length -
1046 net->remain_in_buf);
1047 /* Restore the character that was overwritten by the end 0 */
1048 net->buff[start_of_packet]= net->save_char;
1050 else
1052 /* reuse buffer, as there is nothing in it that we need */
1053 buf_length= start_of_packet= first_packet_offset= 0;
1055 for (;;)
1057 ulong packet_len;
1059 if (buf_length - start_of_packet >= NET_HEADER_SIZE)
1061 read_length = uint3korr(net->buff+start_of_packet);
1062 if (!read_length)
1064 /* End of multi-byte packet */
1065 start_of_packet += NET_HEADER_SIZE;
1066 break;
1068 if (read_length + NET_HEADER_SIZE <= buf_length - start_of_packet)
1070 if (multi_byte_packet)
1072 /* Remove packet header for second packet */
1073 memmove(net->buff + first_packet_offset + start_of_packet,
1074 net->buff + first_packet_offset + start_of_packet +
1075 NET_HEADER_SIZE,
1076 buf_length - start_of_packet);
1077 start_of_packet += read_length;
1078 buf_length -= NET_HEADER_SIZE;
1080 else
1081 start_of_packet+= read_length + NET_HEADER_SIZE;
1083 if (read_length != MAX_PACKET_LENGTH) /* last package */
1085 multi_byte_packet= 0; /* No last zero len packet */
1086 break;
1088 multi_byte_packet= NET_HEADER_SIZE;
1089 /* Move data down to read next data packet after current one */
1090 if (first_packet_offset)
1092 memmove(net->buff,net->buff+first_packet_offset,
1093 buf_length-first_packet_offset);
1094 buf_length-=first_packet_offset;
1095 start_of_packet -= first_packet_offset;
1096 first_packet_offset=0;
1098 continue;
1101 /* Move data down to read next data packet after current one */
1102 if (first_packet_offset)
1104 memmove(net->buff,net->buff+first_packet_offset,
1105 buf_length-first_packet_offset);
1106 buf_length-=first_packet_offset;
1107 start_of_packet -= first_packet_offset;
1108 first_packet_offset=0;
1111 net->where_b=buf_length;
1112 if ((packet_len = my_real_read(net,&complen)) == packet_error)
1113 return packet_error;
1114 if (my_uncompress(net->buff + net->where_b, packet_len,
1115 &complen))
1117 net->error= 2; /* caller will close socket */
1118 net->last_errno= ER_NET_UNCOMPRESS_ERROR;
1119 #ifdef MYSQL_SERVER
1120 my_error(ER_NET_UNCOMPRESS_ERROR, MYF(0));
1121 #endif
1122 return packet_error;
1124 buf_length+= complen;
1127 net->read_pos= net->buff+ first_packet_offset + NET_HEADER_SIZE;
1128 net->buf_length= buf_length;
1129 net->remain_in_buf= (ulong) (buf_length - start_of_packet);
1130 len = ((ulong) (start_of_packet - first_packet_offset) - NET_HEADER_SIZE -
1131 multi_byte_packet);
1132 net->save_char= net->read_pos[len]; /* Must be saved */
1133 net->read_pos[len]=0; /* Safeguard for mysql_use_result */
1135 #endif /* HAVE_COMPRESS */
1136 return len;
1140 void my_net_set_read_timeout(NET *net, uint timeout)
1142 DBUG_ENTER("my_net_set_read_timeout");
1143 DBUG_PRINT("enter", ("timeout: %d", timeout));
1144 net->read_timeout= timeout;
1145 #ifdef NO_ALARM
1146 if (net->vio)
1147 vio_timeout(net->vio, 0, timeout);
1148 #endif
1149 DBUG_VOID_RETURN;
1153 void my_net_set_write_timeout(NET *net, uint timeout)
1155 DBUG_ENTER("my_net_set_write_timeout");
1156 DBUG_PRINT("enter", ("timeout: %d", timeout));
1157 net->write_timeout= timeout;
1158 #ifdef NO_ALARM
1159 if (net->vio)
1160 vio_timeout(net->vio, 1, timeout);
1161 #endif
1162 DBUG_VOID_RETURN;