~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to libdrizzle/net_serv.c

  • Committer: Stewart Smith
  • Date: 2009-01-12 05:43:13 UTC
  • mto: (784.1.4 for-brian)
  • mto: This revision was merged to the branch mainline in revision 785.
  • Revision ID: stewart@flamingspork.com-20090112054313-edk6kpf4l6kpz4j7
fix archive_basic for drizzle

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/* Copyright (C) 2000 MySQL AB
2
 
 
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.
6
 
 
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.
11
 
 
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 */
15
 
 
16
 
/*
17
 
  HFTODO this must be hidden if we don't want client capabilities in 
18
 
  embedded library
 
1
/* - mode: c; c-basic-offset: 2; indent-tabs-mode: nil; -*-
 
2
 *  vim:expandtab:shiftwidth=2:tabstop=2:smarttab:
 
3
 *
 
4
 *  Copyright (C) 2008 Sun Microsystems, Inc.
 
5
 *
 
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.
 
10
 *
 
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.
 
15
 *
 
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
19
19
 */
 
20
 
20
21
#include <drizzled/global.h>
21
 
#include <drizzle.h>
22
 
#include <drizzled/error.h>
23
 
#include <mysys/my_sys.h>
24
 
#include <vio/violite.h>
 
22
#include "libdrizzle.h"
 
23
#include "libdrizzle_priv.h"
 
24
#include <libdrizzle/errmsg.h>
 
25
#include <libdrizzle/vio.h>
 
26
#include <assert.h>
 
27
#include <stdio.h>
 
28
#include <stdlib.h>
 
29
#include <string.h>
25
30
#include <signal.h>
26
31
#include <errno.h>
 
32
#include <sys/socket.h>
27
33
#include <sys/poll.h>
 
34
#include <zlib.h>
28
35
 
29
36
/*
30
37
  The following handles the differences when this is linked between the
36
43
*/
37
44
 
38
45
 
39
 
#define update_statistics(A)
40
 
#define thd_increment_bytes_sent(N)
41
 
 
42
 
#define TEST_BLOCKING           8
43
46
#define MAX_PACKET_LENGTH (256L*256L*256L-1)
44
47
 
45
48
static bool net_write_buff(NET *net, const unsigned char *packet, uint32_t len);
50
53
bool my_net_init(NET *net, Vio* vio)
51
54
{
52
55
  net->vio = vio;
53
 
  my_net_local_init(net);                       /* Set some limits */
54
 
  if (!(net->buff=(uchar*) my_malloc((size_t) net->max_packet+
55
 
                                     NET_HEADER_SIZE + COMP_HEADER_SIZE,
56
 
                                     MYF(MY_WME))))
 
56
  my_net_local_init(net);            /* Set some limits */
 
57
  if (!(net->buff=(unsigned char*) malloc((size_t) net->max_packet+
 
58
                                          NET_HEADER_SIZE + COMP_HEADER_SIZE)))
57
59
    return(1);
58
60
  net->buff_end=net->buff+net->max_packet;
59
61
  net->error=0; net->return_status=0;
65
67
  net->last_errno=0;
66
68
  net->unused= 0;
67
69
 
68
 
  if (vio != 0)                                 /* If real connection */
 
70
  if (vio != 0)                    /* If real connection */
69
71
  {
70
 
    net->fd  = vio_fd(vio);                     /* For perl DBI/DBD */
 
72
    net->fd  = vio_fd(vio);            /* For perl DBI/DBD */
71
73
    vio_fastsend(vio);
72
74
  }
73
75
  return(0);
74
76
}
75
77
 
 
78
bool net_init_sock(NET * net, int sock, int flags)
 
79
{
 
80
 
 
81
  Vio *vio_tmp= vio_new(sock, VIO_TYPE_TCPIP, flags);
 
82
  if (vio_tmp == NULL)
 
83
    return true;
 
84
  else
 
85
    if (my_net_init(net, vio_tmp))
 
86
    {
 
87
      /* Only delete the temporary vio if we didn't already attach it to the
 
88
       * NET object.
 
89
       */
 
90
      if (vio_tmp && (net->vio != vio_tmp))
 
91
        vio_delete(vio_tmp);
 
92
      else
 
93
      {
 
94
        (void) shutdown(sock, SHUT_RDWR);
 
95
        (void) close(sock);
 
96
      }
 
97
      return true;
 
98
    }
 
99
  return false;
 
100
}
76
101
 
77
102
void net_end(NET *net)
78
103
{
79
 
  my_free(net->buff,MYF(MY_ALLOW_ZERO_PTR));
80
 
  net->buff=0;
 
104
  if (net->buff != NULL)
 
105
    free(net->buff);
 
106
  net->buff= NULL;
81
107
  return;
82
108
}
83
109
 
 
110
void net_close(NET *net)
 
111
{
 
112
  if (net->vio != NULL)
 
113
  {
 
114
    vio_delete(net->vio);
 
115
    net->vio= 0;
 
116
  }
 
117
}
 
118
 
 
119
bool net_peer_addr(NET *net, char *buf, uint16_t *port, size_t buflen)
 
120
{
 
121
  return vio_peer_addr(net->vio, buf, port, buflen);
 
122
}
 
123
 
 
124
void net_keepalive(NET *net, bool flag)
 
125
{
 
126
  vio_keepalive(net->vio, flag);
 
127
}
 
128
 
 
129
int net_get_sd(NET *net)
 
130
{
 
131
  return net->vio->sd;
 
132
}
 
133
 
 
134
bool net_should_close(NET *net)
 
135
{
 
136
  return net->error || (net->vio == 0);
 
137
}
 
138
 
 
139
bool net_more_data(NET *net)
 
140
{
 
141
  return (net->vio == 0 || net->vio->read_pos < net->vio->read_end);
 
142
}
84
143
 
85
144
/** Realloc the packet buffer. */
86
145
 
87
146
bool net_realloc(NET *net, size_t length)
88
147
{
89
 
  uchar *buff;
 
148
  unsigned char *buff;
90
149
  size_t pkt_length;
91
150
 
92
151
  if (length >= net->max_packet_size)
93
152
  {
94
153
    /* @todo: 1 and 2 codes are identical. */
95
154
    net->error= 1;
96
 
    net->last_errno= ER_NET_PACKET_TOO_LARGE;
 
155
    net->last_errno= CR_NET_PACKET_TOO_LARGE;
97
156
    return(1);
98
157
  }
99
 
  pkt_length = (length+IO_SIZE-1) & ~(IO_SIZE-1); 
 
158
  pkt_length = (length+IO_SIZE-1) & ~(IO_SIZE-1);
100
159
  /*
101
160
    We must allocate some extra bytes for the end 0 and to be able to
102
161
    read big compressed blocks
103
162
  */
104
 
  if (!(buff= (uchar*) my_realloc((char*) net->buff, pkt_length +
105
 
                                  NET_HEADER_SIZE + COMP_HEADER_SIZE,
106
 
                                  MYF(MY_WME))))
 
163
  if (!(buff= (unsigned char*) realloc((char*) net->buff, pkt_length +
 
164
                               NET_HEADER_SIZE + COMP_HEADER_SIZE)))
107
165
  {
108
166
    /* @todo: 1 and 2 codes are identical. */
109
167
    net->error= 1;
110
 
    net->last_errno= ER_OUT_OF_RESOURCES;
 
168
    net->last_errno= CR_OUT_OF_MEMORY;
111
169
    /* In the server the error is reported by MY_WME flag. */
112
170
    return(1);
113
171
  }
118
176
 
119
177
 
120
178
/**
121
 
  Check if there is any data to be read from the socket.
122
 
 
123
 
  @param sd   socket descriptor
124
 
 
125
 
  @retval
126
 
    0  No data to read
127
 
  @retval
128
 
    1  Data or EOF to read
129
 
  @retval
130
 
    -1   Don't know if data is ready or not
 
179
   Check if there is any data to be read from the socket.
 
180
 
 
181
   @param sd   socket descriptor
 
182
 
 
183
   @retval
 
184
   0  No data to read
 
185
   @retval
 
186
   1  Data or EOF to read
 
187
   @retval
 
188
   -1   Don't know if data is ready or not
131
189
*/
132
190
 
133
191
static bool net_data_is_ready(int sd)
145
203
}
146
204
 
147
205
/**
148
 
  Remove unwanted characters from connection
149
 
  and check if disconnected.
150
 
 
151
 
    Read from socket until there is nothing more to read. Discard
152
 
    what is read.
153
 
 
154
 
    If there is anything when to read 'net_clear' is called this
155
 
    normally indicates an error in the protocol.
156
 
 
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.
160
 
 
161
 
  @param net                    NET handler
162
 
  @param clear_buffer           if <> 0, then clear all data from comm buff
 
206
   Remove unwanted characters from connection
 
207
   and check if disconnected.
 
208
 
 
209
   Read from socket until there is nothing more to read. Discard
 
210
   what is read.
 
211
 
 
212
   If there is anything when to read 'net_clear' is called this
 
213
   normally indicates an error in the protocol.
 
214
 
 
215
   When connection is properly closed (for TCP it means with
 
216
   a FIN packet), then select() considers a socket "ready to read",
 
217
   in the sense that there's EOF to read, but read() returns 0.
 
218
 
 
219
   @param net            NET handler
 
220
   @param clear_buffer           if <> 0, then clear all data from comm buff
163
221
*/
164
222
 
165
223
void net_clear(NET *net, bool clear_buffer)
170
228
    {
171
229
      /* The socket is ready */
172
230
      if (vio_read(net->vio, net->buff,
173
 
                                  (size_t) net->max_packet) <= 0)
 
231
                   (size_t) net->max_packet) <= 0)
174
232
      {
175
233
        net->error= 2;
176
234
        break;
177
235
      }
178
236
    }
179
237
  }
180
 
  net->pkt_nr=net->compress_pkt_nr=0;           /* Ready for new command */
 
238
  net->pkt_nr=net->compress_pkt_nr=0;        /* Ready for new command */
181
239
  net->write_pos=net->buff;
182
240
  return;
183
241
}
190
248
  bool error= 0;
191
249
  if (net->buff != net->write_pos)
192
250
  {
193
 
    error=test(net_real_write(net, net->buff,
194
 
                              (size_t) (net->write_pos - net->buff)));
 
251
    error=net_real_write(net, net->buff,
 
252
                         (size_t) (net->write_pos - net->buff)) ? 1 : 0;
195
253
    net->write_pos=net->buff;
196
254
  }
197
255
  /* Sync packet number if using compression */
202
260
 
203
261
 
204
262
/*****************************************************************************
205
 
** Write something to server/client buffer
206
 
*****************************************************************************/
 
263
 ** Write something to server/client buffer
 
264
 *****************************************************************************/
207
265
 
208
266
/**
209
 
  Write a logical packet with packet header.
210
 
 
211
 
  Format: Packet length (3 bytes), packet number(1 byte)
212
 
  When compression is used a 3 byte compression length is added
213
 
 
214
 
  @note
215
 
    If compression is used the original package is modified!
 
267
   Write a logical packet with packet header.
 
268
 
 
269
   Format: Packet length (3 bytes), packet number(1 byte)
 
270
   When compression is used a 3 byte compression length is added
 
271
 
 
272
   @note
 
273
   If compression is used the original package is modified!
216
274
*/
217
275
 
218
276
bool
219
 
my_net_write(NET *net,const uchar *packet,size_t len)
 
277
my_net_write(NET *net,const unsigned char *packet,size_t len)
220
278
{
221
 
  uchar buff[NET_HEADER_SIZE];
 
279
  unsigned char buff[NET_HEADER_SIZE];
222
280
  if (unlikely(!net->vio)) /* nowhere to write */
223
281
    return 0;
224
282
  /*
230
288
  {
231
289
    const uint32_t z_size = MAX_PACKET_LENGTH;
232
290
    int3store(buff, z_size);
233
 
    buff[3]= (uchar) net->pkt_nr++;
 
291
    buff[3]= (unsigned char) net->pkt_nr++;
234
292
    if (net_write_buff(net, buff, NET_HEADER_SIZE) ||
235
 
        net_write_buff(net, packet, z_size))
 
293
        net_write_buff(net, packet, z_size))
236
294
      return 1;
237
295
    packet += z_size;
238
296
    len-=     z_size;
239
297
  }
240
298
  /* Write last packet */
241
299
  int3store(buff,len);
242
 
  buff[3]= (uchar) net->pkt_nr++;
 
300
  buff[3]= (unsigned char) net->pkt_nr++;
243
301
  if (net_write_buff(net, buff, NET_HEADER_SIZE))
244
302
    return 1;
245
 
  return test(net_write_buff(net,packet,len));
 
303
  return net_write_buff(net,packet,len) ? 1 : 0;
246
304
}
247
305
 
248
306
/**
249
 
  Send a command to the server.
250
 
 
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.
254
 
 
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
257
 
    packet.
258
 
  
259
 
    This function will split big packets into sub-packets if needed.
260
 
    (Each sub packet can only be 2^24 bytes)
261
 
 
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
268
 
 
269
 
  @retval
270
 
    0   ok
271
 
  @retval
272
 
    1   error
 
307
   Send a command to the server.
 
308
 
 
309
   The reason for having both header and packet is so that libdrizzle
 
310
   can easy add a header to a special command (like prepared statements)
 
311
   without having to re-alloc the string.
 
312
 
 
313
   As the command is part of the first data packet, we have to do some data
 
314
   juggling to put the command in there, without having to create a new
 
315
   packet.
 
316
 
 
317
   This function will split big packets into sub-packets if needed.
 
318
   (Each sub packet can only be 2^24 bytes)
 
319
 
 
320
   @param net        NET handler
 
321
   @param command    Command in MySQL server (enum enum_server_command)
 
322
   @param header    Header to write after command
 
323
   @param head_len    Length of header
 
324
   @param packet    Query or parameter to query
 
325
   @param len        Length of packet
 
326
 
 
327
   @retval
 
328
   0    ok
 
329
   @retval
 
330
   1    error
273
331
*/
274
332
 
275
333
bool
276
 
net_write_command(NET *net,uchar command,
277
 
                  const uchar *header, size_t head_len,
278
 
                  const uchar *packet, size_t len)
 
334
net_write_command(NET *net,unsigned char command,
 
335
                  const unsigned char *header, size_t head_len,
 
336
                  const unsigned char *packet, size_t len)
279
337
{
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;
 
338
  uint32_t length=len+1+head_len;            /* 1 extra byte for command */
 
339
  unsigned char buff[NET_HEADER_SIZE+1];
 
340
  uint32_t header_size=NET_HEADER_SIZE+1;
283
341
 
284
 
  buff[4]=command;                              /* For first packet */
 
342
  buff[4]=command;                /* For first packet */
285
343
 
286
344
  if (length >= MAX_PACKET_LENGTH)
287
345
  {
290
348
    do
291
349
    {
292
350
      int3store(buff, MAX_PACKET_LENGTH);
293
 
      buff[3]= (uchar) net->pkt_nr++;
 
351
      buff[3]= (unsigned char) net->pkt_nr++;
294
352
      if (net_write_buff(net, buff, header_size) ||
295
 
          net_write_buff(net, header, head_len) ||
296
 
          net_write_buff(net, packet, len))
297
 
        return(1);
 
353
          net_write_buff(net, header, head_len) ||
 
354
          net_write_buff(net, packet, len))
 
355
        return(1);
298
356
      packet+= len;
299
357
      length-= MAX_PACKET_LENGTH;
300
358
      len= MAX_PACKET_LENGTH;
301
359
      head_len= 0;
302
360
      header_size= NET_HEADER_SIZE;
303
361
    } while (length >= MAX_PACKET_LENGTH);
304
 
    len=length;                                 /* Data left to be written */
 
362
    len=length;                    /* Data left to be written */
305
363
  }
306
364
  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)));
 
365
  buff[3]= (unsigned char) net->pkt_nr++;
 
366
  return((net_write_buff(net, buff, header_size) ||
 
367
          (head_len && net_write_buff(net, header, head_len)) ||
 
368
          net_write_buff(net, packet, len) || net_flush(net)) ? 1 : 0 );
311
369
}
312
370
 
313
371
/**
314
 
  Caching the data in a local buffer before sending it.
 
372
   Caching the data in a local buffer before sending it.
315
373
 
316
374
   Fill up net->buffer and send it to the client when full.
317
375
 
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
321
 
    sending data.
322
 
 
323
 
  @param net            Network handler
324
 
  @param packet Packet to send
325
 
  @param len            Length of packet
326
 
 
327
 
  @note
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.
332
 
 
333
 
  @retval
334
 
    0   ok
335
 
  @retval
336
 
    1
 
376
   If the rest of the to-be-sent-packet is bigger than buffer,
 
377
   send it in one big block (to avoid copying to internal buffer).
 
378
   If not, copy the rest of the data to the buffer and return without
 
379
   sending data.
 
380
 
 
381
   @param net        Network handler
 
382
   @param packet    Packet to send
 
383
   @param len        Length of packet
 
384
 
 
385
   @note
 
386
   The cached buffer can be sent as it is with 'net_flush()'.
 
387
   In this code we have to be careful to not send a packet longer than
 
388
   MAX_PACKET_LENGTH to net_real_write() if we are using the compressed
 
389
   protocol as we store the length of the compressed packet in 3 bytes.
 
390
 
 
391
   @retval
 
392
   0    ok
 
393
   @retval
 
394
   1
337
395
*/
338
396
 
339
397
static bool
351
409
    {
352
410
      /* Fill up already used packet and write it */
353
411
      memcpy(net->write_pos,packet,left_length);
354
 
      if (net_real_write(net, net->buff, 
355
 
                         (size_t) (net->write_pos - net->buff) + left_length))
356
 
        return 1;
 
412
      if (net_real_write(net, net->buff,
 
413
                         (size_t) (net->write_pos - net->buff) + left_length))
 
414
        return 1;
357
415
      net->write_pos= net->buff;
358
416
      packet+= left_length;
359
417
      len-= left_length;
361
419
    if (net->compress)
362
420
    {
363
421
      /*
364
 
        We can't have bigger packets than 16M with compression
365
 
        Because the uncompressed length is stored in 3 bytes
 
422
        We can't have bigger packets than 16M with compression
 
423
        Because the uncompressed length is stored in 3 bytes
366
424
      */
367
425
      left_length= MAX_PACKET_LENGTH;
368
426
      while (len > left_length)
369
427
      {
370
 
        if (net_real_write(net, packet, left_length))
371
 
          return 1;
372
 
        packet+= left_length;
373
 
        len-= left_length;
 
428
        if (net_real_write(net, packet, left_length))
 
429
          return 1;
 
430
        packet+= left_length;
 
431
        len-= left_length;
374
432
      }
375
433
    }
376
434
    if (len > net->max_packet)
384
442
 
385
443
 
386
444
/**
387
 
  Read and write one packet using timeouts.
388
 
  If needed, the packet is compressed before sending.
 
445
   Read and write one packet using timeouts.
 
446
   If needed, the packet is compressed before sending.
389
447
 
390
 
  @todo
391
 
    - TODO is it needed to set this variable if we have no socket
 
448
   @todo
 
449
   - TODO is it needed to set this variable if we have no socket
392
450
*/
393
451
 
394
452
/*
396
454
  in the server, yield to another process and come back later.
397
455
*/
398
456
int
399
 
net_real_write(NET *net,const uchar *packet, size_t len)
 
457
net_real_write(NET *net, const unsigned char *packet, size_t len)
400
458
{
401
459
  size_t length;
402
 
  const uchar *pos,*end;
403
 
  uint retry_count= 0;
 
460
  const unsigned char *pos, *end;
 
461
  uint32_t retry_count= 0;
404
462
 
405
463
  /* Backup of the original SO_RCVTIMEO timeout */
406
 
  struct timeval backtime;
 
464
#ifndef __sun
 
465
  struct timespec backtime;
407
466
  int error;
 
467
#endif
408
468
 
409
469
  if (net->error == 2)
410
 
    return(-1);                         /* socket can't be used */
 
470
    return(-1);                /* socket can't be used */
411
471
 
412
472
  net->reading_or_writing=2;
413
473
  if (net->compress)
414
474
  {
415
475
    size_t complen;
416
 
    uchar *b;
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))))
 
476
    unsigned char *b;
 
477
    const uint32_t header_length=NET_HEADER_SIZE+COMP_HEADER_SIZE;
 
478
    if (!(b= (unsigned char*) malloc(len + NET_HEADER_SIZE +
 
479
                             COMP_HEADER_SIZE)))
420
480
    {
421
481
      net->error= 2;
422
 
      net->last_errno= ER_OUT_OF_RESOURCES;
 
482
      net->last_errno= CR_OUT_OF_MEMORY;
423
483
      /* In the server, the error is reported by MY_WME flag. */
424
484
      net->reading_or_writing= 0;
425
485
      return(1);
426
486
    }
427
487
    memcpy(b+header_length,packet,len);
428
488
 
429
 
    if (my_compress(b+header_length, &len, &complen))
 
489
    complen= len * 120 / 100 + 12;
 
490
    unsigned char * compbuf= (unsigned char *) malloc(complen);
 
491
    if (compbuf != NULL)
 
492
    {
 
493
      uLongf tmp_complen= complen;
 
494
      int res= compress((Bytef*) compbuf, &tmp_complen,
 
495
                        (Bytef*) (b+header_length),
 
496
                        len);
 
497
      complen= tmp_complen;
 
498
 
 
499
      free(compbuf);
 
500
 
 
501
      if ((res != Z_OK) || (complen >= len))
 
502
        complen= 0;
 
503
      else
 
504
      {
 
505
        size_t tmplen= complen;
 
506
        complen= len;
 
507
        len= tmplen;
 
508
      }
 
509
    }
 
510
    else
 
511
    {
430
512
      complen=0;
 
513
    }
431
514
    int3store(&b[NET_HEADER_SIZE],complen);
432
515
    int3store(b,len);
433
 
    b[3]=(uchar) (net->compress_pkt_nr++);
 
516
    b[3]=(unsigned char) (net->compress_pkt_nr++);
434
517
    len+= header_length;
435
518
    packet= b;
436
519
  }
437
520
 
 
521
#ifndef __sun
438
522
  /* Check for error, currently assert */
439
523
  if (net->write_timeout)
440
524
  {
441
 
    struct timeval waittime;
 
525
    struct timespec waittime;
442
526
    socklen_t length;
443
527
 
444
528
    waittime.tv_sec= net->write_timeout;
445
 
    waittime.tv_usec= 0;
 
529
    waittime.tv_nsec= 0;
446
530
 
447
 
    memset(&backtime, 0, sizeof(struct timeval));
448
 
    length= sizeof(struct timeval);
449
 
    error= getsockopt(net->vio->sd, SOL_SOCKET, SO_RCVTIMEO, 
 
531
    memset(&backtime, 0, sizeof(struct timespec));
 
532
    length= sizeof(struct timespec);
 
533
    error= getsockopt(net->vio->sd, SOL_SOCKET, SO_RCVTIMEO,
450
534
                      &backtime, &length);
451
535
    if (error != 0)
452
536
    {
453
537
      perror("getsockopt");
454
538
      assert(error == 0);
455
539
    }
456
 
    error= setsockopt(net->vio->sd, SOL_SOCKET, SO_RCVTIMEO, 
457
 
                      &waittime, (socklen_t)sizeof(struct timeval));
 
540
    error= setsockopt(net->vio->sd, SOL_SOCKET, SO_RCVTIMEO,
 
541
                      &waittime, (socklen_t)sizeof(struct timespec));
458
542
    assert(error == 0);
459
543
  }
 
544
#endif
 
545
 
460
546
  pos= packet;
461
547
  end=pos+len;
462
548
  /* Loop until we have read everything */
463
549
  while (pos != end)
464
550
  {
465
 
    if ((long) (length= vio_write(net->vio,pos,(size_t) (end-pos))) <= 0)
 
551
    assert(pos);
 
552
    if ((long) (length= vio_write(net->vio, pos, (size_t) (end-pos))) <= 0)
466
553
    {
467
554
      const bool interrupted= vio_should_retry(net->vio);
468
 
      /* 
469
 
        If we read 0, or we were interrupted this means that 
470
 
        we need to switch to blocking mode and wait until the timeout 
 
555
      /*
 
556
        If we read 0, or we were interrupted this means that
 
557
        we need to switch to blocking mode and wait until the timeout
471
558
        on the socket kicks in.
472
559
      */
473
560
      if ((interrupted || length == 0))
479
566
          if (vio_should_retry(net->vio) && retry_count++ < net->retry_count)
480
567
            continue;
481
568
          net->error= 2;                     /* Close socket */
482
 
          net->last_errno= ER_NET_PACKET_TOO_LARGE;
 
569
          net->last_errno= CR_NET_PACKET_TOO_LARGE;
483
570
          goto end;
484
571
        }
485
572
        retry_count=0;
490
577
        if (retry_count++ < net->retry_count)
491
578
          continue;
492
579
      }
493
 
      
494
 
      if (vio_errno(net->vio) == SOCKET_EINTR)
 
580
 
 
581
      if (vio_errno(net->vio) == EINTR)
495
582
      {
496
583
        continue;
497
584
      }
498
 
      net->error= 2;                            /* Close socket */
499
 
      net->last_errno= (interrupted ? ER_NET_WRITE_INTERRUPTED :
500
 
                        ER_NET_ERROR_ON_WRITE);
 
585
      net->error= 2;                /* Close socket */
 
586
      net->last_errno= (interrupted ? CR_NET_WRITE_INTERRUPTED :
 
587
                        CR_NET_ERROR_ON_WRITE);
501
588
      break;
502
589
    }
503
590
    pos+=length;
504
 
    update_statistics(thd_increment_bytes_sent(length));
505
591
  }
506
 
 end:
507
 
  if (net->compress)
508
 
    my_free((char*) packet,MYF(0));
 
592
end:
 
593
  if ((net->compress) && (packet != NULL))
 
594
    free((char*) packet);
509
595
  net->reading_or_writing=0;
510
596
 
 
597
#ifndef __sun
511
598
  if (net->write_timeout)
512
 
    error= setsockopt(net->vio->sd, SOL_SOCKET, SO_RCVTIMEO, 
513
 
                      &backtime, (socklen_t)sizeof(struct timeval));
 
599
    error= setsockopt(net->vio->sd, SOL_SOCKET, SO_RCVTIMEO,
 
600
                      &backtime, (socklen_t)sizeof(struct timespec));
 
601
#endif
514
602
 
515
603
  return(((int) (pos != end)));
516
604
}
517
605
 
518
606
 
519
607
/**
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.
 
608
   Reads one packet to net->buff + net->where_b.
 
609
   Long packets are handled by my_net_read().
 
610
   This function reallocates the net->buff buffer if necessary.
523
611
 
524
 
  @return
525
 
    Returns length of packet.
 
612
   @return
 
613
   Returns length of packet.
526
614
*/
527
615
 
528
616
static uint32_t
529
617
my_real_read(NET *net, size_t *complen)
530
618
{
531
 
  uchar *pos;
 
619
  unsigned char *pos;
532
620
  size_t length;
533
 
  uint i,retry_count=0;
 
621
  uint32_t i,retry_count=0;
534
622
  uint32_t len=packet_error;
535
623
  uint32_t remain= (net->compress ? NET_HEADER_SIZE+COMP_HEADER_SIZE :
536
 
                  NET_HEADER_SIZE);
 
624
                    NET_HEADER_SIZE);
 
625
 
 
626
#ifndef __sun
537
627
  /* Backup of the original SO_RCVTIMEO timeout */
538
 
  struct timeval backtime;
 
628
  struct timespec backtime;
539
629
  int error= 0;
 
630
#endif
540
631
 
541
632
  *complen = 0;
542
633
 
543
634
  net->reading_or_writing= 1;
544
635
  /* Read timeout is set in my_net_set_read_timeout */
545
636
 
546
 
  pos = net->buff + net->where_b;               /* net->packet -4 */
547
 
 
548
 
 
 
637
  pos = net->buff + net->where_b;        /* net->packet -4 */
 
638
 
 
639
 
 
640
#ifndef __sun
549
641
  /* Check for error, currently assert */
550
642
  if (net->read_timeout)
551
643
  {
552
 
    struct timeval waittime;
 
644
    struct timespec waittime;
553
645
    socklen_t length;
554
646
 
555
647
    waittime.tv_sec= net->read_timeout;
556
 
    waittime.tv_usec= 0;
 
648
    waittime.tv_nsec= 0;
557
649
 
558
 
    memset(&backtime, 0, sizeof(struct timeval));
559
 
    length= sizeof(struct timeval);
560
 
    error= getsockopt(net->vio->sd, SOL_SOCKET, SO_RCVTIMEO, 
 
650
    memset(&backtime, 0, sizeof(struct timespec));
 
651
    length= sizeof(struct timespec);
 
652
    error= getsockopt(net->vio->sd, SOL_SOCKET, SO_RCVTIMEO,
561
653
                      &backtime, &length);
562
654
    if (error != 0)
563
655
    {
564
656
      perror("getsockopt");
565
657
      assert(error == 0);
566
658
    }
567
 
    error= setsockopt(net->vio->sd, SOL_SOCKET, SO_RCVTIMEO, 
568
 
                      &waittime, (socklen_t)sizeof(struct timeval));
 
659
    error= setsockopt(net->vio->sd, SOL_SOCKET, SO_RCVTIMEO,
 
660
                      &waittime, (socklen_t)sizeof(struct timespec));
569
661
    assert(error == 0);
570
662
  }
 
663
#endif
571
664
 
572
665
  for (i= 0; i < 2 ; i++)
573
666
  {
579
672
        const bool interrupted = vio_should_retry(net->vio);
580
673
 
581
674
        if (interrupted)
582
 
        {                                       /* Probably in MIT threads */
 
675
        {                    /* Probably in MIT threads */
583
676
          if (retry_count++ < net->retry_count)
584
677
            continue;
585
678
        }
586
 
        if (vio_errno(net->vio) == SOCKET_EINTR)
 
679
        if (vio_errno(net->vio) == EINTR)
587
680
        {
588
681
          continue;
589
682
        }
590
683
        len= packet_error;
591
 
        net->error= 2;                          /* Close socket */
 
684
        net->error= 2;                /* Close socket */
592
685
        net->last_errno= (vio_was_interrupted(net->vio) ?
593
 
                          ER_NET_READ_INTERRUPTED :
594
 
                          ER_NET_READ_ERROR);
595
 
        my_error(net->last_errno, MYF(0));
 
686
                          CR_NET_READ_INTERRUPTED :
 
687
                          CR_NET_READ_ERROR);
 
688
        ER(net->last_errno);
596
689
        goto end;
597
690
      }
598
691
      remain -= (uint32_t) length;
599
692
      pos+= length;
600
 
      update_statistics(thd_increment_bytes_received(length));
601
693
    }
602
694
    if (i == 0)
603
 
    {                                   /* First parts is packet length */
 
695
    {                    /* First parts is packet length */
604
696
      uint32_t helping;
605
697
 
606
 
      if (net->buff[net->where_b + 3] != (uchar) net->pkt_nr)
 
698
      if (net->buff[net->where_b + 3] != (unsigned char) net->pkt_nr)
607
699
      {
608
700
        len= packet_error;
609
701
        /* Not a NET error on the client. XXX: why? */
620
712
      }
621
713
 
622
714
      len=uint3korr(net->buff+net->where_b);
623
 
      if (!len)                         /* End of big multi-packet */
 
715
      if (!len)                /* End of big multi-packet */
624
716
        goto end;
625
717
      helping = max(len,*complen) + net->where_b;
626
718
      /* The necessary size of net->buff */
638
730
  }
639
731
 
640
732
end:
 
733
#ifndef __sun
641
734
  if  (net->read_timeout)
642
 
    error= setsockopt(net->vio->sd, SOL_SOCKET, SO_RCVTIMEO, 
643
 
                      &backtime, (socklen_t)sizeof(struct timeval));
 
735
    error= setsockopt(net->vio->sd, SOL_SOCKET, SO_RCVTIMEO,
 
736
                      &backtime, (socklen_t)sizeof(struct timespec));
644
737
  assert(error == 0);
 
738
#endif
645
739
  net->reading_or_writing= 0;
646
740
 
647
741
  return(len);
649
743
 
650
744
 
651
745
/**
652
 
  Read a packet from the client/server and return it without the internal
653
 
  package header.
654
 
 
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.
658
 
 
659
 
  If the packet was compressed, its uncompressed and the length of the
660
 
  uncompressed packet is returned.
661
 
 
662
 
  @return
663
 
  The function returns the length of the found packet or packet_error.
664
 
  net->read_pos points to the read data.
 
746
   Read a packet from the client/server and return it without the internal
 
747
   package header.
 
748
 
 
749
   If the packet is the first packet of a multi-packet packet
 
750
   (which is indicated by the length of the packet = 0xffffff) then
 
751
   all sub packets are read and concatenated.
 
752
 
 
753
   If the packet was compressed, its uncompressed and the length of the
 
754
   uncompressed packet is returned.
 
755
 
 
756
   @return
 
757
   The function returns the length of the found packet or packet_error.
 
758
   net->read_pos points to the read data.
665
759
*/
666
760
 
667
761
uint32_t
679
773
      size_t total_length= 0;
680
774
      do
681
775
      {
682
 
        net->where_b += len;
683
 
        total_length += len;
684
 
        len = my_real_read(net,&complen);
 
776
        net->where_b += len;
 
777
        total_length += len;
 
778
        len = my_real_read(net,&complen);
685
779
      } while (len == MAX_PACKET_LENGTH);
686
780
      if (len != packet_error)
687
 
        len+= total_length;
 
781
        len+= total_length;
688
782
      net->where_b = save_pos;
689
783
    }
690
784
    net->read_pos = net->buff + net->where_b;
691
785
    if (len != packet_error)
692
 
      net->read_pos[len]=0;             /* Safeguard for drizzle_use_result */
 
786
      net->read_pos[len]=0;        /* Safeguard for drizzle_use_result */
693
787
    return len;
694
788
  }
695
789
  else
699
793
    uint32_t buf_length;
700
794
    uint32_t start_of_packet;
701
795
    uint32_t first_packet_offset;
702
 
    uint read_length, multi_byte_packet=0;
 
796
    uint32_t read_length, multi_byte_packet=0;
703
797
 
704
798
    if (net->remain_in_buf)
705
799
    {
706
 
      buf_length= net->buf_length;              /* Data left in old packet */
 
800
      buf_length= net->buf_length;        /* Data left in old packet */
707
801
      first_packet_offset= start_of_packet= (net->buf_length -
708
 
                                             net->remain_in_buf);
 
802
                                             net->remain_in_buf);
709
803
      /* Restore the character that was overwritten by the end 0 */
710
804
      net->buff[start_of_packet]= net->save_char;
711
805
    }
720
814
 
721
815
      if (buf_length - start_of_packet >= NET_HEADER_SIZE)
722
816
      {
723
 
        read_length = uint3korr(net->buff+start_of_packet);
724
 
        if (!read_length)
725
 
        { 
726
 
          /* End of multi-byte packet */
727
 
          start_of_packet += NET_HEADER_SIZE;
728
 
          break;
729
 
        }
730
 
        if (read_length + NET_HEADER_SIZE <= buf_length - start_of_packet)
731
 
        {
732
 
          if (multi_byte_packet)
733
 
          {
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 +
737
 
                    NET_HEADER_SIZE,
738
 
                    buf_length - start_of_packet);
739
 
            start_of_packet += read_length;
740
 
            buf_length -= NET_HEADER_SIZE;
741
 
          }
742
 
          else
743
 
            start_of_packet+= read_length + NET_HEADER_SIZE;
 
817
        read_length = uint3korr(net->buff+start_of_packet);
 
818
        if (!read_length)
 
819
        {
 
820
          /* End of multi-byte packet */
 
821
          start_of_packet += NET_HEADER_SIZE;
 
822
          break;
 
823
        }
 
824
        if (read_length + NET_HEADER_SIZE <= buf_length - start_of_packet)
 
825
        {
 
826
          if (multi_byte_packet)
 
827
          {
 
828
            /* Remove packet header for second packet */
 
829
            memmove(net->buff + first_packet_offset + start_of_packet,
 
830
                    net->buff + first_packet_offset + start_of_packet +
 
831
                    NET_HEADER_SIZE,
 
832
                    buf_length - start_of_packet);
 
833
            start_of_packet += read_length;
 
834
            buf_length -= NET_HEADER_SIZE;
 
835
          }
 
836
          else
 
837
            start_of_packet+= read_length + NET_HEADER_SIZE;
744
838
 
745
 
          if (read_length != MAX_PACKET_LENGTH) /* last package */
746
 
          {
747
 
            multi_byte_packet= 0;               /* No last zero len packet */
748
 
            break;
749
 
          }
750
 
          multi_byte_packet= NET_HEADER_SIZE;
751
 
          /* Move data down to read next data packet after current one */
752
 
          if (first_packet_offset)
753
 
          {
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;
759
 
          }
760
 
          continue;
761
 
        }
 
839
          if (read_length != MAX_PACKET_LENGTH)    /* last package */
 
840
          {
 
841
            multi_byte_packet= 0;        /* No last zero len packet */
 
842
            break;
 
843
          }
 
844
          multi_byte_packet= NET_HEADER_SIZE;
 
845
          /* Move data down to read next data packet after current one */
 
846
          if (first_packet_offset)
 
847
          {
 
848
            memmove(net->buff,net->buff+first_packet_offset,
 
849
                    buf_length-first_packet_offset);
 
850
            buf_length-=first_packet_offset;
 
851
            start_of_packet -= first_packet_offset;
 
852
            first_packet_offset=0;
 
853
          }
 
854
          continue;
 
855
        }
762
856
      }
763
857
      /* Move data down to read next data packet after current one */
764
858
      if (first_packet_offset)
765
859
      {
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;
 
860
        memmove(net->buff,net->buff+first_packet_offset,
 
861
                buf_length-first_packet_offset);
 
862
        buf_length-=first_packet_offset;
 
863
        start_of_packet -= first_packet_offset;
 
864
        first_packet_offset=0;
771
865
      }
772
866
 
773
867
      net->where_b=buf_length;
774
868
      if ((packet_len = my_real_read(net,&complen)) == packet_error)
775
 
        return packet_error;
776
 
      if (my_uncompress(net->buff + net->where_b, packet_len,
777
 
                        &complen))
 
869
        return packet_error;
 
870
 
 
871
      if (complen)
778
872
      {
779
 
        net->error= 2;                  /* caller will close socket */
780
 
        net->last_errno= ER_NET_UNCOMPRESS_ERROR;
781
 
        return packet_error;
 
873
        unsigned char * compbuf= (unsigned char *) malloc(complen);
 
874
        if (compbuf != NULL)
 
875
        {
 
876
          uLongf tmp_complen= complen;
 
877
          int error= uncompress((Bytef*) compbuf, &tmp_complen,
 
878
                                (Bytef*) (net->buff + net->where_b),
 
879
                                (uLong)packet_len);
 
880
          complen= tmp_complen;
 
881
 
 
882
          if (error != Z_OK)
 
883
          {
 
884
            net->error= 2;            /* caller will close socket */
 
885
            net->last_errno= CR_NET_UNCOMPRESS_ERROR;
 
886
          }
 
887
          else
 
888
          {
 
889
            memcpy((net->buff + net->where_b), compbuf, complen);
 
890
          }
 
891
          free(compbuf);
 
892
        }
782
893
      }
783
 
      buf_length+= complen;
 
894
      else
 
895
        complen= packet_len;
 
896
 
784
897
    }
 
898
    buf_length+= complen;
785
899
 
786
900
    net->read_pos=      net->buff+ first_packet_offset + NET_HEADER_SIZE;
787
901
    net->buf_length=    buf_length;
788
902
    net->remain_in_buf= (uint32_t) (buf_length - start_of_packet);
789
903
    len = ((uint32_t) (start_of_packet - first_packet_offset) - NET_HEADER_SIZE -
790
904
           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 */
 
905
    net->save_char= net->read_pos[len];    /* Must be saved */
 
906
    net->read_pos[len]=0;        /* Safeguard for drizzle_use_result */
793
907
  }
794
908
  return len;
795
 
}
796
 
 
797
 
 
798
 
void my_net_set_read_timeout(NET *net, uint timeout)
 
909
  }
 
910
 
 
911
 
 
912
void my_net_set_read_timeout(NET *net, uint32_t timeout)
799
913
{
800
914
  net->read_timeout= timeout;
 
915
#ifndef __sun
801
916
  if (net->vio)
802
917
    vio_timeout(net->vio, 0, timeout);
 
918
#endif
803
919
  return;
804
920
}
805
921
 
806
922
 
807
 
void my_net_set_write_timeout(NET *net, uint timeout)
 
923
void my_net_set_write_timeout(NET *net, uint32_t timeout)
808
924
{
809
925
  net->write_timeout= timeout;
 
926
#ifndef __sun
810
927
  if (net->vio)
811
928
    vio_timeout(net->vio, 1, timeout);
 
929
#endif
812
930
  return;
813
931
}
 
932
/**
 
933
  Clear possible error state of struct NET
 
934
 
 
935
  @param net  clear the state of the argument
 
936
*/
 
937
 
 
938
void net_clear_error(NET *net)
 
939
{
 
940
  net->last_errno= 0;
 
941
  net->last_error[0]= '\0';
 
942
  strcpy(net->sqlstate, sqlstate_get_not_error());
 
943
}
 
944