~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to libdrizzle/net_serv.c

Merged in changes from Andrey.

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