~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to libdrizzle/net_serv.c

  • Committer: Brian Aker
  • Date: 2008-09-04 19:31:00 UTC
  • Revision ID: brian@tangent.org-20080904193100-l849hgghfy4urj43
Changing default character set from this point on.

Show diffs side-by-side

added added

removed removed

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