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
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
22
#include <drizzled/session.h>
20
#include <drizzled/global.h>
22
#include <drizzled/error.h>
23
#include <mysys/my_sys.h>
24
#include <mystrings/m_string.h>
25
#include <vio/violite.h>
28
26
#include <signal.h>
30
#include <sys/socket.h>
31
28
#include <sys/poll.h>
41
namespace drizzle_protocol
45
31
The following handles the differences when this is linked between the
50
36
can't normally do this the client should have a bigger max_allowed_packet.
53
/* Constants when using compression */
54
#define NET_HEADER_SIZE 4 /* standard header size */
55
#define COMP_HEADER_SIZE 3 /* compression header extra size */
40
#define DONT_USE_THR_ALARM
42
#include <mysys/thr_alarm.h>
45
#define update_statistics(A)
46
#define thd_increment_bytes_sent(N)
48
#define TEST_BLOCKING 8
57
49
#define MAX_PACKET_LENGTH (256L*256L*256L-1)
58
const char *not_error_sqlstate= "00000";
60
51
static bool net_write_buff(NET *net, const unsigned char *packet, uint32_t len);
61
static int drizzleclient_net_real_write(NET *net, const unsigned char *packet, size_t len);
63
54
/** Init with packet info. */
65
bool drizzleclient_net_init(NET *net, Vio* vio, uint32_t buffer_length)
56
bool my_net_init(NET *net, Vio* vio)
68
net->max_packet= (uint32_t) buffer_length;
69
net->max_packet_size= max(buffer_length,
70
drizzled::global_system_variables.max_allowed_packet);
72
if (!(net->buff=(unsigned char*) malloc((size_t) net->max_packet+
73
NET_HEADER_SIZE + COMP_HEADER_SIZE)))
59
my_net_local_init(net); /* Set some limits */
60
if (!(net->buff=(uchar*) my_malloc((size_t) net->max_packet+
61
NET_HEADER_SIZE + COMP_HEADER_SIZE,
75
64
net->buff_end=net->buff+net->max_packet;
76
65
net->error=0; net->return_status=0;
85
if (vio != 0) /* If real connection */
74
if (vio != 0) /* If real connection */
87
net->fd = drizzleclient_vio_fd(vio); /* For perl DBI/DBD */
88
drizzleclient_vio_fastsend(vio);
76
net->fd = vio_fd(vio); /* For perl DBI/DBD */
93
bool drizzleclient_net_init_sock(NET * net, int sock, int flags,
94
uint32_t buffer_length)
97
Vio *drizzleclient_vio_tmp= drizzleclient_vio_new(sock, VIO_TYPE_TCPIP, flags);
98
if (drizzleclient_vio_tmp == NULL)
101
if (drizzleclient_net_init(net, drizzleclient_vio_tmp, buffer_length))
103
/* Only delete the temporary vio if we didn't already attach it to the
106
if (drizzleclient_vio_tmp && (net->vio != drizzleclient_vio_tmp))
107
drizzleclient_vio_delete(drizzleclient_vio_tmp);
110
(void) shutdown(sock, SHUT_RDWR);
118
void drizzleclient_net_end(NET *net)
120
if (net->buff != NULL)
83
void net_end(NET *net)
85
my_free(net->buff,MYF(MY_ALLOW_ZERO_PTR));
126
void drizzleclient_net_close(NET *net)
128
if (net->vio != NULL)
130
drizzleclient_vio_delete(net->vio);
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)
150
bool drizzleclient_net_more_data(NET *net)
152
return (net->vio == 0 || net->vio->read_pos < net->vio->read_end);
155
91
/** Realloc the packet buffer. */
157
static bool drizzleclient_net_realloc(NET *net, size_t length)
93
bool net_realloc(NET *net, size_t length)
160
96
size_t pkt_length;
162
98
if (length >= net->max_packet_size)
164
100
/* @todo: 1 and 2 codes are identical. */
166
net->last_errno= CR_NET_PACKET_TOO_LARGE;
102
net->last_errno= ER_NET_PACKET_TOO_LARGE;
169
pkt_length = (length+IO_SIZE-1) & ~(IO_SIZE-1);
105
pkt_length = (length+IO_SIZE-1) & ~(IO_SIZE-1);
171
107
We must allocate some extra bytes for the end 0 and to be able to
172
108
read big compressed blocks
174
if (!(buff= (unsigned char*) realloc((char*) net->buff, pkt_length +
175
NET_HEADER_SIZE + COMP_HEADER_SIZE)))
110
if (!(buff= (uchar*) my_realloc((char*) net->buff, pkt_length +
111
NET_HEADER_SIZE + COMP_HEADER_SIZE,
177
114
/* @todo: 1 and 2 codes are identical. */
179
net->last_errno= CR_OUT_OF_MEMORY;
116
net->last_errno= ER_OUT_OF_RESOURCES;
180
117
/* In the server the error is reported by MY_WME flag. */
183
120
net->buff=net->write_pos=buff;
184
net->buff_end=buff+(net->max_packet= (uint32_t) pkt_length);
121
net->buff_end=buff+(net->max_packet= (ulong) pkt_length);
190
Check if there is any data to be read from the socket.
192
@param sd socket descriptor
197
1 Data or EOF to read
199
-1 Don't know if data is ready or not
127
Check if there is any data to be read from the socket.
129
@param sd socket descriptor
134
1 Data or EOF to read
136
-1 Don't know if data is ready or not
202
static bool net_data_is_ready(int sd)
139
static int net_data_is_ready(my_socket sd)
204
141
struct pollfd ufds;
217
Remove unwanted characters from connection
218
and check if disconnected.
220
Read from socket until there is nothing more to read. Discard
223
If there is anything when to read 'drizzleclient_net_clear' is called this
224
normally indicates an error in the protocol.
226
When connection is properly closed (for TCP it means with
227
a FIN packet), then select() considers a socket "ready to read",
228
in the sense that there's EOF to read, but read() returns 0.
230
@param net NET handler
231
@param clear_buffer if <> 0, then clear all data from comm buff
154
Remove unwanted characters from connection
155
and check if disconnected.
157
Read from socket until there is nothing more to read. Discard
160
If there is anything when to read 'net_clear' is called this
161
normally indicates an error in the protocol.
163
When connection is properly closed (for TCP it means with
164
a FIN packet), then select() considers a socket "ready to read",
165
in the sense that there's EOF to read, but read() returns 0.
167
@param net NET handler
168
@param clear_buffer if <> 0, then clear all data from comm buff
234
void drizzleclient_net_clear(NET *net, bool clear_buffer)
171
void net_clear(NET *net, bool clear_buffer)
236
176
if (clear_buffer)
238
while (net_data_is_ready(net->vio->sd) > 0)
178
while ((ready= net_data_is_ready(net->vio->sd)) > 0)
240
180
/* The socket is ready */
241
if (drizzleclient_vio_read(net->vio, net->buff,
242
(size_t) net->max_packet) <= 0)
181
if ((long) (count= vio_read(net->vio, net->buff,
182
(size_t) net->max_packet)) <= 0)
249
net->pkt_nr=net->compress_pkt_nr=0; /* Ready for new command */
189
net->pkt_nr=net->compress_pkt_nr=0; /* Ready for new command */
250
190
net->write_pos=net->buff;
273
213
/*****************************************************************************
274
** Write something to server/client buffer
275
*****************************************************************************/
214
** Write something to server/client buffer
215
*****************************************************************************/
278
Write a logical packet with packet header.
280
Format: Packet length (3 bytes), packet number(1 byte)
281
When compression is used a 3 byte compression length is added
284
If compression is used the original package is modified!
218
Write a logical packet with packet header.
220
Format: Packet length (3 bytes), packet number(1 byte)
221
When compression is used a 3 byte compression length is added
224
If compression is used the original package is modified!
288
drizzleclient_net_write(NET *net,const unsigned char *packet,size_t len)
228
my_net_write(NET *net,const uchar *packet,size_t len)
290
unsigned char buff[NET_HEADER_SIZE];
230
uchar buff[NET_HEADER_SIZE];
291
231
if (unlikely(!net->vio)) /* nowhere to write */
298
238
while (len >= MAX_PACKET_LENGTH)
300
const uint32_t z_size = MAX_PACKET_LENGTH;
240
const ulong z_size = MAX_PACKET_LENGTH;
301
241
int3store(buff, z_size);
302
buff[3]= (unsigned char) net->pkt_nr++;
242
buff[3]= (uchar) net->pkt_nr++;
303
243
if (net_write_buff(net, buff, NET_HEADER_SIZE) ||
304
net_write_buff(net, packet, z_size))
244
net_write_buff(net, packet, z_size))
306
246
packet += z_size;
309
249
/* Write last packet */
310
250
int3store(buff,len);
311
buff[3]= (unsigned char) net->pkt_nr++;
251
buff[3]= (uchar) net->pkt_nr++;
312
252
if (net_write_buff(net, buff, NET_HEADER_SIZE))
314
return net_write_buff(net,packet,len) ? 1 : 0;
254
return test(net_write_buff(net,packet,len));
318
Send a command to the server.
320
The reason for having both header and packet is so that libdrizzle
321
can easy add a header to a special command (like prepared statements)
322
without having to re-alloc the string.
324
As the command is part of the first data packet, we have to do some data
325
juggling to put the command in there, without having to create a new
328
This function will split big packets into sub-packets if needed.
329
(Each sub packet can only be 2^24 bytes)
331
@param net NET handler
332
@param command Command in MySQL server (enum enum_server_command)
333
@param header Header to write after command
334
@param head_len Length of header
335
@param packet Query or parameter to query
336
@param len Length of packet
258
Send a command to the server.
260
The reason for having both header and packet is so that libdrizzle
261
can easy add a header to a special command (like prepared statements)
262
without having to re-alloc the string.
264
As the command is part of the first data packet, we have to do some data
265
juggling to put the command in there, without having to create a new
268
This function will split big packets into sub-packets if needed.
269
(Each sub packet can only be 2^24 bytes)
271
@param net NET handler
272
@param command Command in MySQL server (enum enum_server_command)
273
@param header Header to write after command
274
@param head_len Length of header
275
@param packet Query or parameter to query
276
@param len Length of packet
345
drizzleclient_net_write_command(NET *net,unsigned char command,
346
const unsigned char *header, size_t head_len,
347
const unsigned char *packet, size_t len)
285
net_write_command(NET *net,uchar command,
286
const uchar *header, size_t head_len,
287
const uchar *packet, size_t len)
349
uint32_t length=len+1+head_len; /* 1 extra byte for command */
350
unsigned char buff[NET_HEADER_SIZE+1];
351
uint32_t header_size=NET_HEADER_SIZE+1;
289
ulong length=len+1+head_len; /* 1 extra byte for command */
290
uchar buff[NET_HEADER_SIZE+1];
291
uint header_size=NET_HEADER_SIZE+1;
353
buff[4]=command; /* For first packet */
293
buff[4]=command; /* For first packet */
355
295
if (length >= MAX_PACKET_LENGTH)
361
301
int3store(buff, MAX_PACKET_LENGTH);
362
buff[3]= (unsigned char) net->pkt_nr++;
302
buff[3]= (uchar) net->pkt_nr++;
363
303
if (net_write_buff(net, buff, header_size) ||
364
net_write_buff(net, header, head_len) ||
365
net_write_buff(net, packet, len))
304
net_write_buff(net, header, head_len) ||
305
net_write_buff(net, packet, len))
368
308
length-= MAX_PACKET_LENGTH;
369
309
len= MAX_PACKET_LENGTH;
371
311
header_size= NET_HEADER_SIZE;
372
312
} while (length >= MAX_PACKET_LENGTH);
373
len=length; /* Data left to be written */
313
len=length; /* Data left to be written */
375
315
int3store(buff,length);
376
buff[3]= (unsigned char) net->pkt_nr++;
377
return((net_write_buff(net, buff, header_size) ||
378
(head_len && net_write_buff(net, header, head_len)) ||
379
net_write_buff(net, packet, len) || drizzleclient_net_flush(net)) ? 1 : 0 );
316
buff[3]= (uchar) net->pkt_nr++;
317
return(test(net_write_buff(net, buff, header_size) ||
318
(head_len && net_write_buff(net, header, head_len)) ||
319
net_write_buff(net, packet, len) || net_flush(net)));
383
Caching the data in a local buffer before sending it.
323
Caching the data in a local buffer before sending it.
385
325
Fill up net->buffer and send it to the client when full.
387
If the rest of the to-be-sent-packet is bigger than buffer,
388
send it in one big block (to avoid copying to internal buffer).
389
If not, copy the rest of the data to the buffer and return without
392
@param net Network handler
393
@param packet Packet to send
394
@param len Length of packet
397
The cached buffer can be sent as it is with 'drizzleclient_net_flush()'.
398
In this code we have to be careful to not send a packet longer than
399
MAX_PACKET_LENGTH to drizzleclient_net_real_write() if we are using the compressed
400
protocol as we store the length of the compressed packet in 3 bytes.
327
If the rest of the to-be-sent-packet is bigger than buffer,
328
send it in one big block (to avoid copying to internal buffer).
329
If not, copy the rest of the data to the buffer and return without
332
@param net Network handler
333
@param packet Packet to send
334
@param len Length of packet
337
The cached buffer can be sent as it is with 'net_flush()'.
338
In this code we have to be careful to not send a packet longer than
339
MAX_PACKET_LENGTH to net_real_write() if we are using the compressed
340
protocol as we store the length of the compressed packet in 3 bytes.
409
349
net_write_buff(NET *net, const unsigned char *packet, uint32_t len)
411
uint32_t left_length;
412
352
if (net->compress && net->max_packet > MAX_PACKET_LENGTH)
413
353
left_length= MAX_PACKET_LENGTH - (net->write_pos - net->buff);
415
left_length= (uint32_t) (net->buff_end - net->write_pos);
355
left_length= (ulong) (net->buff_end - net->write_pos);
417
357
if (len > left_length)
419
359
if (net->write_pos != net->buff)
421
361
/* Fill up already used packet and write it */
422
memcpy(net->write_pos,packet,left_length);
423
if (drizzleclient_net_real_write(net, net->buff,
424
(size_t) (net->write_pos - net->buff) + left_length))
362
memcpy((char*) net->write_pos,packet,left_length);
363
if (net_real_write(net, net->buff,
364
(size_t) (net->write_pos - net->buff) + left_length))
426
366
net->write_pos= net->buff;
427
367
packet+= left_length;
428
368
len-= left_length;
430
370
if (net->compress)
433
We can't have bigger packets than 16M with compression
434
Because the uncompressed length is stored in 3 bytes
373
We can't have bigger packets than 16M with compression
374
Because the uncompressed length is stored in 3 bytes
436
376
left_length= MAX_PACKET_LENGTH;
437
377
while (len > left_length)
439
if (drizzleclient_net_real_write(net, packet, left_length))
441
packet+= left_length;
379
if (net_real_write(net, packet, left_length))
381
packet+= left_length;
445
385
if (len > net->max_packet)
446
return drizzleclient_net_real_write(net, packet, len) ? 1 : 0;
386
return net_real_write(net, packet, len) ? 1 : 0;
447
387
/* Send out rest of the blocks as full sized blocks */
449
memcpy(net->write_pos,packet,len);
389
memcpy((char*) net->write_pos,packet,len);
450
390
net->write_pos+= len;
456
Read and write one packet using timeouts.
457
If needed, the packet is compressed before sending.
396
Read and write one packet using timeouts.
397
If needed, the packet is compressed before sending.
460
- TODO is it needed to set this variable if we have no socket
400
- TODO is it needed to set this variable if we have no socket
464
404
TODO: rewrite this in a manner to do non-block writes. If a write can not be made, and we are
465
405
in the server, yield to another process and come back later.
468
drizzleclient_net_real_write(NET *net, const unsigned char *packet, size_t len)
408
net_real_write(NET *net,const uchar *packet, size_t len)
471
const unsigned char *pos, *end;
472
uint32_t retry_count= 0;
411
const uchar *pos,*end;
474
414
/* Backup of the original SO_RCVTIMEO timeout */
415
struct timeval backtime;
476
418
if (net->error == 2)
477
return(-1); /* socket can't be used */
419
return(-1); /* socket can't be used */
479
421
net->reading_or_writing=2;
480
422
if (net->compress)
484
const uint32_t header_length=NET_HEADER_SIZE+COMP_HEADER_SIZE;
485
if (!(b= (unsigned char*) malloc(len + NET_HEADER_SIZE +
426
uint header_length=NET_HEADER_SIZE+COMP_HEADER_SIZE;
427
if (!(b= (uchar*) my_malloc(len + NET_HEADER_SIZE +
428
COMP_HEADER_SIZE, MYF(MY_WME))))
489
net->last_errno= CR_OUT_OF_MEMORY;
431
net->last_errno= ER_OUT_OF_RESOURCES;
490
432
/* In the server, the error is reported by MY_WME flag. */
491
433
net->reading_or_writing= 0;
494
436
memcpy(b+header_length,packet,len);
496
complen= len * 120 / 100 + 12;
497
unsigned char * compbuf= (unsigned char *) malloc(complen);
500
uLongf tmp_complen= complen;
501
int res= compress((Bytef*) compbuf, &tmp_complen,
502
(Bytef*) (b+header_length),
504
complen= tmp_complen;
508
if ((res != Z_OK) || (complen >= len))
512
size_t tmplen= complen;
438
if (my_compress(b+header_length, &len, &complen))
521
440
int3store(&b[NET_HEADER_SIZE],complen);
522
441
int3store(b,len);
523
b[3]=(unsigned char) (net->compress_pkt_nr++);
442
b[3]=(uchar) (net->compress_pkt_nr++);
524
443
len+= header_length;
447
/* Check for error, currently assert */
448
if (net->write_timeout)
450
struct timeval waittime;
453
waittime.tv_sec= net->write_timeout;
456
memset(&backtime, 0, sizeof(struct timeval));
457
length= sizeof(struct timeval);
458
error= getsockopt(net->vio->sd, SOL_SOCKET, SO_RCVTIMEO,
462
perror("getsockopt");
465
error= setsockopt(net->vio->sd, SOL_SOCKET, SO_RCVTIMEO,
466
&waittime, (socklen_t)sizeof(struct timeval));
530
471
/* Loop until we have read everything */
531
472
while (pos != end)
534
if ((long) (length= drizzleclient_vio_write(net->vio, pos, (size_t) (end-pos))) <= 0)
474
if ((long) (length= vio_write(net->vio,pos,(size_t) (end-pos))) <= 0)
537
* We could end up here with net->vio == NULL
539
* If that is the case, we exit the while loop
541
if (net->vio == NULL)
544
const bool interrupted= drizzleclient_vio_should_retry(net->vio);
546
If we read 0, or we were interrupted this means that
547
we need to switch to blocking mode and wait until the timeout
476
my_bool interrupted= vio_should_retry(net->vio);
478
If we read 0, or we were interrupted this means that
479
we need to switch to blocking mode and wait until the timeout
548
480
on the socket kicks in.
550
482
if ((interrupted || length == 0))
554
while (drizzleclient_vio_blocking(net->vio, true, &old_mode) < 0)
486
while (vio_blocking(net->vio, true, &old_mode) < 0)
556
if (drizzleclient_vio_should_retry(net->vio) && retry_count++ < net->retry_count)
488
if (vio_should_retry(net->vio) && retry_count++ < net->retry_count)
558
490
net->error= 2; /* Close socket */
559
net->last_errno= CR_NET_PACKET_TOO_LARGE;
491
net->last_errno= ER_NET_PACKET_TOO_LARGE;
567
499
if (retry_count++ < net->retry_count)
571
if (drizzleclient_vio_errno(net->vio) == EINTR)
503
if (vio_errno(net->vio) == SOCKET_EINTR)
575
net->error= 2; /* Close socket */
576
net->last_errno= (interrupted ? CR_NET_WRITE_INTERRUPTED :
577
CR_NET_ERROR_ON_WRITE);
507
net->error= 2; /* Close socket */
508
net->last_errno= (interrupted ? ER_NET_WRITE_INTERRUPTED :
509
ER_NET_ERROR_ON_WRITE);
581
current_session->status_var.bytes_sent+= length;
513
update_statistics(thd_increment_bytes_sent(length));
584
if ((net->compress) && (packet != NULL))
585
free((char*) packet);
517
my_free((char*) packet,MYF(0));
586
518
net->reading_or_writing=0;
520
if (net->write_timeout)
521
error= setsockopt(net->vio->sd, SOL_SOCKET, SO_RCVTIMEO,
522
&backtime, (socklen_t)sizeof(struct timeval));
588
524
return(((int) (pos != end)));
593
Reads one packet to net->buff + net->where_b.
594
Long packets are handled by drizzleclient_net_read().
595
This function reallocates the net->buff buffer if necessary.
529
Reads one packet to net->buff + net->where_b.
530
Long packets are handled by my_net_read().
531
This function reallocates the net->buff buffer if necessary.
598
Returns length of packet.
534
Returns length of packet.
602
538
my_real_read(NET *net, size_t *complen)
606
uint32_t i,retry_count=0;
607
size_t len=packet_error;
542
uint i,retry_count=0;
543
ulong len=packet_error;
608
544
uint32_t remain= (net->compress ? NET_HEADER_SIZE+COMP_HEADER_SIZE :
546
/* Backup of the original SO_RCVTIMEO timeout */
547
struct timeval backtime;
613
552
net->reading_or_writing= 1;
614
/* Read timeout is set in drizzleclient_net_set_read_timeout */
616
pos = net->buff + net->where_b; /* net->packet -4 */
553
/* Read timeout is set in my_net_set_read_timeout */
555
pos = net->buff + net->where_b; /* net->packet -4 */
558
/* Check for error, currently assert */
559
if (net->read_timeout)
561
struct timeval waittime;
564
waittime.tv_sec= net->read_timeout;
567
memset(&backtime, 0, sizeof(struct timeval));
568
length= sizeof(struct timeval);
569
error= getsockopt(net->vio->sd, SOL_SOCKET, SO_RCVTIMEO,
573
perror("getsockopt");
576
error= setsockopt(net->vio->sd, SOL_SOCKET, SO_RCVTIMEO,
577
&waittime, (socklen_t)sizeof(struct timeval));
618
581
for (i= 0; i < 2 ; i++)
620
583
while (remain > 0)
622
585
/* First read is done with non blocking mode */
623
if ((long) (length= drizzleclient_vio_read(net->vio, pos, remain)) <= 0L)
586
if ((long) (length= vio_read(net->vio, pos, remain)) <= 0L)
625
if (net->vio == NULL)
628
const bool interrupted = drizzleclient_vio_should_retry(net->vio);
588
bool interrupted = vio_should_retry(net->vio);
631
{ /* Probably in MIT threads */
591
{ /* Probably in MIT threads */
632
592
if (retry_count++ < net->retry_count)
635
if (drizzleclient_vio_errno(net->vio) == EINTR)
595
if (vio_errno(net->vio) == SOCKET_EINTR)
639
599
len= packet_error;
640
net->error= 2; /* Close socket */
641
net->last_errno= (drizzleclient_vio_was_interrupted(net->vio) ?
642
CR_NET_READ_INTERRUPTED :
600
net->error= 2; /* Close socket */
601
net->last_errno= (vio_was_interrupted(net->vio) ?
602
ER_NET_READ_INTERRUPTED :
647
606
remain -= (uint32_t) length;
649
current_session->status_var.bytes_received+= length;
608
update_statistics(thd_increment_bytes_received(length));
652
{ /* First parts is packet length */
611
{ /* First parts is packet length */
655
if (net->buff[net->where_b + 3] != (unsigned char) net->pkt_nr)
614
if (net->buff[net->where_b + 3] != (uchar) net->pkt_nr)
657
616
len= packet_error;
658
617
/* Not a NET error on the client. XXX: why? */
697
Read a packet from the client/server and return it without the internal
700
If the packet is the first packet of a multi-packet packet
701
(which is indicated by the length of the packet = 0xffffff) then
702
all sub packets are read and concatenated.
704
If the packet was compressed, its uncompressed and the length of the
705
uncompressed packet is returned.
708
The function returns the length of the found packet or packet_error.
709
net->read_pos points to the read data.
660
Read a packet from the client/server and return it without the internal
663
If the packet is the first packet of a multi-packet packet
664
(which is indicated by the length of the packet = 0xffffff) then
665
all sub packets are read and concatenated.
667
If the packet was compressed, its uncompressed and the length of the
668
uncompressed packet is returned.
671
The function returns the length of the found packet or packet_error.
672
net->read_pos points to the read data.
713
drizzleclient_net_read(NET *net)
676
my_net_read(NET *net)
715
678
size_t len, complen;
720
683
if (len == MAX_PACKET_LENGTH)
722
685
/* First packet of a multi-packet. Concatenate the packets */
723
uint32_t save_pos = net->where_b;
686
ulong save_pos = net->where_b;
724
687
size_t total_length= 0;
729
len = my_real_read(net,&complen);
692
len = my_real_read(net,&complen);
730
693
} while (len == MAX_PACKET_LENGTH);
731
694
if (len != packet_error)
733
696
net->where_b = save_pos;
735
698
net->read_pos = net->buff + net->where_b;
736
699
if (len != packet_error)
737
net->read_pos[len]=0; /* Safeguard for drizzleclient_use_result */
700
net->read_pos[len]=0; /* Safeguard for drizzle_use_result */
742
705
/* We are using the compressed protocol */
745
uint32_t start_of_packet;
746
uint32_t first_packet_offset;
747
uint32_t read_length, multi_byte_packet=0;
708
ulong start_of_packet;
709
ulong first_packet_offset;
710
uint read_length, multi_byte_packet=0;
749
712
if (net->remain_in_buf)
751
buf_length= net->buf_length; /* Data left in old packet */
714
buf_length= net->buf_length; /* Data left in old packet */
752
715
first_packet_offset= start_of_packet= (net->buf_length -
754
717
/* Restore the character that was overwritten by the end 0 */
755
718
net->buff[start_of_packet]= net->save_char;
766
729
if (buf_length - start_of_packet >= NET_HEADER_SIZE)
768
read_length = uint3korr(net->buff+start_of_packet);
771
/* End of multi-byte packet */
772
start_of_packet += NET_HEADER_SIZE;
775
if (read_length + NET_HEADER_SIZE <= buf_length - start_of_packet)
777
if (multi_byte_packet)
779
/* Remove packet header for second packet */
780
memmove(net->buff + first_packet_offset + start_of_packet,
781
net->buff + first_packet_offset + start_of_packet +
783
buf_length - start_of_packet);
784
start_of_packet += read_length;
785
buf_length -= NET_HEADER_SIZE;
788
start_of_packet+= read_length + NET_HEADER_SIZE;
731
read_length = uint3korr(net->buff+start_of_packet);
734
/* End of multi-byte packet */
735
start_of_packet += NET_HEADER_SIZE;
738
if (read_length + NET_HEADER_SIZE <= buf_length - start_of_packet)
740
if (multi_byte_packet)
742
/* Remove packet header for second packet */
743
memmove(net->buff + first_packet_offset + start_of_packet,
744
net->buff + first_packet_offset + start_of_packet +
746
buf_length - start_of_packet);
747
start_of_packet += read_length;
748
buf_length -= NET_HEADER_SIZE;
751
start_of_packet+= read_length + NET_HEADER_SIZE;
790
if (read_length != MAX_PACKET_LENGTH) /* last package */
792
multi_byte_packet= 0; /* No last zero len packet */
795
multi_byte_packet= NET_HEADER_SIZE;
796
/* Move data down to read next data packet after current one */
797
if (first_packet_offset)
799
memmove(net->buff,net->buff+first_packet_offset,
800
buf_length-first_packet_offset);
801
buf_length-=first_packet_offset;
802
start_of_packet -= first_packet_offset;
803
first_packet_offset=0;
753
if (read_length != MAX_PACKET_LENGTH) /* last package */
755
multi_byte_packet= 0; /* No last zero len packet */
758
multi_byte_packet= NET_HEADER_SIZE;
759
/* Move data down to read next data packet after current one */
760
if (first_packet_offset)
762
memmove(net->buff,net->buff+first_packet_offset,
763
buf_length-first_packet_offset);
764
buf_length-=first_packet_offset;
765
start_of_packet -= first_packet_offset;
766
first_packet_offset=0;
808
771
/* Move data down to read next data packet after current one */
809
772
if (first_packet_offset)
811
memmove(net->buff,net->buff+first_packet_offset,
812
buf_length-first_packet_offset);
813
buf_length-=first_packet_offset;
814
start_of_packet -= first_packet_offset;
815
first_packet_offset=0;
774
memmove(net->buff,net->buff+first_packet_offset,
775
buf_length-first_packet_offset);
776
buf_length-=first_packet_offset;
777
start_of_packet -= first_packet_offset;
778
first_packet_offset=0;
818
781
net->where_b=buf_length;
819
782
if ((packet_len = my_real_read(net,&complen)) == packet_error)
784
if (my_uncompress(net->buff + net->where_b, packet_len,
824
unsigned char * compbuf= (unsigned char *) malloc(complen);
827
uLongf tmp_complen= complen;
828
int error= uncompress((Bytef*) compbuf, &tmp_complen,
829
(Bytef*) (net->buff + net->where_b),
831
complen= tmp_complen;
835
net->error= 2; /* caller will close socket */
836
net->last_errno= CR_NET_UNCOMPRESS_ERROR;
840
memcpy((net->buff + net->where_b), compbuf, complen);
787
net->error= 2; /* caller will close socket */
788
net->last_errno= ER_NET_UNCOMPRESS_ERROR;
791
buf_length+= complen;
849
buf_length+= complen;
851
794
net->read_pos= net->buff+ first_packet_offset + NET_HEADER_SIZE;
852
795
net->buf_length= buf_length;
853
net->remain_in_buf= (uint32_t) (buf_length - start_of_packet);
854
len = ((uint32_t) (start_of_packet - first_packet_offset) - NET_HEADER_SIZE -
796
net->remain_in_buf= (ulong) (buf_length - start_of_packet);
797
len = ((ulong) (start_of_packet - first_packet_offset) - NET_HEADER_SIZE -
855
798
multi_byte_packet);
856
net->save_char= net->read_pos[len]; /* Must be saved */
857
net->read_pos[len]=0; /* Safeguard for drizzleclient_use_result */
799
net->save_char= net->read_pos[len]; /* Must be saved */
800
net->read_pos[len]=0; /* Safeguard for drizzle_use_result */
863
void drizzleclient_net_set_read_timeout(NET *net, uint32_t timeout)
806
void my_net_set_read_timeout(NET *net, uint timeout)
865
808
net->read_timeout= timeout;
868
drizzleclient_vio_timeout(net->vio, 0, timeout);
810
vio_timeout(net->vio, 0, timeout);
874
void drizzleclient_net_set_write_timeout(NET *net, uint32_t timeout)
815
void my_net_set_write_timeout(NET *net, uint timeout)
876
817
net->write_timeout= timeout;
879
drizzleclient_vio_timeout(net->vio, 1, timeout);
819
vio_timeout(net->vio, 1, timeout);
884
Clear possible error state of struct NET
886
@param net clear the state of the argument
889
void drizzleclient_drizzleclient_net_clear_error(NET *net)
892
net->last_error[0]= '\0';
893
strcpy(net->sqlstate, not_error_sqlstate);
896
} /* namespace drizzle_protocol */