diff options
Diffstat (limited to 'ext/mysql/libmysql/net.c')
| -rw-r--r-- | ext/mysql/libmysql/net.c | 671 | 
1 files changed, 0 insertions, 671 deletions
diff --git a/ext/mysql/libmysql/net.c b/ext/mysql/libmysql/net.c deleted file mode 100644 index 161fba4ace..0000000000 --- a/ext/mysql/libmysql/net.c +++ /dev/null @@ -1,671 +0,0 @@ -/* Copyright Abandoned 1996 TCX DataKonsult AB & Monty Program KB & Detron HB  -This file is public domain and comes with NO WARRANTY of any kind */ - -/* Write and read of logical packets to/from socket -** Writes are cached into net_buffer_length big packets. -** Read packets are reallocated dynamicly when reading big packets. -** Each logical packet has the following pre-info: -** 3 byte length & 1 byte package-number. -*/ - -#ifdef __WIN__ -#include <winsock.h> -#endif -#include <global.h> -#include <violite.h> -#include <my_sys.h> -#include <m_string.h> -#include "mysql.h" -#include "mysqld_error.h" -#include <signal.h> -#include <errno.h> -#include <sys/types.h> -#include <violite.h> - -#ifdef MYSQL_SERVER -ulong max_allowed_packet=65536; -extern ulong net_read_timeout,net_write_timeout; -extern uint test_flags; -#else -ulong max_allowed_packet=16*1024*1024L; -ulong net_read_timeout=  NET_READ_TIMEOUT; -ulong net_write_timeout= NET_WRITE_TIMEOUT; -#endif -ulong net_buffer_length=8192;	/* Default length. Enlarged if necessary */ - -#if !defined(__WIN__) && !defined(MSDOS) -#include <sys/socket.h> -#else -#undef MYSQL_SERVER			/* Win32 can't handle interrupts */ -#endif -#if !defined(MSDOS) && !defined(__WIN__) && !defined(HAVE_BROKEN_NETINET_INCLUDES) && !defined(__BEOS__) -#include <netinet/in_systm.h> -#include <netinet/in.h> -#include <netinet/ip.h> -#if !defined(alpha_linux_port) -#include <netinet/tcp.h> -#endif -#endif -#include "mysqld_error.h" -#ifdef MYSQL_SERVER -#include "my_pthread.h" -#include "thr_alarm.h" -void sql_print_error(const char *format,...); -#define RETRY_COUNT mysqld_net_retry_count -extern ulong mysqld_net_retry_count; -#else - -#ifdef OS2				/* avoid name conflict */ -#define thr_alarm_t  thr_alarm_t_net -#define ALARM        ALARM_net -#endif - -typedef my_bool thr_alarm_t; -typedef my_bool ALARM; -#define thr_alarm_init(A) (*(A))=0 -#define thr_alarm_in_use(A) (*(A)!= 0) -#define thr_end_alarm(A) -#define thr_alarm(A,B,C) local_thr_alarm((A),(B),(C)) -inline int local_thr_alarm(my_bool *A,int B __attribute__((unused)),ALARM *C __attribute__((unused))) -{ -  *A=1; -  return 0; -} -#define thr_got_alarm(A) 0 -#define RETRY_COUNT 1 -#endif - -#ifdef MYSQL_SERVER -extern ulong bytes_sent, bytes_received;  -extern pthread_mutex_t LOCK_bytes_sent , LOCK_bytes_received; -#else -#undef statistic_add -#define statistic_add(A,B,C) -#endif - -/* -** Give error if a too big packet is found -** The server can change this with the -O switch, but because the client -** can't normally do this the client should have a bigger max-buffer. -*/ - -#define TEST_BLOCKING		8 -static int net_write_buff(NET *net,const char *packet,uint len); - - -	/* Init with packet info */ - -int my_net_init(NET *net, Vio* vio) -{ -  if (!(net->buff=(uchar*) my_malloc(net_buffer_length,MYF(MY_WME)))) -    return 1; -  if (net_buffer_length > max_allowed_packet) -    max_allowed_packet=net_buffer_length; -  net->buff_end=net->buff+(net->max_packet=net_buffer_length); -  net->vio = vio; -  net->no_send_ok = 0; -  net->error=0; net->return_errno=0; net->return_status=0; -  net->timeout=(uint) net_read_timeout;		/* Timeout for read */ -  net->pkt_nr=0; -  net->write_pos=net->read_pos = net->buff; -  net->last_error[0]=0; -  net->compress=0; net->reading_or_writing=0; -  net->where_b = net->remain_in_buf=0; -  net->last_errno=0; - -  if (vio != 0)					/* If real connection */ -  { -    net->fd  = vio_fd(vio);			/* For perl DBI/DBD */ -#if defined(MYSQL_SERVER) && !defined(___WIN__) && !defined(__EMX__) && !defined(OS2) -    if (!(test_flags & TEST_BLOCKING)) -      vio_blocking(vio, FALSE); -#endif -    vio_fastsend(vio); -  } -  return 0; -} - -void net_end(NET *net) -{ -  my_free((gptr) net->buff,MYF(MY_ALLOW_ZERO_PTR)); -  net->buff=0; -} - -/* Realloc the packet buffer */ - -static my_bool net_realloc(NET *net, ulong length) -{ -  uchar *buff; -  ulong pkt_length; -  if (length >= max_allowed_packet) -  { -    DBUG_PRINT("error",("Packet too large (%lu)", length)); -    net->error=1; -    net->last_errno=ER_NET_PACKET_TOO_LARGE; -    return 1; -  } -  pkt_length = (length+IO_SIZE-1) & ~(IO_SIZE-1); -  if (!(buff=(uchar*) my_realloc((char*) net->buff, pkt_length, MYF(MY_WME)))) -  { -    net->error=1; -#ifdef MYSQL_SERVER -    net->last_errno=ER_OUT_OF_RESOURCES; -#endif -    return 1; -  } -  net->buff=net->write_pos=buff; -  net->buff_end=buff+(net->max_packet=pkt_length); -  return 0; -} - -	/* Remove unwanted characters from connection */ - -void net_clear(NET *net) -{ -#ifndef EXTRA_DEBUG -  int count; -  bool is_blocking=vio_is_blocking(net->vio); -  if (is_blocking) -    vio_blocking(net->vio, FALSE); -  if (!vio_is_blocking(net->vio))		/* Safety if SSL */ -  { -    while ( (count = vio_read(net->vio, (char*) (net->buff), -			      net->max_packet)) > 0) -      DBUG_PRINT("info",("skipped %d bytes from file: %s", -			 count,vio_description(net->vio))); -    if (is_blocking) -      vio_blocking(net->vio, TRUE); -  } -#endif /* EXTRA_DEBUG */ -  net->pkt_nr=0;				/* Ready for new command */ -  net->write_pos=net->buff; -} - -	/* Flush write_buffer if not empty. */ - -int net_flush(NET *net) -{ -  int error=0; -  DBUG_ENTER("net_flush"); -  if (net->buff != net->write_pos) -  { -    error=net_real_write(net,(char*) net->buff, -			 (uint) (net->write_pos - net->buff)); -    net->write_pos=net->buff; -  } -  DBUG_RETURN(error); -} - - -/***************************************************************************** -** Write something to server/client buffer -*****************************************************************************/ - - -/* -** Write a logical packet with packet header -** Format: Packet length (3 bytes), packet number(1 byte) -**         When compression is used a 3 byte compression length is added -** NOTE: If compression is used the original package is destroyed! -*/ - -int -my_net_write(NET *net,const char *packet,ulong len) -{ -  uchar buff[NET_HEADER_SIZE]; -  int3store(buff,len); -  buff[3]= (net->compress) ? 0 : (uchar) (net->pkt_nr++); -  if (net_write_buff(net,(char*) buff,NET_HEADER_SIZE)) -    return 1; -  return net_write_buff(net,packet,len); -} - -int -net_write_command(NET *net,uchar command,const char *packet,ulong len) -{ -  uchar buff[NET_HEADER_SIZE+1]; -  uint length=len+1;				/* 1 extra byte for command */ - -  int3store(buff,length); -  buff[3]= (net->compress) ? 0 : (uchar) (net->pkt_nr++); -  buff[4]=command; -  if (net_write_buff(net,(char*) buff,5)) -    return 1; -  return test(net_write_buff(net,packet,len) || net_flush(net)); -} - - -static int -net_write_buff(NET *net,const char *packet,uint len) -{ -  uint left_length=(uint) (net->buff_end - net->write_pos); - -  while (len > left_length) -  { -    memcpy((char*) net->write_pos,packet,left_length); -    if (net_real_write(net,(char*) net->buff,net->max_packet)) -      return 1; -    net->write_pos=net->buff; -    packet+=left_length; -    len-=left_length; -    left_length=net->max_packet; -  } -  memcpy((char*) net->write_pos,packet,len); -  net->write_pos+=len; -  return 0; -} - -/*  Read and write using timeouts */ - -int -net_real_write(NET *net,const char *packet,ulong len) -{ -  int length; -  char *pos,*end; -  thr_alarm_t alarmed; -#if !defined(__WIN__) && !defined(__EMX__) && !defined(OS2) -  ALARM alarm_buff; -#endif -  uint retry_count=0; -  my_bool net_blocking = vio_is_blocking(net->vio); -  DBUG_ENTER("net_real_write"); - -  if (net->error == 2) -    DBUG_RETURN(-1);				/* socket can't be used */ - -  net->reading_or_writing=2; -#ifdef HAVE_COMPRESS -  if (net->compress) -  { -    ulong complen; -    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)))) -    { -#ifdef MYSQL_SERVER -      net->last_errno=ER_OUT_OF_RESOURCES; -      net->error=2; -#endif -      net->reading_or_writing=0; -      DBUG_RETURN(1); -    } -    memcpy(b+header_length,packet,len); - -    if (my_compress((byte*) b+header_length,&len,&complen)) -    { -      DBUG_PRINT("warning", -		 ("Compression error; Continuing without compression")); -      complen=0; -    } -    int3store(&b[NET_HEADER_SIZE],complen); -    int3store(b,len); -    b[3]=(uchar) (net->pkt_nr++); -    len+= header_length; -    packet= (char*) b; -  } -#endif /* HAVE_COMPRESS */ - -  /* DBUG_DUMP("net",packet,len); */ -#ifdef MYSQL_SERVER -  thr_alarm_init(&alarmed); -  if (net_blocking) -    thr_alarm(&alarmed,(uint) net_write_timeout,&alarm_buff); -#else -  alarmed=0; -#endif /* MYSQL_SERVER */ - -  pos=(char*) packet; end=pos+len; -  while (pos != end) -  { -    if ((int) (length=vio_write(net->vio,pos,(int) (end-pos))) <= 0) -    { -      my_bool interrupted = vio_should_retry(net->vio); -#if (!defined(__WIN__) && !defined(__EMX__) && !defined(OS2)) -      if ((interrupted || length==0) && !thr_alarm_in_use(&alarmed)) -      { -        if (!thr_alarm(&alarmed,(uint) net_write_timeout,&alarm_buff)) -        {                                       /* Always true for client */ -	  if (!vio_is_blocking(net->vio)) -	  { -	    while (vio_blocking(net->vio, TRUE) < 0) -	    { -	      if (vio_should_retry(net->vio) && retry_count++ < RETRY_COUNT) -		continue; -#ifdef 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 */ -	      goto end; -	    } -	  } -	  retry_count=0; -	  continue; -	} -      } -      else -#endif /* (!defined(__WIN__) && !defined(__EMX__)) */ -	if (thr_alarm_in_use(&alarmed) && !thr_got_alarm(&alarmed) && -	    interrupted) -      { -	if (retry_count++ < RETRY_COUNT) -	    continue; -#ifdef EXTRA_DEBUG -	  fprintf(stderr, "%s: write looped, aborting thread\n", -		  my_progname); -#endif /* EXTRA_DEBUG */ -      } -#if defined(THREAD_SAFE_CLIENT) && !defined(MYSQL_SERVER) -      if (vio_errno(net->vio) == SOCKET_EINTR) -      { -	DBUG_PRINT("warning",("Interrupted write. Retrying...")); -	continue; -      } -#endif /* defined(THREAD_SAFE_CLIENT) && !defined(MYSQL_SERVER) */ -      net->error=2;				/* Close socket */ -#ifdef MYSQL_SERVER -      net->last_errno= (interrupted ? ER_NET_WRITE_INTERRUPTED : -			ER_NET_ERROR_ON_WRITE); -#endif /* MYSQL_SERVER */ -      break; -    } -    pos+=length; -    statistic_add(bytes_sent,length,&LOCK_bytes_sent); -  } -#ifndef __WIN__ - end: -#endif -#ifdef HAVE_COMPRESS -  if (net->compress) -    my_free((char*) packet,MYF(0)); -#endif -  if (thr_alarm_in_use(&alarmed)) -  { -    thr_end_alarm(&alarmed); -    vio_blocking(net->vio, net_blocking); -  } -  net->reading_or_writing=0; -  DBUG_RETURN(((int) (pos != end))); -} - - -/***************************************************************************** -** Read something from server/clinet -*****************************************************************************/ - -#ifdef MYSQL_SERVER - -/* -  Help function to clear the commuication buffer when we get a too -  big packet -*/ - -static void my_net_skip_rest(NET *net, ulong remain, thr_alarm_t *alarmed) -{ -  ALARM alarm_buff; -  uint retry_count=0; -  if (!thr_alarm_in_use(&alarmed)) -  { -    if (!thr_alarm(alarmed,net->timeout,&alarm_buff) || -	(!vio_is_blocking(net->vio) && vio_blocking(net->vio,TRUE) < 0)) -      return;					/* Can't setup, abort */ -  } -  while (remain > 0) -  { -    ulong length; -    if ((int) (length=vio_read(net->vio,(char*) net->buff,remain)) <= 0L) -    { -      my_bool interrupted = vio_should_retry(net->vio); -      if (!thr_got_alarm(alarmed) && interrupted) -      {					/* Probably in MIT threads */ -	if (retry_count++ < RETRY_COUNT) -	  continue; -      } -      return; -    } -    remain -=(ulong) length; -    statistic_add(bytes_received,(ulong) length,&LOCK_bytes_received); -  } -} -#endif /* MYSQL_SERVER */ - - -static uint -my_real_read(NET *net, ulong *complen) -{ -  uchar *pos; -  long length; -  uint i,retry_count=0; -  ulong len=packet_error; -  thr_alarm_t alarmed; -#if (!defined(__WIN__) && !defined(__EMX__) && !defined(OS2)) || defined(MYSQL_SERVER) -  ALARM alarm_buff; -#endif -  my_bool net_blocking=vio_is_blocking(net->vio); -  ulong remain= (net->compress ? NET_HEADER_SIZE+COMP_HEADER_SIZE : -		 NET_HEADER_SIZE); -  *complen = 0; - -  net->reading_or_writing=1; -  thr_alarm_init(&alarmed); -#ifdef MYSQL_SERVER -  if (net_blocking) -    thr_alarm(&alarmed,net->timeout,&alarm_buff); -#endif /* MYSQL_SERVER */ - -    pos = net->buff + net->where_b;		/* net->packet -4 */ -    for (i=0 ; i < 2 ; i++) -    { -      while (remain > 0) -      { -	/* First read is done with non blocking mode */ -        if ((int) (length=vio_read(net->vio,(char*) pos,remain)) <= 0L) -        { -          my_bool interrupted = vio_should_retry(net->vio); - -	  DBUG_PRINT("info",("vio_read returned %d,  errno: %d", -			     length, vio_errno(net->vio))); -#if (!defined(__WIN__) && !defined(__EMX__) && !defined(OS2)) || 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 -	    mode and try again -	  */ -	  if ((interrupted || length == 0) && !thr_alarm_in_use(&alarmed)) -	  { -	    if (!thr_alarm(&alarmed,net->timeout,&alarm_buff)) /* Don't wait too long */ -	    { -              if (!vio_is_blocking(net->vio)) -              { -                while (vio_blocking(net->vio,TRUE) < 0) -                { -                  if (vio_should_retry(net->vio) && -		      retry_count++ < RETRY_COUNT) -                    continue; -                  DBUG_PRINT("error", -			     ("fcntl returned error %d, aborting thread", -			      vio_errno(net->vio))); -#ifdef 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 */ -#ifdef MYSQL_SERVER -		  net->last_errno=ER_NET_FCNTL_ERROR; -#endif -		  goto end; -                } -              } -	      retry_count=0; -	      continue; -	    } -	  } -#endif /* (!defined(__WIN__) && !defined(__EMX__)) || defined(MYSQL_SERVER) */ -	  if (thr_alarm_in_use(&alarmed) && !thr_got_alarm(&alarmed) && -	      interrupted) -	  {					/* Probably in MIT threads */ -	    if (retry_count++ < RETRY_COUNT) -	      continue; -#ifdef 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) -	  if (vio_should_retry(net->vio)) -	  { -	    DBUG_PRINT("warning",("Interrupted read. Retrying...")); -	    continue; -	  } -#endif -	  DBUG_PRINT("error",("Couldn't read packet: remain: %d  errno: %d  length: %d  alarmed: %d", remain,vio_errno(net->vio),length,alarmed)); -	  len= packet_error; -	  net->error=2;				/* Close socket */ -#ifdef MYSQL_SERVER -	  net->last_errno= (interrupted ? ER_NET_READ_INTERRUPTED : -			    ER_NET_READ_ERROR); -#endif -	  goto end; -	} -	remain -= (ulong) length; -	pos+= (ulong) length; -	statistic_add(bytes_received,(ulong) length,&LOCK_bytes_received); -      } -      if (i == 0) -      {					/* First parts is packet length */ -	ulong helping; -	if (net->buff[net->where_b + 3] != (uchar) net->pkt_nr) -	{ -	  if (net->buff[net->where_b] != (uchar) 255) -	  { -	    DBUG_PRINT("error", -		       ("Packets out of order (Found: %d, expected %d)", -			(int) net->buff[net->where_b + 3], -			(uint) (uchar) net->pkt_nr)); -#ifdef EXTRA_DEBUG -	    fprintf(stderr,"Packets out of order (Found: %d, expected %d)\n", -		    (int) net->buff[net->where_b + 3], -		    (uint) (uchar) net->pkt_nr); -#endif -	  } -	  len= packet_error; -#ifdef MYSQL_SERVER -	  net->last_errno=ER_NET_PACKETS_OUT_OF_ORDER; -#endif -	  goto end; -	} -	net->pkt_nr++; -#ifdef HAVE_COMPRESS -	if (net->compress) -	{ -	  /* complen is > 0 if package is really compressed */ -	  *complen=uint3korr(&(net->buff[net->where_b + NET_HEADER_SIZE])); -	} -#endif - -	len=uint3korr(net->buff+net->where_b); -	helping = max(len,*complen) + net->where_b; -	/* The necessary size of net->buff */ -	if (helping >= net->max_packet) -	{ -	  /* We must allocate one extra byte for the end null */ -	  if (net_realloc(net,helping+1)) -	  { -#ifdef MYSQL_SERVER -	    if (i == 1) -	      my_net_skip_rest(net, len, &alarmed); -#endif -	    len= packet_error;		/* Return error */ -	    goto end; -	  } -	} -	pos=net->buff + net->where_b; -	remain = len; -      } -    } - -end: -  if (thr_alarm_in_use(&alarmed)) -  { -    thr_end_alarm(&alarmed); -    vio_blocking(net->vio, net_blocking); -  } -  net->reading_or_writing=0; -  return(len); -} - -uint -my_net_read(NET *net) -{ -  ulong len,complen; - -#ifdef HAVE_COMPRESS -  if (!net->compress) -  { -#endif -    len = my_real_read (net,&complen); -    net->read_pos = net->buff + net->where_b; -    if (len != packet_error) -      net->read_pos[len]=0;		/* Safeguard for mysql_use_result */ -    return len; -#ifdef HAVE_COMPRESS -  } -  if (net->remain_in_buf) -    net->buff[net->buf_length - net->remain_in_buf]=net->save_char; -  for (;;) -  { -    if (net->remain_in_buf) -    { -      uchar *pos = net->buff + net->buf_length - net->remain_in_buf; -      if (net->remain_in_buf >= 4) -      { -	net->length = uint3korr(pos); -	if (net->length <= net->remain_in_buf - 4) -	{ -	  /* We have a full packet */ -	  len=net->length; -	  net->remain_in_buf -= net->length + 4; -	  net->read_pos=pos + 4; -	  break;			/* We have a full packet */ -	} -      } -      /* Move data down to read next data packet after current one */ -      if (net->buf_length != net->remain_in_buf) -      { -	memmove(net->buff,pos,net->remain_in_buf); -	net->buf_length=net->remain_in_buf; -      } -      net->where_b=net->buf_length; -    } -    else -    { -      net->where_b=0; -      net->buf_length=0; -    } - -    if ((len = my_real_read(net,&complen)) == packet_error) -      break; -    if (my_uncompress((byte*) net->buff + net->where_b, &len, &complen)) -    { -      len= packet_error; -      net->error=2;			/* caller will close socket */ -#ifdef MYSQL_SERVER -      net->last_errno=ER_NET_UNCOMPRESS_ERROR; -#endif -      break; -    } -    net->buf_length+=len; -    net->remain_in_buf+=len; -  } -  if (len != packet_error) -  { -    net->save_char= net->read_pos[len];	/* Must be saved */ -    net->read_pos[len]=0;		/* Safeguard for mysql_use_result */ -  } -  return len; -#endif -}  | 
