diff options
Diffstat (limited to 'sql/net_serv.cc')
-rw-r--r-- | sql/net_serv.cc | 156 |
1 files changed, 78 insertions, 78 deletions
diff --git a/sql/net_serv.cc b/sql/net_serv.cc index 1a79679ed7c..e0a0d5b75cf 100644 --- a/sql/net_serv.cc +++ b/sql/net_serv.cc @@ -1,4 +1,5 @@ -/* Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved. +/* Copyright (c) 2000, 2011, Oracle and/or its affiliates. + Copyright (c) 2012, Monty Program Ab This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -51,6 +52,22 @@ #define MYSQL_CLIENT #endif /*EMBEDDED_LIBRARY */ +/* + to reduce the number of ifdef's in the code +*/ +#ifdef EXTRA_DEBUG +#define EXTRA_DEBUG_fprintf fprintf +#define EXTRA_DEBUG_fflush fflush +#else +static void inline EXTRA_DEBUG_fprintf(...) {} +static int inline EXTRA_DEBUG_fflush(...) { return 0; } +#endif +#ifdef MYSQL_SERVER +#define MYSQL_SERVER_my_error my_error +#else +static void inline MYSQL_SERVER_my_error(...) {} +#endif + /* The following handles the differences when this is linked between the @@ -85,19 +102,14 @@ void sql_print_error(const char *format,...); */ extern uint test_flags; extern ulong bytes_sent, bytes_received, net_big_packet_count; -#ifndef MYSQL_INSTANCE_MANAGER #ifdef HAVE_QUERY_CACHE #define USE_QUERY_CACHE extern void query_cache_insert(const char *packet, ulong length, unsigned pkt_nr); #endif // HAVE_QUERY_CACHE #define update_statistics(A) A -#endif /* MYSQL_INSTANCE_MANGER */ -#endif /* defined(MYSQL_SERVER) && !defined(MYSQL_INSTANCE_MANAGER) */ - -#if !defined(MYSQL_SERVER) || defined(MYSQL_INSTANCE_MANAGER) +#else #define update_statistics(A) -#define thd_increment_bytes_sent(N) #endif #define TEST_BLOCKING 8 @@ -114,7 +126,7 @@ my_bool my_net_init(NET *net, Vio* vio) net->vio = vio; my_net_local_init(net); /* Set some limits */ if (!(net->buff=(uchar*) my_malloc((size_t) net->max_packet+ - NET_HEADER_SIZE + COMP_HEADER_SIZE, + NET_HEADER_SIZE + COMP_HEADER_SIZE +1, MYF(MY_WME)))) DBUG_RETURN(1); net->buff_end=net->buff+net->max_packet; @@ -124,11 +136,9 @@ my_bool my_net_init(NET *net, Vio* vio) net->last_error[0]=0; net->compress=0; net->reading_or_writing=0; net->where_b = net->remain_in_buf=0; + net->net_skip_rest_factor= 0; net->last_errno=0; net->unused= 0; -#if defined(MYSQL_SERVER) && !defined(EMBEDDED_LIBRARY) - net->skip_big_packet= FALSE; -#endif if (vio != 0) /* If real connection */ { @@ -171,9 +181,7 @@ my_bool net_realloc(NET *net, size_t length) /* @todo: 1 and 2 codes are identical. */ net->error= 1; net->last_errno= ER_NET_PACKET_TOO_LARGE; -#ifdef MYSQL_SERVER - my_error(ER_NET_PACKET_TOO_LARGE, MYF(0)); -#endif + MYSQL_SERVER_my_error(ER_NET_PACKET_TOO_LARGE, MYF(0)); DBUG_RETURN(1); } pkt_length = (length+IO_SIZE-1) & ~(IO_SIZE-1); @@ -212,7 +220,7 @@ my_bool net_realloc(NET *net, size_t length) -1 Don't know if data is ready or not */ -#if !defined(EMBEDDED_LIBRARY) +#if !defined(EMBEDDED_LIBRARY) && defined(DBUG_OFF) static int net_data_is_ready(my_socket sd) { @@ -254,34 +262,39 @@ static int net_data_is_ready(my_socket sd) #endif /* EMBEDDED_LIBRARY */ /** - Remove unwanted characters from connection - and check if disconnected. + Intialize NET handler for new reads: - Read from socket until there is nothing more to read. Discard - what is read. + - Read from socket until there is nothing more to read. Discard + what is read. + - Initialize net for new net_read/net_write calls. - If there is anything when to read 'net_clear' is called this - normally indicates an error in the protocol. + If there is anything when to read 'net_clear' is called this + normally indicates an error in the protocol. Normally one should not + need to do clear the communication buffer. If one compiles without + -DUSE_NET_CLEAR then one wins one read call / query. - When connection is properly closed (for TCP it means with - a FIN packet), then select() considers a socket "ready to read", - in the sense that there's EOF to read, but read() returns 0. + When connection is properly closed (for TCP it means with + a FIN packet), then select() considers a socket "ready to read", + in the sense that there's EOF to read, but read() returns 0. @param net NET handler @param clear_buffer if <> 0, then clear all data from comm buff */ -void net_clear(NET *net, my_bool clear_buffer) +void net_clear(NET *net, my_bool clear_buffer __attribute__((unused))) { -#if !defined(EMBEDDED_LIBRARY) - size_t count; - int ready; -#endif DBUG_ENTER("net_clear"); -#if !defined(EMBEDDED_LIBRARY) +/* + We don't do a clear in case of not DBUG_OFF to catch bugs in the + protocol handling. +*/ + +#if (!defined(EMBEDDED_LIBRARY) && defined(DBUG_OFF)) || defined(USE_NET_CLEAR) if (clear_buffer) { + size_t count; + int ready; while ((ready= net_data_is_ready(net->vio->sd)) > 0) { /* The socket is ready */ @@ -290,10 +303,8 @@ void net_clear(NET *net, my_bool clear_buffer) { DBUG_PRINT("info",("skipped %ld bytes from file: %s", (long) count, vio_description(net->vio))); -#if defined(EXTRA_DEBUG) - fprintf(stderr,"Note: net_clear() skipped %ld bytes from file: %s\n", + EXTRA_DEBUG_fprintf(stderr,"Note: net_clear() skipped %ld bytes from file: %s\n", (long) count, vio_description(net->vio)); -#endif } else { @@ -592,7 +603,7 @@ net_real_write(NET *net,const uchar *packet, size_t len) uchar *b; uint header_length=NET_HEADER_SIZE+COMP_HEADER_SIZE; if (!(b= (uchar*) my_malloc(len + NET_HEADER_SIZE + - COMP_HEADER_SIZE, MYF(MY_WME)))) + COMP_HEADER_SIZE + 1, MYF(MY_WME)))) { net->error= 2; net->last_errno= ER_OUT_OF_RESOURCES; @@ -642,16 +653,12 @@ net_real_write(NET *net,const uchar *packet, size_t len) { if (vio_should_retry(net->vio) && retry_count++ < net->retry_count) continue; -#ifdef EXTRA_DEBUG - fprintf(stderr, + EXTRA_DEBUG_fprintf(stderr, "%s: my_net_write: fcntl returned error %d, aborting thread\n", my_progname,vio_errno(net->vio)); -#endif /* EXTRA_DEBUG */ net->error= 2; /* Close socket */ net->last_errno= ER_NET_PACKET_TOO_LARGE; -#ifdef MYSQL_SERVER - my_error(ER_NET_PACKET_TOO_LARGE, MYF(0)); -#endif + MYSQL_SERVER_my_error(ER_NET_PACKET_TOO_LARGE, MYF(0)); goto end; } retry_count=0; @@ -665,24 +672,20 @@ net_real_write(NET *net,const uchar *packet, size_t len) { if (retry_count++ < net->retry_count) continue; -#ifdef EXTRA_DEBUG - fprintf(stderr, "%s: write looped, aborting thread\n", + EXTRA_DEBUG_fprintf(stderr, "%s: write looped, aborting thread\n", my_progname); -#endif /* EXTRA_DEBUG */ } -#if defined(THREAD_SAFE_CLIENT) && !defined(MYSQL_SERVER) +#ifndef MYSQL_SERVER if (vio_errno(net->vio) == SOCKET_EINTR) { DBUG_PRINT("warning",("Interrupted write. Retrying...")); continue; } -#endif /* defined(THREAD_SAFE_CLIENT) && !defined(MYSQL_SERVER) */ +#endif /* !defined(MYSQL_SERVER) */ net->error= 2; /* Close socket */ net->last_errno= (interrupted ? ER_NET_WRITE_INTERRUPTED : ER_NET_ERROR_ON_WRITE); -#ifdef MYSQL_SERVER - my_error(net->last_errno, MYF(0)); -#endif /* MYSQL_SERVER */ + MYSQL_SERVER_my_error(net->last_errno, MYF(0)); break; } pos+=length; @@ -699,7 +702,8 @@ net_real_write(NET *net,const uchar *packet, size_t len) { my_bool old_mode; thr_end_alarm(&alarmed); - vio_blocking(net->vio, net_blocking, &old_mode); + if (!net_blocking) + vio_blocking(net->vio, net_blocking, &old_mode); } net->reading_or_writing=0; DBUG_RETURN(((int) (pos != end))); @@ -752,6 +756,7 @@ static my_bool net_safe_read(NET *net, uchar *buff, size_t length, static my_bool my_net_skip_rest(NET *net, uint32 remain, thr_alarm_t *alarmed, ALARM *alarm_buff) { + longlong limit= net->max_packet_size*net->net_skip_rest_factor; uint32 old=remain; DBUG_ENTER("my_net_skip_rest"); DBUG_PRINT("enter",("bytes_to_skip: %u", (uint) remain)); @@ -775,11 +780,15 @@ static my_bool my_net_skip_rest(NET *net, uint32 remain, thr_alarm_t *alarmed, DBUG_RETURN(1); update_statistics(thd_increment_bytes_received(length)); remain -= (uint32) length; + limit-= length; + if (limit < 0) + DBUG_RETURN(1); } if (old != MAX_PACKET_LENGTH) break; if (net_safe_read(net, net->buff, NET_HEADER_SIZE, alarmed)) DBUG_RETURN(1); + limit-= NET_HEADER_SIZE; old=remain= uint3korr(net->buff); net->pkt_nr++; } @@ -834,10 +843,10 @@ my_real_read(NET *net, size_t *complen) DBUG_PRINT("info",("vio_read returned %ld errno: %d", (long) length, vio_errno(net->vio))); -#if !defined(__WIN__) || defined(MYSQL_SERVER) +#if !defined(__WIN__) && defined(MYSQL_SERVER) /* We got an error that there was no data on the socket. We now set up - an alarm to not 'read forever', change the socket to non blocking + an alarm to not 'read forever', change the socket to the blocking mode and try again */ if ((interrupted || length == 0) && !thr_alarm_in_use(&alarmed)) @@ -853,35 +862,29 @@ my_real_read(NET *net, size_t *complen) DBUG_PRINT("error", ("fcntl returned error %d, aborting thread", vio_errno(net->vio))); -#ifdef EXTRA_DEBUG - fprintf(stderr, + EXTRA_DEBUG_fprintf(stderr, "%s: read: fcntl returned error %d, aborting thread\n", my_progname,vio_errno(net->vio)); -#endif /* EXTRA_DEBUG */ len= packet_error; net->error= 2; /* Close socket */ net->last_errno= ER_NET_FCNTL_ERROR; -#ifdef MYSQL_SERVER - my_error(ER_NET_FCNTL_ERROR, MYF(0)); -#endif + MYSQL_SERVER_my_error(ER_NET_FCNTL_ERROR, MYF(0)); goto end; } retry_count=0; continue; } } -#endif /* (!defined(__WIN__) || defined(MYSQL_SERVER) */ +#endif /* (!defined(__WIN__) && defined(MYSQL_SERVER) */ if (thr_alarm_in_use(&alarmed) && !thr_got_alarm(&alarmed) && interrupted) { /* Probably in MIT threads */ if (retry_count++ < net->retry_count) continue; -#ifdef EXTRA_DEBUG - fprintf(stderr, "%s: read looped with error %d, aborting thread\n", + EXTRA_DEBUG_fprintf(stderr, "%s: read looped with error %d, aborting thread\n", my_progname,vio_errno(net->vio)); -#endif /* EXTRA_DEBUG */ } -#if defined(THREAD_SAFE_CLIENT) && !defined(MYSQL_SERVER) +#ifndef MYSQL_SERVER if (vio_errno(net->vio) == SOCKET_EINTR) { DBUG_PRINT("warning",("Interrupted read. Retrying...")); @@ -895,9 +898,7 @@ my_real_read(NET *net, size_t *complen) net->last_errno= (vio_was_interrupted(net->vio) ? ER_NET_READ_INTERRUPTED : ER_NET_READ_ERROR); -#ifdef MYSQL_SERVER - my_error(net->last_errno, MYF(0)); -#endif + MYSQL_SERVER_my_error(net->last_errno, MYF(0)); goto end; } remain -= (uint32) length; @@ -923,20 +924,17 @@ my_real_read(NET *net, size_t *complen) the server expects the client to send a file, but the client may reply with a new command instead. */ -#if defined (EXTRA_DEBUG) && !defined (MYSQL_SERVER) - fflush(stdout); - fprintf(stderr,"Error: Packets out of order (Found: %d, expected %d)\n", +#ifndef MYSQL_SERVER + EXTRA_DEBUG_fflush(stdout); + EXTRA_DEBUG_fprintf(stderr,"Error: Packets out of order (Found: %d, expected %d)\n", (int) net->buff[net->where_b + 3], (uint) (uchar) net->pkt_nr); - fflush(stderr); - DBUG_ASSERT(0); + EXTRA_DEBUG_fflush(stderr); #endif } len= packet_error; /* Not a NET error on the client. XXX: why? */ -#ifdef MYSQL_SERVER - my_error(ER_NET_PACKETS_OUT_OF_ORDER, MYF(0)); -#endif + MYSQL_SERVER_my_error(ER_NET_PACKETS_OUT_OF_ORDER, MYF(0)); goto end; } net->compress_pkt_nr= ++net->pkt_nr; @@ -969,7 +967,6 @@ my_real_read(NET *net, size_t *complen) { #if defined(MYSQL_SERVER) && !defined(NO_ALARM) if (!net->compress && - net->skip_big_packet && !my_net_skip_rest(net, (uint32) len, &alarmed, &alarm_buff)) net->error= 3; /* Successfully skiped packet */ #endif @@ -987,7 +984,8 @@ end: { my_bool old_mode; thr_end_alarm(&alarmed); - vio_blocking(net->vio, net_blocking, &old_mode); + if (!net_blocking) + vio_blocking(net->vio, net_blocking, &old_mode); } net->reading_or_writing=0; #ifdef DEBUG_DATA_PACKETS @@ -1137,9 +1135,7 @@ my_net_read(NET *net) { net->error= 2; /* caller will close socket */ net->last_errno= ER_NET_UNCOMPRESS_ERROR; -#ifdef MYSQL_SERVER - my_error(ER_NET_UNCOMPRESS_ERROR, MYF(0)); -#endif + MYSQL_SERVER_my_error(ER_NET_UNCOMPRESS_ERROR, MYF(0)); MYSQL_NET_READ_DONE(1, 0); return packet_error; } @@ -1164,6 +1160,8 @@ void my_net_set_read_timeout(NET *net, uint timeout) { DBUG_ENTER("my_net_set_read_timeout"); DBUG_PRINT("enter", ("timeout: %d", timeout)); + if (net->read_timeout == timeout) + DBUG_VOID_RETURN; net->read_timeout= timeout; #ifdef NO_ALARM if (net->vio) @@ -1177,6 +1175,8 @@ void my_net_set_write_timeout(NET *net, uint timeout) { DBUG_ENTER("my_net_set_write_timeout"); DBUG_PRINT("enter", ("timeout: %d", timeout)); + if (net->write_timeout == timeout) + DBUG_VOID_RETURN; net->write_timeout= timeout; #ifdef NO_ALARM if (net->vio) |