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
1
/* - mode: c; c-basic-offset: 2; indent-tabs-mode: nil; -*-
2
* vim:expandtab:shiftwidth=2:tabstop=2:smarttab:
4
* Copyright (C) 2008 Sun Microsystems, Inc.
6
* This program is free software; you can redistribute it and/or modify
7
* it under the terms of the GNU General Public License as published by
8
* the Free Software Foundation; either version 2 of the License, or
9
* (at your option) any later version.
11
* This program is distributed in the hope that it will be useful,
12
* but WITHOUT ANY WARRANTY; without even the implied warranty of
13
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14
* GNU General Public License for more details.
16
* You should have received a copy of the GNU General Public License
17
* along with this program; if not, write to the Free Software
18
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
20
#include <drizzled/global.h>
22
#include <drizzled/error.h>
23
#include <mysys/my_sys.h>
21
#define __need_timeval 1
23
#include "libdrizzle.h"
24
#include "libdrizzle_priv.h"
25
#include <libdrizzle/errmsg.h>
24
26
#include <vio/violite.h>
25
31
#include <signal.h>
33
#include <sys/socket.h>
27
34
#include <sys/poll.h>
30
38
The following handles the differences when this is linked between the
68
if (vio != 0) /* If real connection */
76
if (vio != 0) /* If real connection */
70
net->fd = vio_fd(vio); /* For perl DBI/DBD */
78
net->fd = vio_fd(vio); /* For perl DBI/DBD */
84
bool net_init_sock(NET * net, int sock, int flags)
87
Vio *vio_tmp= vio_new(sock, VIO_TYPE_TCPIP, flags);
91
if (my_net_init(net, vio_tmp))
93
/* Only delete the temporary vio if we didn't already attach it to the
96
if (vio_tmp && (net->vio != vio_tmp))
100
(void) shutdown(sock, SHUT_RDWR);
77
108
void net_end(NET *net)
79
my_free(net->buff,MYF(MY_ALLOW_ZERO_PTR));
110
if (net->buff != NULL)
116
void net_close(NET *net)
118
if (net->vio != NULL)
120
vio_delete(net->vio);
125
bool net_peer_addr(NET *net, char *buf, uint16_t *port, size_t buflen)
127
return vio_peer_addr(net->vio, buf, port, buflen);
130
void net_keepalive(NET *net, bool flag)
132
vio_keepalive(net->vio, flag);
135
int net_get_sd(NET *net)
140
bool net_should_close(NET *net)
142
return net->error || (net->vio == 0);
145
bool net_more_data(NET *net)
147
return (net->vio == 0 || net->vio->read_pos < net->vio->read_end);
85
150
/** Realloc the packet buffer. */
87
152
bool net_realloc(NET *net, size_t length)
90
155
size_t pkt_length;
92
157
if (length >= net->max_packet_size)
94
159
/* @todo: 1 and 2 codes are identical. */
96
net->last_errno= ER_NET_PACKET_TOO_LARGE;
161
net->last_errno= CR_NET_PACKET_TOO_LARGE;
99
pkt_length = (length+IO_SIZE-1) & ~(IO_SIZE-1);
164
pkt_length = (length+IO_SIZE-1) & ~(IO_SIZE-1);
101
166
We must allocate some extra bytes for the end 0 and to be able to
102
167
read big compressed blocks
104
if (!(buff= (uchar*) my_realloc((char*) net->buff, pkt_length +
105
NET_HEADER_SIZE + COMP_HEADER_SIZE,
169
if (!(buff= (unsigned char*) realloc((char*) net->buff, pkt_length +
170
NET_HEADER_SIZE + COMP_HEADER_SIZE)))
108
172
/* @todo: 1 and 2 codes are identical. */
110
net->last_errno= ER_OUT_OF_RESOURCES;
174
net->last_errno= CR_OUT_OF_MEMORY;
111
175
/* In the server the error is reported by MY_WME flag. */
148
Remove unwanted characters from connection
149
and check if disconnected.
151
Read from socket until there is nothing more to read. Discard
154
If there is anything when to read 'net_clear' is called this
155
normally indicates an error in the protocol.
157
When connection is properly closed (for TCP it means with
158
a FIN packet), then select() considers a socket "ready to read",
159
in the sense that there's EOF to read, but read() returns 0.
161
@param net NET handler
162
@param clear_buffer if <> 0, then clear all data from comm buff
212
Remove unwanted characters from connection
213
and check if disconnected.
215
Read from socket until there is nothing more to read. Discard
218
If there is anything when to read 'net_clear' is called this
219
normally indicates an error in the protocol.
221
When connection is properly closed (for TCP it means with
222
a FIN packet), then select() considers a socket "ready to read",
223
in the sense that there's EOF to read, but read() returns 0.
225
@param net NET handler
226
@param clear_buffer if <> 0, then clear all data from comm buff
165
229
void net_clear(NET *net, bool clear_buffer)
204
268
/*****************************************************************************
205
** Write something to server/client buffer
206
*****************************************************************************/
269
** Write something to server/client buffer
270
*****************************************************************************/
209
Write a logical packet with packet header.
211
Format: Packet length (3 bytes), packet number(1 byte)
212
When compression is used a 3 byte compression length is added
215
If compression is used the original package is modified!
273
Write a logical packet with packet header.
275
Format: Packet length (3 bytes), packet number(1 byte)
276
When compression is used a 3 byte compression length is added
279
If compression is used the original package is modified!
219
my_net_write(NET *net,const uchar *packet,size_t len)
283
my_net_write(NET *net,const unsigned char *packet,size_t len)
221
uchar buff[NET_HEADER_SIZE];
285
unsigned char buff[NET_HEADER_SIZE];
222
286
if (unlikely(!net->vio)) /* nowhere to write */
231
295
const uint32_t z_size = MAX_PACKET_LENGTH;
232
296
int3store(buff, z_size);
233
buff[3]= (uchar) net->pkt_nr++;
297
buff[3]= (unsigned char) net->pkt_nr++;
234
298
if (net_write_buff(net, buff, NET_HEADER_SIZE) ||
235
net_write_buff(net, packet, z_size))
299
net_write_buff(net, packet, z_size))
237
301
packet += z_size;
240
304
/* Write last packet */
241
305
int3store(buff,len);
242
buff[3]= (uchar) net->pkt_nr++;
306
buff[3]= (unsigned char) net->pkt_nr++;
243
307
if (net_write_buff(net, buff, NET_HEADER_SIZE))
245
return test(net_write_buff(net,packet,len));
309
return net_write_buff(net,packet,len) ? 1 : 0;
249
Send a command to the server.
251
The reason for having both header and packet is so that libdrizzle
252
can easy add a header to a special command (like prepared statements)
253
without having to re-alloc the string.
255
As the command is part of the first data packet, we have to do some data
256
juggling to put the command in there, without having to create a new
259
This function will split big packets into sub-packets if needed.
260
(Each sub packet can only be 2^24 bytes)
262
@param net NET handler
263
@param command Command in MySQL server (enum enum_server_command)
264
@param header Header to write after command
265
@param head_len Length of header
266
@param packet Query or parameter to query
267
@param len Length of packet
313
Send a command to the server.
315
The reason for having both header and packet is so that libdrizzle
316
can easy add a header to a special command (like prepared statements)
317
without having to re-alloc the string.
319
As the command is part of the first data packet, we have to do some data
320
juggling to put the command in there, without having to create a new
323
This function will split big packets into sub-packets if needed.
324
(Each sub packet can only be 2^24 bytes)
326
@param net NET handler
327
@param command Command in MySQL server (enum enum_server_command)
328
@param header Header to write after command
329
@param head_len Length of header
330
@param packet Query or parameter to query
331
@param len Length of packet
276
net_write_command(NET *net,uchar command,
277
const uchar *header, size_t head_len,
278
const uchar *packet, size_t len)
340
net_write_command(NET *net,unsigned char command,
341
const unsigned char *header, size_t head_len,
342
const unsigned char *packet, size_t len)
280
uint32_t length=len+1+head_len; /* 1 extra byte for command */
281
uchar buff[NET_HEADER_SIZE+1];
282
uint header_size=NET_HEADER_SIZE+1;
344
uint32_t length=len+1+head_len; /* 1 extra byte for command */
345
unsigned char buff[NET_HEADER_SIZE+1];
346
uint32_t header_size=NET_HEADER_SIZE+1;
284
buff[4]=command; /* For first packet */
348
buff[4]=command; /* For first packet */
286
350
if (length >= MAX_PACKET_LENGTH)
292
356
int3store(buff, MAX_PACKET_LENGTH);
293
buff[3]= (uchar) net->pkt_nr++;
357
buff[3]= (unsigned char) net->pkt_nr++;
294
358
if (net_write_buff(net, buff, header_size) ||
295
net_write_buff(net, header, head_len) ||
296
net_write_buff(net, packet, len))
359
net_write_buff(net, header, head_len) ||
360
net_write_buff(net, packet, len))
299
363
length-= MAX_PACKET_LENGTH;
300
364
len= MAX_PACKET_LENGTH;
302
366
header_size= NET_HEADER_SIZE;
303
367
} while (length >= MAX_PACKET_LENGTH);
304
len=length; /* Data left to be written */
368
len=length; /* Data left to be written */
306
370
int3store(buff,length);
307
buff[3]= (uchar) net->pkt_nr++;
308
return(test(net_write_buff(net, buff, header_size) ||
309
(head_len && net_write_buff(net, header, head_len)) ||
310
net_write_buff(net, packet, len) || net_flush(net)));
371
buff[3]= (unsigned char) net->pkt_nr++;
372
return((net_write_buff(net, buff, header_size) ||
373
(head_len && net_write_buff(net, header, head_len)) ||
374
net_write_buff(net, packet, len) || net_flush(net)) ? 1 : 0 );
314
Caching the data in a local buffer before sending it.
378
Caching the data in a local buffer before sending it.
316
380
Fill up net->buffer and send it to the client when full.
318
If the rest of the to-be-sent-packet is bigger than buffer,
319
send it in one big block (to avoid copying to internal buffer).
320
If not, copy the rest of the data to the buffer and return without
323
@param net Network handler
324
@param packet Packet to send
325
@param len Length of packet
328
The cached buffer can be sent as it is with 'net_flush()'.
329
In this code we have to be careful to not send a packet longer than
330
MAX_PACKET_LENGTH to net_real_write() if we are using the compressed
331
protocol as we store the length of the compressed packet in 3 bytes.
382
If the rest of the to-be-sent-packet is bigger than buffer,
383
send it in one big block (to avoid copying to internal buffer).
384
If not, copy the rest of the data to the buffer and return without
387
@param net Network handler
388
@param packet Packet to send
389
@param len Length of packet
392
The cached buffer can be sent as it is with 'net_flush()'.
393
In this code we have to be careful to not send a packet longer than
394
MAX_PACKET_LENGTH to net_real_write() if we are using the compressed
395
protocol as we store the length of the compressed packet in 3 bytes.
396
460
in the server, yield to another process and come back later.
399
net_real_write(NET *net,const uchar *packet, size_t len)
463
net_real_write(NET *net,const unsigned char *packet, size_t len)
402
const uchar *pos,*end;
466
const unsigned char *pos,*end;
467
uint32_t retry_count= 0;
405
469
/* Backup of the original SO_RCVTIMEO timeout */
406
struct timeval backtime;
471
struct timespec backtime;
409
475
if (net->error == 2)
410
return(-1); /* socket can't be used */
476
return(-1); /* socket can't be used */
412
478
net->reading_or_writing=2;
413
479
if (net->compress)
417
const uint header_length=NET_HEADER_SIZE+COMP_HEADER_SIZE;
418
if (!(b= (uchar*) my_malloc(len + NET_HEADER_SIZE +
419
COMP_HEADER_SIZE, MYF(MY_WME))))
483
const uint32_t header_length=NET_HEADER_SIZE+COMP_HEADER_SIZE;
484
if (!(b= (unsigned char*) malloc(len + NET_HEADER_SIZE +
422
net->last_errno= ER_OUT_OF_RESOURCES;
488
net->last_errno= CR_OUT_OF_MEMORY;
423
489
/* In the server, the error is reported by MY_WME flag. */
424
490
net->reading_or_writing= 0;
427
493
memcpy(b+header_length,packet,len);
429
if (my_compress(b+header_length, &len, &complen))
495
complen= len * 120 / 100 + 12;
496
unsigned char * compbuf= (unsigned char *) malloc(complen);
499
uLongf tmp_complen= complen;
500
int res= compress((Bytef*) compbuf, &tmp_complen,
501
(Bytef*) (b+header_length),
503
complen= tmp_complen;
507
if ((res != Z_OK) || (complen >= len))
511
size_t tmplen= complen;
431
520
int3store(&b[NET_HEADER_SIZE],complen);
432
521
int3store(b,len);
433
b[3]=(uchar) (net->compress_pkt_nr++);
522
b[3]=(unsigned char) (net->compress_pkt_nr++);
434
523
len+= header_length;
438
528
/* Check for error, currently assert */
439
529
if (net->write_timeout)
441
struct timeval waittime;
531
struct timespec waittime;
442
532
socklen_t length;
444
534
waittime.tv_sec= net->write_timeout;
447
memset(&backtime, 0, sizeof(struct timeval));
448
length= sizeof(struct timeval);
449
error= getsockopt(net->vio->sd, SOL_SOCKET, SO_RCVTIMEO,
537
memset(&backtime, 0, sizeof(struct timespec));
538
length= sizeof(struct timespec);
539
error= getsockopt(net->vio->sd, SOL_SOCKET, SO_RCVTIMEO,
450
540
&backtime, &length);
453
543
perror("getsockopt");
454
544
assert(error == 0);
456
error= setsockopt(net->vio->sd, SOL_SOCKET, SO_RCVTIMEO,
457
&waittime, (socklen_t)sizeof(struct timeval));
546
error= setsockopt(net->vio->sd, SOL_SOCKET, SO_RCVTIMEO,
547
&waittime, (socklen_t)sizeof(struct timespec));
458
548
assert(error == 0);
462
554
/* Loop until we have read everything */
490
582
if (retry_count++ < net->retry_count)
494
if (vio_errno(net->vio) == SOCKET_EINTR)
586
if (vio_errno(net->vio) == EINTR)
498
net->error= 2; /* Close socket */
499
net->last_errno= (interrupted ? ER_NET_WRITE_INTERRUPTED :
500
ER_NET_ERROR_ON_WRITE);
590
net->error= 2; /* Close socket */
591
net->last_errno= (interrupted ? CR_NET_WRITE_INTERRUPTED :
592
CR_NET_ERROR_ON_WRITE);
504
596
update_statistics(thd_increment_bytes_sent(length));
508
my_free((char*) packet,MYF(0));
599
if ((net->compress) && (packet != NULL))
600
free((char*) packet);
509
601
net->reading_or_writing=0;
511
604
if (net->write_timeout)
512
error= setsockopt(net->vio->sd, SOL_SOCKET, SO_RCVTIMEO,
513
&backtime, (socklen_t)sizeof(struct timeval));
605
error= setsockopt(net->vio->sd, SOL_SOCKET, SO_RCVTIMEO,
606
&backtime, (socklen_t)sizeof(struct timespec));
515
609
return(((int) (pos != end)));
520
Reads one packet to net->buff + net->where_b.
521
Long packets are handled by my_net_read().
522
This function reallocates the net->buff buffer if necessary.
614
Reads one packet to net->buff + net->where_b.
615
Long packets are handled by my_net_read().
616
This function reallocates the net->buff buffer if necessary.
525
Returns length of packet.
619
Returns length of packet.
529
623
my_real_read(NET *net, size_t *complen)
533
uint i,retry_count=0;
627
uint32_t i,retry_count=0;
534
628
uint32_t len=packet_error;
535
629
uint32_t remain= (net->compress ? NET_HEADER_SIZE+COMP_HEADER_SIZE :
537
633
/* Backup of the original SO_RCVTIMEO timeout */
538
struct timeval backtime;
634
struct timespec backtime;
543
640
net->reading_or_writing= 1;
544
641
/* Read timeout is set in my_net_set_read_timeout */
546
pos = net->buff + net->where_b; /* net->packet -4 */
643
pos = net->buff + net->where_b; /* net->packet -4 */
549
647
/* Check for error, currently assert */
550
648
if (net->read_timeout)
552
struct timeval waittime;
650
struct timespec waittime;
553
651
socklen_t length;
555
653
waittime.tv_sec= net->read_timeout;
558
memset(&backtime, 0, sizeof(struct timeval));
559
length= sizeof(struct timeval);
560
error= getsockopt(net->vio->sd, SOL_SOCKET, SO_RCVTIMEO,
656
memset(&backtime, 0, sizeof(struct timespec));
657
length= sizeof(struct timespec);
658
error= getsockopt(net->vio->sd, SOL_SOCKET, SO_RCVTIMEO,
561
659
&backtime, &length);
564
662
perror("getsockopt");
565
663
assert(error == 0);
567
error= setsockopt(net->vio->sd, SOL_SOCKET, SO_RCVTIMEO,
568
&waittime, (socklen_t)sizeof(struct timeval));
665
error= setsockopt(net->vio->sd, SOL_SOCKET, SO_RCVTIMEO,
666
&waittime, (socklen_t)sizeof(struct timespec));
569
667
assert(error == 0);
572
671
for (i= 0; i < 2 ; i++)
652
Read a packet from the client/server and return it without the internal
655
If the packet is the first packet of a multi-packet packet
656
(which is indicated by the length of the packet = 0xffffff) then
657
all sub packets are read and concatenated.
659
If the packet was compressed, its uncompressed and the length of the
660
uncompressed packet is returned.
663
The function returns the length of the found packet or packet_error.
664
net->read_pos points to the read data.
753
Read a packet from the client/server and return it without the internal
756
If the packet is the first packet of a multi-packet packet
757
(which is indicated by the length of the packet = 0xffffff) then
758
all sub packets are read and concatenated.
760
If the packet was compressed, its uncompressed and the length of the
761
uncompressed packet is returned.
764
The function returns the length of the found packet or packet_error.
765
net->read_pos points to the read data.
721
822
if (buf_length - start_of_packet >= NET_HEADER_SIZE)
723
read_length = uint3korr(net->buff+start_of_packet);
726
/* End of multi-byte packet */
727
start_of_packet += NET_HEADER_SIZE;
730
if (read_length + NET_HEADER_SIZE <= buf_length - start_of_packet)
732
if (multi_byte_packet)
734
/* Remove packet header for second packet */
735
memmove(net->buff + first_packet_offset + start_of_packet,
736
net->buff + first_packet_offset + start_of_packet +
738
buf_length - start_of_packet);
739
start_of_packet += read_length;
740
buf_length -= NET_HEADER_SIZE;
743
start_of_packet+= read_length + NET_HEADER_SIZE;
824
read_length = uint3korr(net->buff+start_of_packet);
827
/* End of multi-byte packet */
828
start_of_packet += NET_HEADER_SIZE;
831
if (read_length + NET_HEADER_SIZE <= buf_length - start_of_packet)
833
if (multi_byte_packet)
835
/* Remove packet header for second packet */
836
memmove(net->buff + first_packet_offset + start_of_packet,
837
net->buff + first_packet_offset + start_of_packet +
839
buf_length - start_of_packet);
840
start_of_packet += read_length;
841
buf_length -= NET_HEADER_SIZE;
844
start_of_packet+= read_length + NET_HEADER_SIZE;
745
if (read_length != MAX_PACKET_LENGTH) /* last package */
747
multi_byte_packet= 0; /* No last zero len packet */
750
multi_byte_packet= NET_HEADER_SIZE;
751
/* Move data down to read next data packet after current one */
752
if (first_packet_offset)
754
memmove(net->buff,net->buff+first_packet_offset,
755
buf_length-first_packet_offset);
756
buf_length-=first_packet_offset;
757
start_of_packet -= first_packet_offset;
758
first_packet_offset=0;
846
if (read_length != MAX_PACKET_LENGTH) /* last package */
848
multi_byte_packet= 0; /* No last zero len packet */
851
multi_byte_packet= NET_HEADER_SIZE;
852
/* Move data down to read next data packet after current one */
853
if (first_packet_offset)
855
memmove(net->buff,net->buff+first_packet_offset,
856
buf_length-first_packet_offset);
857
buf_length-=first_packet_offset;
858
start_of_packet -= first_packet_offset;
859
first_packet_offset=0;
763
864
/* Move data down to read next data packet after current one */
764
865
if (first_packet_offset)
766
memmove(net->buff,net->buff+first_packet_offset,
767
buf_length-first_packet_offset);
768
buf_length-=first_packet_offset;
769
start_of_packet -= first_packet_offset;
770
first_packet_offset=0;
867
memmove(net->buff,net->buff+first_packet_offset,
868
buf_length-first_packet_offset);
869
buf_length-=first_packet_offset;
870
start_of_packet -= first_packet_offset;
871
first_packet_offset=0;
773
874
net->where_b=buf_length;
774
875
if ((packet_len = my_real_read(net,&complen)) == packet_error)
776
if (my_uncompress(net->buff + net->where_b, packet_len,
779
net->error= 2; /* caller will close socket */
780
net->last_errno= ER_NET_UNCOMPRESS_ERROR;
880
unsigned char * compbuf= (unsigned char *) malloc(complen);
883
uLongf tmp_complen= complen;
884
int error= uncompress((Bytef*) compbuf, &tmp_complen,
885
(Bytef*) (net->buff + net->where_b),
887
complen= tmp_complen;
891
net->error= 2; /* caller will close socket */
892
net->last_errno= CR_NET_UNCOMPRESS_ERROR;
896
memcpy((net->buff + net->where_b), compbuf, complen);
783
buf_length+= complen;
905
buf_length+= complen;
786
907
net->read_pos= net->buff+ first_packet_offset + NET_HEADER_SIZE;
787
908
net->buf_length= buf_length;
788
909
net->remain_in_buf= (uint32_t) (buf_length - start_of_packet);
789
910
len = ((uint32_t) (start_of_packet - first_packet_offset) - NET_HEADER_SIZE -
790
911
multi_byte_packet);
791
net->save_char= net->read_pos[len]; /* Must be saved */
792
net->read_pos[len]=0; /* Safeguard for drizzle_use_result */
912
net->save_char= net->read_pos[len]; /* Must be saved */
913
net->read_pos[len]=0; /* Safeguard for drizzle_use_result */
798
void my_net_set_read_timeout(NET *net, uint timeout)
919
void my_net_set_read_timeout(NET *net, uint32_t timeout)
800
921
net->read_timeout= timeout;
802
924
vio_timeout(net->vio, 0, timeout);
807
void my_net_set_write_timeout(NET *net, uint timeout)
930
void my_net_set_write_timeout(NET *net, uint32_t timeout)
809
932
net->write_timeout= timeout;
811
935
vio_timeout(net->vio, 1, timeout);
940
Clear possible error state of struct NET
942
@param net clear the state of the argument
945
void net_clear_error(NET *net)
948
net->last_error[0]= '\0';
949
strcpy(net->sqlstate, sqlstate_get_not_error());