18
18
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
21
#define __need_timeval 1
21
#include <drizzled/global.h>
22
#include <drizzled/session.h>
23
23
#include "libdrizzle.h"
24
24
#include "libdrizzle_priv.h"
25
#include <libdrizzle/errmsg.h>
26
#include <vio/violite.h>
27
27
#include <assert.h>
29
29
#include <stdlib.h>
47
#define update_statistics(A)
48
#define thd_increment_bytes_sent(N)
50
#define TEST_BLOCKING 8
51
49
#define MAX_PACKET_LENGTH (256L*256L*256L-1)
52
#define MIN_COMPRESS_LENGTH 50 /* Don't compress small bl. */
54
51
static bool net_write_buff(NET *net, const unsigned char *packet, uint32_t len);
53
void drizzleclient_net_local_init(NET *net)
55
net->max_packet= (uint32_t) global_system_variables.net_buffer_length;
57
drizzleclient_net_set_read_timeout(net,
58
(uint32_t)global_system_variables.net_read_timeout);
59
drizzleclient_net_set_write_timeout(net,
60
(uint32_t)global_system_variables.net_write_timeout);
62
net->retry_count= (uint32_t) global_system_variables.net_retry_count;
63
net->max_packet_size= cmax(global_system_variables.net_buffer_length,
64
global_system_variables.max_allowed_packet);
57
67
/** Init with packet info. */
59
bool my_net_init(NET *net, Vio* vio)
69
bool drizzleclient_net_init(NET *net, Vio* vio)
62
my_net_local_init(net); /* Set some limits */
72
drizzleclient_net_local_init(net); /* Set some limits */
63
73
if (!(net->buff=(unsigned char*) malloc((size_t) net->max_packet+
64
NET_HEADER_SIZE + COMP_HEADER_SIZE)))
74
NET_HEADER_SIZE + COMP_HEADER_SIZE)))
66
76
net->buff_end=net->buff+net->max_packet;
67
77
net->error=0; net->return_status=0;
76
86
if (vio != 0) /* If real connection */
78
net->fd = vio_fd(vio); /* For perl DBI/DBD */
88
net->fd = drizzleclient_vio_fd(vio); /* For perl DBI/DBD */
89
drizzleclient_vio_fastsend(vio);
84
bool net_init_sock(NET * net, int sock, int flags)
94
bool drizzleclient_net_init_sock(NET * net, int sock, int flags)
87
Vio *vio_tmp= vio_new(sock, VIO_TYPE_TCPIP, flags);
97
Vio *drizzleclient_vio_tmp= drizzleclient_vio_new(sock, VIO_TYPE_TCPIP, flags);
98
if (drizzleclient_vio_tmp == NULL)
91
if (my_net_init(net, vio_tmp))
101
if (drizzleclient_net_init(net, drizzleclient_vio_tmp))
93
103
/* Only delete the temporary vio if we didn't already attach it to the
96
if (vio_tmp && (net->vio != vio_tmp))
106
if (drizzleclient_vio_tmp && (net->vio != drizzleclient_vio_tmp))
107
drizzleclient_vio_delete(drizzleclient_vio_tmp);
100
110
(void) shutdown(sock, SHUT_RDWR);
108
void net_end(NET *net)
118
void drizzleclient_net_end(NET *net)
110
120
if (net->buff != NULL)
116
void net_close(NET *net)
126
void drizzleclient_net_close(NET *net)
118
128
if (net->vio != NULL)
120
vio_delete(net->vio);
130
drizzleclient_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)
135
bool drizzleclient_net_peer_addr(NET *net, char *buf, uint16_t *port, size_t buflen)
137
return drizzleclient_vio_peer_addr(net->vio, buf, port, buflen);
140
void drizzleclient_net_keepalive(NET *net, bool flag)
142
drizzleclient_vio_keepalive(net->vio, flag);
145
int drizzleclient_net_get_sd(NET *net)
137
147
return net->vio->sd;
140
bool net_should_close(NET *net)
150
bool drizzleclient_net_should_close(NET *net)
142
152
return net->error || (net->vio == 0);
145
bool net_more_data(NET *net)
155
bool drizzleclient_net_more_data(NET *net)
147
157
return (net->vio == 0 || net->vio->read_pos < net->vio->read_end);
150
160
/** Realloc the packet buffer. */
152
bool net_realloc(NET *net, size_t length)
162
bool drizzleclient_net_realloc(NET *net, size_t length)
154
164
unsigned char *buff;
155
165
size_t pkt_length;
215
225
Read from socket until there is nothing more to read. Discard
218
If there is anything when to read 'net_clear' is called this
228
If there is anything when to read 'drizzleclient_net_clear' is called this
219
229
normally indicates an error in the protocol.
221
231
When connection is properly closed (for TCP it means with
226
236
@param clear_buffer if <> 0, then clear all data from comm buff
229
void net_clear(NET *net, bool clear_buffer)
239
void drizzleclient_net_clear(NET *net, bool clear_buffer)
231
241
if (clear_buffer)
233
243
while (net_data_is_ready(net->vio->sd) > 0)
235
245
/* The socket is ready */
236
if (vio_read(net->vio, net->buff,
246
if (drizzleclient_vio_read(net->vio, net->buff,
237
247
(size_t) net->max_packet) <= 0)
250
260
/** Flush write_buffer if not empty. */
252
bool net_flush(NET *net)
262
bool drizzleclient_net_flush(NET *net)
255
265
if (net->buff != net->write_pos)
257
error=net_real_write(net, net->buff,
267
error=drizzleclient_net_real_write(net, net->buff,
258
268
(size_t) (net->write_pos - net->buff)) ? 1 : 0;
259
269
net->write_pos=net->buff;
283
my_net_write(NET *net,const unsigned char *packet,size_t len)
293
drizzleclient_net_write(NET *net,const unsigned char *packet,size_t len)
285
295
unsigned char buff[NET_HEADER_SIZE];
286
296
if (unlikely(!net->vio)) /* nowhere to write */
340
net_write_command(NET *net,unsigned char command,
350
drizzleclient_net_write_command(NET *net,unsigned char command,
341
351
const unsigned char *header, size_t head_len,
342
352
const unsigned char *packet, size_t len)
371
381
buff[3]= (unsigned char) net->pkt_nr++;
372
382
return((net_write_buff(net, buff, header_size) ||
373
383
(head_len && net_write_buff(net, header, head_len)) ||
374
net_write_buff(net, packet, len) || net_flush(net)) ? 1 : 0 );
384
net_write_buff(net, packet, len) || drizzleclient_net_flush(net)) ? 1 : 0 );
389
399
@param len Length of packet
392
The cached buffer can be sent as it is with 'net_flush()'.
402
The cached buffer can be sent as it is with 'drizzleclient_net_flush()'.
393
403
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
404
MAX_PACKET_LENGTH to drizzleclient_net_real_write() if we are using the compressed
395
405
protocol as we store the length of the compressed packet in 3 bytes.
416
426
/* Fill up already used packet and write it */
417
427
memcpy(net->write_pos,packet,left_length);
418
if (net_real_write(net, net->buff,
428
if (drizzleclient_net_real_write(net, net->buff,
419
429
(size_t) (net->write_pos - net->buff) + left_length))
421
431
net->write_pos= net->buff;
431
441
left_length= MAX_PACKET_LENGTH;
432
442
while (len > left_length)
434
if (net_real_write(net, packet, left_length))
444
if (drizzleclient_net_real_write(net, packet, left_length))
436
446
packet+= left_length;
437
447
len-= left_length;
440
450
if (len > net->max_packet)
441
return net_real_write(net, packet, len) ? 1 : 0;
451
return drizzleclient_net_real_write(net, packet, len) ? 1 : 0;
442
452
/* Send out rest of the blocks as full sized blocks */
444
454
memcpy(net->write_pos,packet,len);
460
470
in the server, yield to another process and come back later.
463
net_real_write(NET *net,const unsigned char *packet, size_t len)
473
drizzleclient_net_real_write(NET *net, const unsigned char *packet, size_t len)
466
const unsigned char *pos,*end;
476
const unsigned char *pos, *end;
467
477
uint32_t retry_count= 0;
469
479
/* Backup of the original SO_RCVTIMEO timeout */
471
struct timespec backtime;
475
481
if (net->error == 2)
476
482
return(-1); /* socket can't be used */
528
/* Check for error, currently assert */
529
if (net->write_timeout)
531
struct timespec waittime;
534
waittime.tv_sec= net->write_timeout;
537
memset(&backtime, 0, sizeof(struct timespec));
538
length= sizeof(struct timespec);
539
error= getsockopt(net->vio->sd, SOL_SOCKET, SO_RCVTIMEO,
543
perror("getsockopt");
546
error= setsockopt(net->vio->sd, SOL_SOCKET, SO_RCVTIMEO,
547
&waittime, (socklen_t)sizeof(struct timespec));
554
535
/* Loop until we have read everything */
555
536
while (pos != end)
557
if ((long) (length= vio_write(net->vio,pos,(size_t) (end-pos))) <= 0)
539
if ((long) (length= drizzleclient_vio_write(net->vio, pos, (size_t) (end-pos))) <= 0)
559
const bool interrupted= vio_should_retry(net->vio);
541
const bool interrupted= drizzleclient_vio_should_retry(net->vio);
561
543
If we read 0, or we were interrupted this means that
562
544
we need to switch to blocking mode and wait until the timeout
569
while (vio_blocking(net->vio, true, &old_mode) < 0)
551
while (drizzleclient_vio_blocking(net->vio, true, &old_mode) < 0)
571
if (vio_should_retry(net->vio) && retry_count++ < net->retry_count)
553
if (drizzleclient_vio_should_retry(net->vio) && retry_count++ < net->retry_count)
573
555
net->error= 2; /* Close socket */
574
556
net->last_errno= CR_NET_PACKET_TOO_LARGE;
596
update_statistics(thd_increment_bytes_sent(length));
599
580
if ((net->compress) && (packet != NULL))
600
581
free((char*) packet);
601
582
net->reading_or_writing=0;
604
if (net->write_timeout)
605
error= setsockopt(net->vio->sd, SOL_SOCKET, SO_RCVTIMEO,
606
&backtime, (socklen_t)sizeof(struct timespec));
609
584
return(((int) (pos != end)));
614
589
Reads one packet to net->buff + net->where_b.
615
Long packets are handled by my_net_read().
590
Long packets are handled by drizzleclient_net_read().
616
591
This function reallocates the net->buff buffer if necessary.
625
600
unsigned char *pos;
627
602
uint32_t i,retry_count=0;
628
uint32_t len=packet_error;
603
size_t len=packet_error;
629
604
uint32_t remain= (net->compress ? NET_HEADER_SIZE+COMP_HEADER_SIZE :
630
605
NET_HEADER_SIZE);
633
/* Backup of the original SO_RCVTIMEO timeout */
634
struct timespec backtime;
640
609
net->reading_or_writing= 1;
641
/* Read timeout is set in my_net_set_read_timeout */
610
/* Read timeout is set in drizzleclient_net_set_read_timeout */
643
612
pos = net->buff + net->where_b; /* net->packet -4 */
647
/* Check for error, currently assert */
648
if (net->read_timeout)
650
struct timespec waittime;
653
waittime.tv_sec= net->read_timeout;
656
memset(&backtime, 0, sizeof(struct timespec));
657
length= sizeof(struct timespec);
658
error= getsockopt(net->vio->sd, SOL_SOCKET, SO_RCVTIMEO,
662
perror("getsockopt");
665
error= setsockopt(net->vio->sd, SOL_SOCKET, SO_RCVTIMEO,
666
&waittime, (socklen_t)sizeof(struct timespec));
671
614
for (i= 0; i < 2 ; i++)
673
616
while (remain > 0)
675
618
/* First read is done with non blocking mode */
676
if ((long) (length= vio_read(net->vio, pos, remain)) <= 0L)
619
if ((long) (length= drizzleclient_vio_read(net->vio, pos, remain)) <= 0L)
678
const bool interrupted = vio_should_retry(net->vio);
621
const bool interrupted = drizzleclient_vio_should_retry(net->vio);
681
624
{ /* Probably in MIT threads */
682
625
if (retry_count++ < net->retry_count)
685
if (vio_errno(net->vio) == EINTR)
628
if (drizzleclient_vio_errno(net->vio) == EINTR)
689
632
len= packet_error;
690
633
net->error= 2; /* Close socket */
691
net->last_errno= (vio_was_interrupted(net->vio) ?
634
net->last_errno= (drizzleclient_vio_was_interrupted(net->vio) ?
692
635
CR_NET_READ_INTERRUPTED :
693
636
CR_NET_READ_ERROR);
694
637
ER(net->last_errno);
725
667
/* The necessary size of net->buff */
726
668
if (helping >= net->max_packet)
728
if (net_realloc(net,helping))
670
if (drizzleclient_net_realloc(net,helping))
730
672
len= packet_error; /* Return error and close connection */
741
if (net->read_timeout)
742
error= setsockopt(net->vio->sd, SOL_SOCKET, SO_RCVTIMEO,
743
&backtime, (socklen_t)sizeof(struct timespec));
746
682
net->reading_or_writing= 0;
910
846
len = ((uint32_t) (start_of_packet - first_packet_offset) - NET_HEADER_SIZE -
911
847
multi_byte_packet);
912
848
net->save_char= net->read_pos[len]; /* Must be saved */
913
net->read_pos[len]=0; /* Safeguard for drizzle_use_result */
849
net->read_pos[len]=0; /* Safeguard for drizzleclient_use_result */
919
void my_net_set_read_timeout(NET *net, uint32_t timeout)
855
void drizzleclient_net_set_read_timeout(NET *net, uint32_t timeout)
921
857
net->read_timeout= timeout;
924
vio_timeout(net->vio, 0, timeout);
860
drizzleclient_vio_timeout(net->vio, 0, timeout);
930
void my_net_set_write_timeout(NET *net, uint32_t timeout)
866
void drizzleclient_net_set_write_timeout(NET *net, uint32_t timeout)
932
868
net->write_timeout= timeout;
935
vio_timeout(net->vio, 1, timeout);
871
drizzleclient_vio_timeout(net->vio, 1, timeout);
942
878
@param net clear the state of the argument
945
void net_clear_error(NET *net)
881
void drizzleclient_drizzleclient_net_clear_error(NET *net)
947
883
net->last_errno= 0;
948
884
net->last_error[0]= '\0';
949
strcpy(net->sqlstate, sqlstate_get_not_error());
885
strcpy(net->sqlstate, drizzleclient_sqlstate_get_not_error());