1
/* Copyright (C) 2000 MySQL AB
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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
17
HFTODO this must be hidden if we don't want client capabilities in
20
#include <my_global.h>
22
#include <mysql_embed.h>
23
#include <mysql_com.h>
24
#include <mysqld_error.h>
33
The following handles the differences when this is linked between the
34
client and the server.
36
This gives an error if a too big packet is found
37
The server can change this with the -O switch, but because the client
38
can't normally do this the client should have a bigger max_allowed_packet.
41
#if !defined(MYSQL_SERVER)
46
#include "my_pthread.h"
47
void sql_print_error(const char *format,...);
49
#define DONT_USE_THR_ALARM
52
#include "thr_alarm.h"
56
The following variables/functions should really not be declared
57
extern, but as it's hard to include mysql_priv.h here, we have to
58
live with this for a while.
60
extern uint test_flags;
61
extern ulong bytes_sent, bytes_received, net_big_packet_count;
62
extern pthread_mutex_t LOCK_bytes_sent , LOCK_bytes_received;
63
#ifndef MYSQL_INSTANCE_MANAGER
64
#define update_statistics(A) A
65
#endif /* MYSQL_INSTANCE_MANGER */
66
#endif /* defined(MYSQL_SERVER) && !defined(MYSQL_INSTANCE_MANAGER) */
68
#if !defined(MYSQL_SERVER) || defined(MYSQL_INSTANCE_MANAGER)
69
#define update_statistics(A)
70
#define thd_increment_bytes_sent(N)
73
#define TEST_BLOCKING 8
74
#define MAX_PACKET_LENGTH (256L*256L*256L-1)
76
static my_bool net_write_buff(NET *net,const uchar *packet,ulong len);
79
/** Init with packet info. */
81
my_bool my_net_init(NET *net, Vio* vio)
83
DBUG_ENTER("my_net_init");
85
my_net_local_init(net); /* Set some limits */
86
if (!(net->buff=(uchar*) my_malloc((size_t) net->max_packet+
87
NET_HEADER_SIZE + COMP_HEADER_SIZE,
90
net->buff_end=net->buff+net->max_packet;
91
net->error=0; net->return_status=0;
92
net->pkt_nr=net->compress_pkt_nr=0;
93
net->write_pos=net->read_pos = net->buff;
95
net->compress=0; net->reading_or_writing=0;
96
net->where_b = net->remain_in_buf=0;
100
if (vio != 0) /* If real connection */
102
net->fd = vio_fd(vio); /* For perl DBI/DBD */
103
#if defined(MYSQL_SERVER)
104
if (!(test_flags & TEST_BLOCKING))
107
vio_blocking(vio, FALSE, &old_mode);
116
void net_end(NET *net)
118
DBUG_ENTER("net_end");
119
my_free(net->buff,MYF(MY_ALLOW_ZERO_PTR));
125
/** Realloc the packet buffer. */
127
my_bool net_realloc(NET *net, size_t length)
131
DBUG_ENTER("net_realloc");
132
DBUG_PRINT("enter",("length: %lu", (ulong) length));
134
if (length >= net->max_packet_size)
136
DBUG_PRINT("error", ("Packet too large. Max size: %lu",
137
net->max_packet_size));
138
/* @todo: 1 and 2 codes are identical. */
140
net->last_errno= ER_NET_PACKET_TOO_LARGE;
142
my_error(ER_NET_PACKET_TOO_LARGE, MYF(0));
146
pkt_length = (length+IO_SIZE-1) & ~(IO_SIZE-1);
148
We must allocate some extra bytes for the end 0 and to be able to
149
read big compressed blocks
151
if (!(buff= (uchar*) my_realloc((char*) net->buff, pkt_length +
152
NET_HEADER_SIZE + COMP_HEADER_SIZE,
155
/* @todo: 1 and 2 codes are identical. */
157
net->last_errno= ER_OUT_OF_RESOURCES;
158
/* In the server the error is reported by MY_WME flag. */
161
net->buff=net->write_pos=buff;
162
net->buff_end=buff+(net->max_packet= (ulong) pkt_length);
168
Check if there is any data to be read from the socket.
170
@param sd socket descriptor
175
1 Data or EOF to read
177
-1 Don't know if data is ready or not
180
static int net_data_is_ready(my_socket sd)
187
ufds.events= POLLIN | POLLPRI;
188
if (!(res= poll(&ufds, 1, 0)))
190
if (res < 0 || !(ufds.revents & (POLLIN | POLLPRI)))
198
/* Windows uses an _array_ of 64 fd's as default, so it's safe */
199
if (sd >= FD_SETSIZE)
201
#define NET_DATA_IS_READY_CAN_RETURN_MINUS_ONE
206
tv.tv_sec= tv.tv_usec= 0;
208
if ((res= select(sd+1, &sfds, NULL, NULL, &tv)) < 0)
211
return test(res ? FD_ISSET(sd, &sfds) : 0);
212
#endif /* HAVE_POLL */
216
Remove unwanted characters from connection
217
and check if disconnected.
219
Read from socket until there is nothing more to read. Discard
222
If there is anything when to read 'net_clear' is called this
223
normally indicates an error in the protocol.
225
When connection is properly closed (for TCP it means with
226
a FIN packet), then select() considers a socket "ready to read",
227
in the sense that there's EOF to read, but read() returns 0.
229
@param net NET handler
230
@param clear_buffer if <> 0, then clear all data from comm buff
233
void net_clear(NET *net, my_bool clear_buffer)
237
DBUG_ENTER("net_clear");
241
while ((ready= net_data_is_ready(net->vio->sd)) > 0)
243
/* The socket is ready */
244
if ((long) (count= vio_read(net->vio, net->buff,
245
(size_t) net->max_packet)) > 0)
247
DBUG_PRINT("info",("skipped %ld bytes from file: %s",
248
(long) count, vio_description(net->vio)));
252
DBUG_PRINT("info",("socket ready but only EOF to read - disconnected"));
257
#ifdef NET_DATA_IS_READY_CAN_RETURN_MINUS_ONE
258
/* 'net_data_is_ready' returned "don't know" */
261
/* Read unblocking to clear net */
263
if (!vio_blocking(net->vio, FALSE, &old_mode))
265
while ((long) (count= vio_read(net->vio, net->buff,
266
(size_t) net->max_packet)) > 0)
267
DBUG_PRINT("info",("skipped %ld bytes from file: %s",
268
(long) count, vio_description(net->vio)));
269
vio_blocking(net->vio, TRUE, &old_mode);
272
#endif /* NET_DATA_IS_READY_CAN_RETURN_MINUS_ONE */
274
net->pkt_nr=net->compress_pkt_nr=0; /* Ready for new command */
275
net->write_pos=net->buff;
280
/** Flush write_buffer if not empty. */
282
my_bool net_flush(NET *net)
285
DBUG_ENTER("net_flush");
286
if (net->buff != net->write_pos)
288
error=test(net_real_write(net, net->buff,
289
(size_t) (net->write_pos - net->buff)));
290
net->write_pos=net->buff;
292
/* Sync packet number if using compression */
294
net->pkt_nr=net->compress_pkt_nr;
299
/*****************************************************************************
300
** Write something to server/client buffer
301
*****************************************************************************/
304
Write a logical packet with packet header.
306
Format: Packet length (3 bytes), packet number(1 byte)
307
When compression is used a 3 byte compression length is added
310
If compression is used the original package is modified!
314
my_net_write(NET *net,const uchar *packet,size_t len)
316
uchar buff[NET_HEADER_SIZE];
317
if (unlikely(!net->vio)) /* nowhere to write */
320
Big packets are handled by splitting them in packets of MAX_PACKET_LENGTH
321
length. The last packet is always a packet that is < MAX_PACKET_LENGTH.
322
(The last packet may even have a length of 0)
324
while (len >= MAX_PACKET_LENGTH)
326
const ulong z_size = MAX_PACKET_LENGTH;
327
int3store(buff, z_size);
328
buff[3]= (uchar) net->pkt_nr++;
329
if (net_write_buff(net, buff, NET_HEADER_SIZE) ||
330
net_write_buff(net, packet, z_size))
335
/* Write last packet */
337
buff[3]= (uchar) net->pkt_nr++;
338
if (net_write_buff(net, buff, NET_HEADER_SIZE))
340
#ifndef DEBUG_DATA_PACKETS
341
DBUG_DUMP("packet_header", buff, NET_HEADER_SIZE);
343
return test(net_write_buff(net,packet,len));
347
Send a command to the server.
349
The reason for having both header and packet is so that libmysql
350
can easy add a header to a special command (like prepared statements)
351
without having to re-alloc the string.
353
As the command is part of the first data packet, we have to do some data
354
juggling to put the command in there, without having to create a new
357
This function will split big packets into sub-packets if needed.
358
(Each sub packet can only be 2^24 bytes)
360
@param net NET handler
361
@param command Command in MySQL server (enum enum_server_command)
362
@param header Header to write after command
363
@param head_len Length of header
364
@param packet Query or parameter to query
365
@param len Length of packet
374
net_write_command(NET *net,uchar command,
375
const uchar *header, size_t head_len,
376
const uchar *packet, size_t len)
378
ulong length=len+1+head_len; /* 1 extra byte for command */
379
uchar buff[NET_HEADER_SIZE+1];
380
uint header_size=NET_HEADER_SIZE+1;
381
DBUG_ENTER("net_write_command");
382
DBUG_PRINT("enter",("length: %lu", (ulong) len));
384
buff[4]=command; /* For first packet */
386
if (length >= MAX_PACKET_LENGTH)
388
/* Take into account that we have the command in the first header */
389
len= MAX_PACKET_LENGTH - 1 - head_len;
392
int3store(buff, MAX_PACKET_LENGTH);
393
buff[3]= (uchar) net->pkt_nr++;
394
if (net_write_buff(net, buff, header_size) ||
395
net_write_buff(net, header, head_len) ||
396
net_write_buff(net, packet, len))
399
length-= MAX_PACKET_LENGTH;
400
len= MAX_PACKET_LENGTH;
402
header_size= NET_HEADER_SIZE;
403
} while (length >= MAX_PACKET_LENGTH);
404
len=length; /* Data left to be written */
406
int3store(buff,length);
407
buff[3]= (uchar) net->pkt_nr++;
408
DBUG_RETURN(test(net_write_buff(net, buff, header_size) ||
409
(head_len && net_write_buff(net, header, head_len)) ||
410
net_write_buff(net, packet, len) || net_flush(net)));
414
Caching the data in a local buffer before sending it.
416
Fill up net->buffer and send it to the client when full.
418
If the rest of the to-be-sent-packet is bigger than buffer,
419
send it in one big block (to avoid copying to internal buffer).
420
If not, copy the rest of the data to the buffer and return without
423
@param net Network handler
424
@param packet Packet to send
425
@param len Length of packet
428
The cached buffer can be sent as it is with 'net_flush()'.
429
In this code we have to be careful to not send a packet longer than
430
MAX_PACKET_LENGTH to net_real_write() if we are using the compressed
431
protocol as we store the length of the compressed packet in 3 bytes.
440
net_write_buff(NET *net, const uchar *packet, ulong len)
443
if (net->compress && net->max_packet > MAX_PACKET_LENGTH)
444
left_length= MAX_PACKET_LENGTH - (net->write_pos - net->buff);
446
left_length= (ulong) (net->buff_end - net->write_pos);
448
#ifdef DEBUG_DATA_PACKETS
449
DBUG_DUMP("data", packet, len);
451
if (len > left_length)
453
if (net->write_pos != net->buff)
455
/* Fill up already used packet and write it */
456
memcpy((char*) net->write_pos,packet,left_length);
457
if (net_real_write(net, net->buff,
458
(size_t) (net->write_pos - net->buff) + left_length))
460
net->write_pos= net->buff;
461
packet+= left_length;
467
We can't have bigger packets than 16M with compression
468
Because the uncompressed length is stored in 3 bytes
470
left_length= MAX_PACKET_LENGTH;
471
while (len > left_length)
473
if (net_real_write(net, packet, left_length))
475
packet+= left_length;
479
if (len > net->max_packet)
480
return net_real_write(net, packet, len) ? 1 : 0;
481
/* Send out rest of the blocks as full sized blocks */
483
memcpy((char*) net->write_pos,packet,len);
484
net->write_pos+= len;
490
Read and write one packet using timeouts.
491
If needed, the packet is compressed before sending.
494
- TODO is it needed to set this variable if we have no socket
498
net_real_write(NET *net,const uchar *packet, size_t len)
501
const uchar *pos,*end;
507
my_bool net_blocking = vio_is_blocking(net->vio);
508
DBUG_ENTER("net_real_write");
510
#if defined(MYSQL_SERVER) && defined(USE_QUERY_CACHE)
511
query_cache_insert((char*) packet, len, net->pkt_nr);
515
DBUG_RETURN(-1); /* socket can't be used */
517
net->reading_or_writing=2;
522
uint header_length=NET_HEADER_SIZE+COMP_HEADER_SIZE;
523
if (!(b= (uchar*) my_malloc(len + NET_HEADER_SIZE +
524
COMP_HEADER_SIZE, MYF(MY_WME))))
527
net->last_errno= ER_OUT_OF_RESOURCES;
528
/* In the server, the error is reported by MY_WME flag. */
529
net->reading_or_writing= 0;
532
memcpy(b+header_length,packet,len);
534
if (my_compress(b+header_length, &len, &complen))
536
int3store(&b[NET_HEADER_SIZE],complen);
538
b[3]=(uchar) (net->compress_pkt_nr++);
543
#ifdef DEBUG_DATA_PACKETS
544
DBUG_DUMP("data", packet, len);
548
thr_alarm_init(&alarmed);
550
thr_alarm(&alarmed, net->write_timeout, &alarm_buff);
553
/* Write timeout is set in my_net_set_write_timeout */
554
#endif /* NO_ALARM */
560
if ((long) (length= vio_write(net->vio,pos,(size_t) (end-pos))) <= 0)
562
my_bool interrupted = vio_should_retry(net->vio);
563
if ((interrupted || length == 0) && !thr_alarm_in_use(&alarmed))
565
if (!thr_alarm(&alarmed, net->write_timeout, &alarm_buff))
566
{ /* Always true for client */
568
while (vio_blocking(net->vio, TRUE, &old_mode) < 0)
570
if (vio_should_retry(net->vio) && retry_count++ < net->retry_count)
574
"%s: my_net_write: fcntl returned error %d, aborting thread\n",
575
my_progname,vio_errno(net->vio));
576
#endif /* EXTRA_DEBUG */
577
net->error= 2; /* Close socket */
578
net->last_errno= ER_NET_PACKET_TOO_LARGE;
580
my_error(ER_NET_PACKET_TOO_LARGE, MYF(0));
589
if (thr_alarm_in_use(&alarmed) && !thr_got_alarm(&alarmed) &&
592
if (retry_count++ < net->retry_count)
595
fprintf(stderr, "%s: write looped, aborting thread\n",
597
#endif /* EXTRA_DEBUG */
599
#if defined(THREAD_SAFE_CLIENT) && !defined(MYSQL_SERVER)
600
if (vio_errno(net->vio) == SOCKET_EINTR)
602
DBUG_PRINT("warning",("Interrupted write. Retrying..."));
605
#endif /* defined(THREAD_SAFE_CLIENT) && !defined(MYSQL_SERVER) */
606
net->error= 2; /* Close socket */
607
net->last_errno= (interrupted ? ER_NET_WRITE_INTERRUPTED :
608
ER_NET_ERROR_ON_WRITE);
610
my_error(net->last_errno, MYF(0));
611
#endif /* MYSQL_SERVER */
615
update_statistics(thd_increment_bytes_sent(length));
619
my_free((char*) packet,MYF(0));
620
if (thr_alarm_in_use(&alarmed))
623
thr_end_alarm(&alarmed);
624
vio_blocking(net->vio, net_blocking, &old_mode);
626
net->reading_or_writing=0;
627
DBUG_RETURN(((int) (pos != end)));
631
/*****************************************************************************
632
** Read something from server/clinet
633
*****************************************************************************/
637
static my_bool net_safe_read(NET *net, uchar *buff, size_t length,
638
thr_alarm_t *alarmed)
644
if ((long) (tmp= vio_read(net->vio, buff, length)) <= 0)
646
my_bool interrupted = vio_should_retry(net->vio);
647
if (!thr_got_alarm(alarmed) && interrupted)
648
{ /* Probably in MIT threads */
649
if (retry_count++ < net->retry_count)
661
Help function to clear the commuication buffer when we get a too big packet.
663
@param net Communication handle
664
@param remain Bytes to read
665
@param alarmed Parameter for thr_alarm()
666
@param alarm_buff Parameter for thr_alarm()
669
0 Was able to read the whole packet
671
1 Got mailformed packet from client
674
static my_bool my_net_skip_rest(NET *net, uint32 remain, thr_alarm_t *alarmed,
678
DBUG_ENTER("my_net_skip_rest");
679
DBUG_PRINT("enter",("bytes_to_skip: %u", (uint) remain));
681
/* The following is good for debugging */
682
update_statistics(thd_increment_net_big_packet_count(1));
684
if (!thr_alarm_in_use(alarmed))
687
if (thr_alarm(alarmed,net->read_timeout, alarm_buff) ||
688
vio_blocking(net->vio, TRUE, &old_mode) < 0)
689
DBUG_RETURN(1); /* Can't setup, abort */
695
size_t length= min(remain, net->max_packet);
696
if (net_safe_read(net, net->buff, length, alarmed))
698
update_statistics(thd_increment_bytes_received(length));
699
remain -= (uint32) length;
701
if (old != MAX_PACKET_LENGTH)
703
if (net_safe_read(net, net->buff, NET_HEADER_SIZE, alarmed))
705
old=remain= uint3korr(net->buff);
710
#endif /* NO_ALARM */
714
Reads one packet to net->buff + net->where_b.
715
Long packets are handled by my_net_read().
716
This function reallocates the net->buff buffer if necessary.
719
Returns length of packet.
723
my_real_read(NET *net, size_t *complen)
727
uint i,retry_count=0;
728
ulong len=packet_error;
733
my_bool net_blocking=vio_is_blocking(net->vio);
734
uint32 remain= (net->compress ? NET_HEADER_SIZE+COMP_HEADER_SIZE :
738
net->reading_or_writing=1;
739
thr_alarm_init(&alarmed);
742
thr_alarm(&alarmed,net->read_timeout,&alarm_buff);
744
/* Read timeout is set in my_net_set_read_timeout */
745
#endif /* NO_ALARM */
747
pos = net->buff + net->where_b; /* net->packet -4 */
748
for (i=0 ; i < 2 ; i++)
752
/* First read is done with non blocking mode */
753
if ((long) (length= vio_read(net->vio, pos, remain)) <= 0L)
755
my_bool interrupted = vio_should_retry(net->vio);
757
DBUG_PRINT("info",("vio_read returned %ld errno: %d",
758
(long) length, vio_errno(net->vio)));
759
#if defined(MYSQL_SERVER)
761
We got an error that there was no data on the socket. We now set up
762
an alarm to not 'read forever', change the socket to non blocking
765
if ((interrupted || length == 0) && !thr_alarm_in_use(&alarmed))
767
if (!thr_alarm(&alarmed,net->read_timeout,&alarm_buff)) /* Don't wait too long */
770
while (vio_blocking(net->vio, TRUE, &old_mode) < 0)
772
if (vio_should_retry(net->vio) &&
773
retry_count++ < net->retry_count)
776
("fcntl returned error %d, aborting thread",
777
vio_errno(net->vio)));
780
"%s: read: fcntl returned error %d, aborting thread\n",
781
my_progname,vio_errno(net->vio));
782
#endif /* EXTRA_DEBUG */
784
net->error= 2; /* Close socket */
785
net->last_errno= ER_NET_FCNTL_ERROR;
787
my_error(ER_NET_FCNTL_ERROR, MYF(0));
795
#endif /* defined(MYSQL_SERVER) */
796
if (thr_alarm_in_use(&alarmed) && !thr_got_alarm(&alarmed) &&
798
{ /* Probably in MIT threads */
799
if (retry_count++ < net->retry_count)
802
fprintf(stderr, "%s: read looped with error %d, aborting thread\n",
803
my_progname,vio_errno(net->vio));
804
#endif /* EXTRA_DEBUG */
806
#if defined(THREAD_SAFE_CLIENT) && !defined(MYSQL_SERVER)
807
if (vio_errno(net->vio) == SOCKET_EINTR)
809
DBUG_PRINT("warning",("Interrupted read. Retrying..."));
813
DBUG_PRINT("error",("Couldn't read packet: remain: %u errno: %d length: %ld",
814
remain, vio_errno(net->vio), (long) length));
816
net->error= 2; /* Close socket */
817
net->last_errno= (vio_was_interrupted(net->vio) ?
818
ER_NET_READ_INTERRUPTED :
821
my_error(net->last_errno, MYF(0));
825
remain -= (uint32) length;
827
update_statistics(thd_increment_bytes_received(length));
830
{ /* First parts is packet length */
832
DBUG_DUMP("packet_header", net->buff+net->where_b,
834
if (net->buff[net->where_b + 3] != (uchar) net->pkt_nr)
836
if (net->buff[net->where_b] != (uchar) 255)
839
("Packets out of order (Found: %d, expected %u)",
840
(int) net->buff[net->where_b + 3],
844
fprintf(stderr,"Error: Packets out of order (Found: %d, expected %d)\n",
845
(int) net->buff[net->where_b + 3],
846
(uint) (uchar) net->pkt_nr);
852
/* Not a NET error on the client. XXX: why? */
854
my_error(ER_NET_PACKETS_OUT_OF_ORDER, MYF(0));
858
net->compress_pkt_nr= ++net->pkt_nr;
862
If the packet is compressed then complen > 0 and contains the
863
number of bytes in the uncompressed packet
865
*complen=uint3korr(&(net->buff[net->where_b + NET_HEADER_SIZE]));
868
len=uint3korr(net->buff+net->where_b);
869
if (!len) /* End of big multi-packet */
871
helping = max(len,*complen) + net->where_b;
872
/* The necessary size of net->buff */
873
if (helping >= net->max_packet)
875
if (net_realloc(net,helping))
877
#if defined(MYSQL_SERVER) && !defined(NO_ALARM)
878
if (!net->compress &&
879
!my_net_skip_rest(net, (uint32) len, &alarmed, &alarm_buff))
880
net->error= 3; /* Successfully skiped packet */
882
len= packet_error; /* Return error and close connection */
886
pos=net->buff + net->where_b;
887
remain = (uint32) len;
892
if (thr_alarm_in_use(&alarmed))
895
thr_end_alarm(&alarmed);
896
vio_blocking(net->vio, net_blocking, &old_mode);
898
net->reading_or_writing=0;
899
#ifdef DEBUG_DATA_PACKETS
900
if (len != packet_error)
901
DBUG_DUMP("data", net->buff+net->where_b, len);
908
Read a packet from the client/server and return it without the internal
911
If the packet is the first packet of a multi-packet packet
912
(which is indicated by the length of the packet = 0xffffff) then
913
all sub packets are read and concatenated.
915
If the packet was compressed, its uncompressed and the length of the
916
uncompressed packet is returned.
919
The function returns the length of the found packet or packet_error.
920
net->read_pos points to the read data.
924
my_net_read(NET *net)
930
len = my_real_read(net,&complen);
931
if (len == MAX_PACKET_LENGTH)
933
/* First packet of a multi-packet. Concatenate the packets */
934
ulong save_pos = net->where_b;
935
size_t total_length= 0;
940
len = my_real_read(net,&complen);
941
} while (len == MAX_PACKET_LENGTH);
942
if (len != packet_error)
944
net->where_b = save_pos;
946
net->read_pos = net->buff + net->where_b;
947
if (len != packet_error)
948
net->read_pos[len]=0; /* Safeguard for mysql_use_result */
953
/* We are using the compressed protocol */
956
ulong start_of_packet;
957
ulong first_packet_offset;
958
uint read_length, multi_byte_packet=0;
960
if (net->remain_in_buf)
962
buf_length= net->buf_length; /* Data left in old packet */
963
first_packet_offset= start_of_packet= (net->buf_length -
965
/* Restore the character that was overwritten by the end 0 */
966
net->buff[start_of_packet]= net->save_char;
970
/* reuse buffer, as there is nothing in it that we need */
971
buf_length= start_of_packet= first_packet_offset= 0;
977
if (buf_length - start_of_packet >= NET_HEADER_SIZE)
979
read_length = uint3korr(net->buff+start_of_packet);
982
/* End of multi-byte packet */
983
start_of_packet += NET_HEADER_SIZE;
986
if (read_length + NET_HEADER_SIZE <= buf_length - start_of_packet)
988
if (multi_byte_packet)
990
/* Remove packet header for second packet */
991
memmove(net->buff + first_packet_offset + start_of_packet,
992
net->buff + first_packet_offset + start_of_packet +
994
buf_length - start_of_packet);
995
start_of_packet += read_length;
996
buf_length -= NET_HEADER_SIZE;
999
start_of_packet+= read_length + NET_HEADER_SIZE;
1001
if (read_length != MAX_PACKET_LENGTH) /* last package */
1003
multi_byte_packet= 0; /* No last zero len packet */
1006
multi_byte_packet= NET_HEADER_SIZE;
1007
/* Move data down to read next data packet after current one */
1008
if (first_packet_offset)
1010
memmove(net->buff,net->buff+first_packet_offset,
1011
buf_length-first_packet_offset);
1012
buf_length-=first_packet_offset;
1013
start_of_packet -= first_packet_offset;
1014
first_packet_offset=0;
1019
/* Move data down to read next data packet after current one */
1020
if (first_packet_offset)
1022
memmove(net->buff,net->buff+first_packet_offset,
1023
buf_length-first_packet_offset);
1024
buf_length-=first_packet_offset;
1025
start_of_packet -= first_packet_offset;
1026
first_packet_offset=0;
1029
net->where_b=buf_length;
1030
if ((packet_len = my_real_read(net,&complen)) == packet_error)
1031
return packet_error;
1032
if (my_uncompress(net->buff + net->where_b, packet_len,
1035
net->error= 2; /* caller will close socket */
1036
net->last_errno= ER_NET_UNCOMPRESS_ERROR;
1038
my_error(ER_NET_UNCOMPRESS_ERROR, MYF(0));
1040
return packet_error;
1042
buf_length+= complen;
1045
net->read_pos= net->buff+ first_packet_offset + NET_HEADER_SIZE;
1046
net->buf_length= buf_length;
1047
net->remain_in_buf= (ulong) (buf_length - start_of_packet);
1048
len = ((ulong) (start_of_packet - first_packet_offset) - NET_HEADER_SIZE -
1050
net->save_char= net->read_pos[len]; /* Must be saved */
1051
net->read_pos[len]=0; /* Safeguard for mysql_use_result */
1057
void my_net_set_read_timeout(NET *net, uint timeout)
1059
DBUG_ENTER("my_net_set_read_timeout");
1060
DBUG_PRINT("enter", ("timeout: %d", timeout));
1061
net->read_timeout= timeout;
1064
vio_timeout(net->vio, 0, timeout);
1070
void my_net_set_write_timeout(NET *net, uint timeout)
1072
DBUG_ENTER("my_net_set_write_timeout");
1073
DBUG_PRINT("enter", ("timeout: %d", timeout));
1074
net->write_timeout= timeout;
1077
vio_timeout(net->vio, 1, timeout);