MySQL 5.6.14 Source Code Document
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
viosocket.c
1 /*
2  Copyright (c) 2001, 2012, Oracle and/or its affiliates. All rights reserved.
3 
4  This program is free software; you can redistribute it and/or
5  modify it under the terms of the GNU General Public License
6  as published by the Free Software Foundation; version 2 of
7  the License.
8 
9  This program is distributed in the hope that it will be useful,
10  but WITHOUT ANY WARRANTY; without even the implied warranty of
11  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12  GNU General Public License for more details.
13 
14  You should have received a copy of the GNU General Public License
15  along with this program; if not, write to the Free Software
16  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
17  02110-1301 USA */
18 
19 /*
20  Note that we can't have assertion on file descriptors; The reason for
21  this is that during mysql shutdown, another thread can close a file
22  we are working on. In this case we should just return read errors from
23  the file descriptior.
24 */
25 
26 #include "vio_priv.h"
27 
28 #ifdef FIONREAD_IN_SYS_FILIO
29 # include <sys/filio.h>
30 #endif
31 
32 int vio_errno(Vio *vio __attribute__((unused)))
33 {
34  /* These transport types are not Winsock based. */
35 #ifdef _WIN32
36  if (vio->type == VIO_TYPE_NAMEDPIPE ||
37  vio->type == VIO_TYPE_SHARED_MEMORY)
38  return GetLastError();
39 #endif
40 
41  /* Mapped to WSAGetLastError() on Win32. */
42  return socket_errno;
43 }
44 
45 
55 int vio_socket_io_wait(Vio *vio, enum enum_vio_io_event event)
56 {
57  int timeout, ret;
58 
59  DBUG_ASSERT(event == VIO_IO_EVENT_READ || event == VIO_IO_EVENT_WRITE);
60 
61  /* Choose an appropriate timeout. */
62  if (event == VIO_IO_EVENT_READ)
63  timeout= vio->read_timeout;
64  else
65  timeout= vio->write_timeout;
66 
67  /* Wait for input data to become available. */
68  switch (vio_io_wait(vio, event, timeout))
69  {
70  case -1:
71  /* Upon failure, vio_read/write() shall return -1. */
72  ret= -1;
73  break;
74  case 0:
75  /* The wait timed out. */
76  ret= -1;
77  break;
78  default:
79  /* A positive value indicates an I/O event. */
80  ret= 0;
81  break;
82  }
83 
84  return ret;
85 }
86 
87 
88 /*
89  Define a stub MSG_DONTWAIT if unavailable. In this case, fcntl
90  (or a equivalent) is used to enable non-blocking operations.
91  The flag must be supported in both send and recv operations.
92 */
93 #if defined(__linux__)
94 #define VIO_USE_DONTWAIT 1
95 #define VIO_DONTWAIT MSG_DONTWAIT
96 #else
97 #define VIO_DONTWAIT 0
98 #endif
99 
100 
101 size_t vio_read(Vio *vio, uchar *buf, size_t size)
102 {
103  ssize_t ret;
104  int flags= 0;
105  DBUG_ENTER("vio_read");
106 
107  /* Ensure nobody uses vio_read_buff and vio_read simultaneously. */
108  DBUG_ASSERT(vio->read_end == vio->read_pos);
109 
110  /* If timeout is enabled, do not block if data is unavailable. */
111  if (vio->read_timeout >= 0)
112  flags= VIO_DONTWAIT;
113 
114  while ((ret= mysql_socket_recv(vio->mysql_socket, (SOCKBUF_T *)buf, size, flags)) == -1)
115  {
116  int error= socket_errno;
117 
118  /* The operation would block? */
119  if (error != SOCKET_EAGAIN && error != SOCKET_EWOULDBLOCK)
120  break;
121 
122  /* Wait for input data to become available. */
123  if ((ret= vio_socket_io_wait(vio, VIO_IO_EVENT_READ)))
124  break;
125  }
126 
127  DBUG_RETURN(ret);
128 }
129 
130 
131 /*
132  Buffered read: if average read size is small it may
133  reduce number of syscalls.
134 */
135 
136 size_t vio_read_buff(Vio *vio, uchar* buf, size_t size)
137 {
138  size_t rc;
139 #define VIO_UNBUFFERED_READ_MIN_SIZE 2048
140  DBUG_ENTER("vio_read_buff");
141  DBUG_PRINT("enter", ("sd: %d buf: 0x%lx size: %u",
142  mysql_socket_getfd(vio->mysql_socket), (long)buf, (uint)size));
143 
144  if (vio->read_pos < vio->read_end)
145  {
146  rc= MY_MIN((size_t) (vio->read_end - vio->read_pos), size);
147  memcpy(buf, vio->read_pos, rc);
148  vio->read_pos+= rc;
149  /*
150  Do not try to read from the socket now even if rc < size:
151  vio_read can return -1 due to an error or non-blocking mode, and
152  the safest way to handle it is to move to a separate branch.
153  */
154  }
155  else if (size < VIO_UNBUFFERED_READ_MIN_SIZE)
156  {
157  rc= vio_read(vio, (uchar*) vio->read_buffer, VIO_READ_BUFFER_SIZE);
158  if (rc != 0 && rc != (size_t) -1)
159  {
160  if (rc > size)
161  {
162  vio->read_pos= vio->read_buffer + size;
163  vio->read_end= vio->read_buffer + rc;
164  rc= size;
165  }
166  memcpy(buf, vio->read_buffer, rc);
167  }
168  }
169  else
170  rc= vio_read(vio, buf, size);
171  DBUG_RETURN(rc);
172 #undef VIO_UNBUFFERED_READ_MIN_SIZE
173 }
174 
175 
176 my_bool vio_buff_has_data(Vio *vio)
177 {
178  return (vio->read_pos != vio->read_end);
179 }
180 
181 
182 size_t vio_write(Vio *vio, const uchar* buf, size_t size)
183 {
184  ssize_t ret;
185  int flags= 0;
186  DBUG_ENTER("vio_write");
187 
188  /* If timeout is enabled, do not block. */
189  if (vio->write_timeout >= 0)
190  flags= VIO_DONTWAIT;
191 
192  while ((ret= mysql_socket_send(vio->mysql_socket, (SOCKBUF_T *)buf, size, flags)) == -1)
193  {
194  int error= socket_errno;
195 
196  /* The operation would block? */
197  if (error != SOCKET_EAGAIN && error != SOCKET_EWOULDBLOCK)
198  break;
199 
200  /* Wait for the output buffer to become writable.*/
201  if ((ret= vio_socket_io_wait(vio, VIO_IO_EVENT_WRITE)))
202  break;
203  }
204 
205  DBUG_RETURN(ret);
206 }
207 
208 //WL#4896: Not covered
209 static int vio_set_blocking(Vio *vio, my_bool status)
210 {
211  DBUG_ENTER("vio_set_blocking");
212 
213 #ifdef _WIN32
214  DBUG_ASSERT(vio->type != VIO_TYPE_NAMEDPIPE);
215  DBUG_ASSERT(vio->type != VIO_TYPE_SHARED_MEMORY);
216  {
217  int ret;
218  u_long arg= status ? 0 : 1;
219  ret= ioctlsocket(mysql_socket_getfd(vio->mysql_socket), FIONBIO, &arg);
220  DBUG_RETURN(ret);
221  }
222 #else
223  {
224  int flags;
225 
226  if ((flags= fcntl(mysql_socket_getfd(vio->mysql_socket), F_GETFL, NULL)) < 0)
227  DBUG_RETURN(-1);
228 
229  /*
230  Always set/clear the flag to avoid inheritance issues. This is
231  a issue mainly on Mac OS X Tiger (version 10.4) where although
232  the O_NONBLOCK flag is inherited from the parent socket, the
233  actual non-blocking behavior is not inherited.
234  */
235  if (status)
236  flags&= ~O_NONBLOCK;
237  else
238  flags|= O_NONBLOCK;
239 
240  if (fcntl(mysql_socket_getfd(vio->mysql_socket), F_SETFL, flags) == -1)
241  DBUG_RETURN(-1);
242  }
243 #endif
244 
245  DBUG_RETURN(0);
246 }
247 
248 
249 int vio_socket_timeout(Vio *vio,
250  uint which __attribute__((unused)),
251  my_bool old_mode __attribute__((unused)))
252 {
253  int ret= 0;
254  DBUG_ENTER("vio_socket_timeout");
255 
256 #if defined(_WIN32)
257  {
258  int optname;
259  DWORD timeout= 0;
260  const char *optval= (const char *) &timeout;
261 
262  /*
263  The default socket timeout value is zero, which means an infinite
264  timeout. Values less than 500 milliseconds are interpreted to be of
265  500 milliseconds. Hence, the VIO behavior for zero timeout, which is
266  intended to cause the send or receive operation to fail immediately
267  if no data is available, is not supported on WIN32 and neither is
268  necessary as it's not possible to set the VIO timeout value to zero.
269 
270  Assert that the VIO timeout is either positive or set to infinite.
271  */
272  DBUG_ASSERT(which || vio->read_timeout);
273  DBUG_ASSERT(!which || vio->write_timeout);
274 
275  if (which)
276  {
277  optname= SO_SNDTIMEO;
278  if (vio->write_timeout > 0)
279  timeout= vio->write_timeout;
280  }
281  else
282  {
283  optname= SO_RCVTIMEO;
284  if (vio->read_timeout > 0)
285  timeout= vio->read_timeout;
286  }
287 
288  ret= mysql_socket_setsockopt(vio->mysql_socket, SOL_SOCKET, optname,
289  optval, sizeof(timeout));
290  }
291 #else
292  /*
293  The MSG_DONTWAIT trick is not used with SSL sockets as the send and
294  receive I/O operations are wrapped through SSL-specific functions
295  (SSL_read and SSL_write) which are not equivalent to the standard
296  recv(2) and send(2) used in vio_read() and vio_write(). Hence, the
297  socket blocking mode is changed and vio_io_wait() is used to wait
298  for I/O or timeout.
299  */
300 #ifdef VIO_USE_DONTWAIT
301  if (vio->type == VIO_TYPE_SSL)
302 #endif
303  {
304  /* Deduce what should be the new blocking mode of the socket. */
305  my_bool new_mode= vio->write_timeout < 0 && vio->read_timeout < 0;
306 
307  /* If necessary, update the blocking mode. */
308  if (new_mode != old_mode)
309  ret= vio_set_blocking(vio, new_mode);
310  }
311 #endif
312 
313  DBUG_RETURN(ret);
314 }
315 
316 
317 int vio_fastsend(Vio * vio __attribute__((unused)))
318 {
319  int r=0;
320  DBUG_ENTER("vio_fastsend");
321 
322 #if defined(IPTOS_THROUGHPUT)
323  {
324  int tos = IPTOS_THROUGHPUT;
325  r= mysql_socket_setsockopt(vio->mysql_socket, IPPROTO_IP, IP_TOS,
326  (void *)&tos, sizeof(tos));
327  }
328 #endif /* IPTOS_THROUGHPUT */
329  if (!r)
330  {
331 #ifdef __WIN__
332  BOOL nodelay= 1;
333 #else
334  int nodelay = 1;
335 #endif
336 
337  r= mysql_socket_setsockopt(vio->mysql_socket, IPPROTO_TCP, TCP_NODELAY,
338  IF_WIN((const char*), (void*)) &nodelay,
339  sizeof(nodelay));
340 
341  }
342  if (r)
343  {
344  DBUG_PRINT("warning", ("Couldn't set socket option for fast send"));
345  r= -1;
346  }
347  DBUG_PRINT("exit", ("%d", r));
348  DBUG_RETURN(r);
349 }
350 
351 int vio_keepalive(Vio* vio, my_bool set_keep_alive)
352 {
353  int r=0;
354  uint opt = 0;
355  DBUG_ENTER("vio_keepalive");
356  DBUG_PRINT("enter", ("sd: %d set_keep_alive: %d",
357  mysql_socket_getfd(vio->mysql_socket), (int)set_keep_alive));
358  if (vio->type != VIO_TYPE_NAMEDPIPE)
359  {
360  if (set_keep_alive)
361  opt = 1;
362  r = mysql_socket_setsockopt(vio->mysql_socket, SOL_SOCKET, SO_KEEPALIVE,
363  (char *)&opt, sizeof(opt));
364  }
365  DBUG_RETURN(r);
366 }
367 
368 
379 my_bool
380 vio_should_retry(Vio *vio)
381 {
382  return (vio_errno(vio) == SOCKET_EINTR);
383 }
384 
385 
396 my_bool
397 vio_was_timeout(Vio *vio)
398 {
399  return (vio_errno(vio) == SOCKET_ETIMEDOUT);
400 }
401 
402 
403 int vio_shutdown(Vio * vio)
404 {
405  int r=0;
406  DBUG_ENTER("vio_shutdown");
407 
408  if (vio->inactive == FALSE)
409  {
410  DBUG_ASSERT(vio->type == VIO_TYPE_TCPIP ||
411  vio->type == VIO_TYPE_SOCKET ||
412  vio->type == VIO_TYPE_SSL);
413 
414  DBUG_ASSERT(mysql_socket_getfd(vio->mysql_socket) >= 0);
415  if (mysql_socket_shutdown(vio->mysql_socket, SHUT_RDWR))
416  r= -1;
417  if (mysql_socket_close(vio->mysql_socket))
418  r= -1;
419  }
420  if (r)
421  {
422  DBUG_PRINT("vio_error", ("close() failed, error: %d",socket_errno));
423  /* FIXME: error handling (not critical for MySQL) */
424  }
425  vio->inactive= TRUE;
426  vio->mysql_socket= MYSQL_INVALID_SOCKET;
427  DBUG_RETURN(r);
428 }
429 
430 
431 const char *vio_description(Vio * vio)
432 {
433  if (!vio->desc[0])
434  {
435  my_snprintf(vio->desc, VIO_DESCRIPTION_SIZE,
436  (vio->type == VIO_TYPE_SOCKET ? "socket (%d)" : "TCP/IP (%d)"),
437  mysql_socket_getfd(vio->mysql_socket));
438  }
439  return vio->desc;
440 }
441 
442 enum enum_vio_type vio_type(Vio* vio)
443 {
444  return vio->type;
445 }
446 
447 my_socket vio_fd(Vio* vio)
448 {
449  return mysql_socket_getfd(vio->mysql_socket);
450 }
451 
475 static void vio_get_normalized_ip(const struct sockaddr *src,
476  int src_length,
477  struct sockaddr *dst,
478  int *dst_length)
479 {
480  switch (src->sa_family) {
481  case AF_INET:
482  memcpy(dst, src, src_length);
483  *dst_length= src_length;
484  break;
485 
486 #ifdef HAVE_IPV6
487  case AF_INET6:
488  {
489  const struct sockaddr_in6 *src_addr6= (const struct sockaddr_in6 *) src;
490  const struct in6_addr *src_ip6= &(src_addr6->sin6_addr);
491  const uint32 *src_ip6_int32= (uint32 *) src_ip6->s6_addr;
492 
493  if (IN6_IS_ADDR_V4MAPPED(src_ip6) || IN6_IS_ADDR_V4COMPAT(src_ip6))
494  {
495  struct sockaddr_in *dst_ip4= (struct sockaddr_in *) dst;
496 
497  /*
498  This is an IPv4-mapped or IPv4-compatible IPv6 address. It should
499  be converted to the IPv4 form.
500  */
501 
502  *dst_length= sizeof (struct sockaddr_in);
503 
504  memset(dst_ip4, 0, *dst_length);
505  dst_ip4->sin_family= AF_INET;
506  dst_ip4->sin_port= src_addr6->sin6_port;
507 
508  /*
509  In an IPv4 mapped or compatible address, the last 32 bits represent
510  the IPv4 address. The byte orders for IPv6 and IPv4 addresses are
511  the same, so a simple copy is possible.
512  */
513  dst_ip4->sin_addr.s_addr= src_ip6_int32[3];
514  }
515  else
516  {
517  /* This is a "native" IPv6 address. */
518 
519  memcpy(dst, src, src_length);
520  *dst_length= src_length;
521  }
522 
523  break;
524  }
525 #endif /* HAVE_IPV6 */
526  }
527 }
528 
529 
551 my_bool vio_get_normalized_ip_string(const struct sockaddr *addr,
552  int addr_length,
553  char *ip_string,
554  size_t ip_string_size)
555 {
556  struct sockaddr_storage norm_addr_storage;
557  struct sockaddr *norm_addr= (struct sockaddr *) &norm_addr_storage;
558  int norm_addr_length;
559  int err_code;
560 
561  vio_get_normalized_ip(addr, addr_length, norm_addr, &norm_addr_length);
562 
563  err_code= vio_getnameinfo(norm_addr, ip_string, ip_string_size, NULL, 0,
564  NI_NUMERICHOST);
565 
566  if (!err_code)
567  return FALSE;
568 
569  DBUG_PRINT("error", ("getnameinfo() failed with %d (%s).",
570  (int) err_code,
571  (const char *) gai_strerror(err_code)));
572  return TRUE;
573 }
574 
575 
586 my_bool vio_peer_addr(Vio *vio, char *ip_buffer, uint16 *port,
587  size_t ip_buffer_size)
588 {
589  DBUG_ENTER("vio_peer_addr");
590  DBUG_PRINT("enter", ("Client socked fd: %d",
591  (int)mysql_socket_getfd(vio->mysql_socket)));
592 
593  if (vio->localhost)
594  {
595  /*
596  Initialize vio->remote and vio->addLen. Set vio->remote to IPv4 loopback
597  address.
598  */
599  struct in_addr *ip4= &((struct sockaddr_in *) &(vio->remote))->sin_addr;
600 
601  vio->remote.ss_family= AF_INET;
602  vio->addrLen= sizeof (struct sockaddr_in);
603 
604  ip4->s_addr= htonl(INADDR_LOOPBACK);
605 
606  /* Initialize ip_buffer and port. */
607 
608  strmov(ip_buffer, "127.0.0.1");
609  *port= 0;
610  }
611  else
612  {
613  int err_code;
614  char port_buffer[NI_MAXSERV];
615 
616  struct sockaddr_storage addr_storage;
617  struct sockaddr *addr= (struct sockaddr *) &addr_storage;
618  size_socket addr_length= sizeof (addr_storage);
619 
620  /* Get sockaddr by socked fd. */
621 
622  err_code= mysql_socket_getpeername(vio->mysql_socket, addr, &addr_length);
623 
624  if (err_code)
625  {
626  DBUG_PRINT("exit", ("getpeername() gave error: %d", socket_errno));
627  DBUG_RETURN(TRUE);
628  }
629 
630  /* Normalize IP address. */
631 
632  vio_get_normalized_ip(addr, addr_length,
633  (struct sockaddr *) &vio->remote, &vio->addrLen);
634 
635  /* Get IP address & port number. */
636 
637  err_code= vio_getnameinfo((struct sockaddr *) &vio->remote,
638  ip_buffer, ip_buffer_size,
639  port_buffer, NI_MAXSERV,
640  NI_NUMERICHOST | NI_NUMERICSERV);
641 
642  if (err_code)
643  {
644  DBUG_PRINT("exit", ("getnameinfo() gave error: %s",
645  gai_strerror(err_code)));
646  DBUG_RETURN(TRUE);
647  }
648 
649  *port= (uint16) strtol(port_buffer, NULL, 10);
650  }
651 
652  DBUG_PRINT("exit", ("Client IP address: %s; port: %d",
653  (const char *) ip_buffer,
654  (int) *port));
655  DBUG_RETURN(FALSE);
656 }
657 
658 
668 // WL#4896: Not covered
669 static my_bool socket_peek_read(Vio *vio, uint *bytes)
670 {
671  my_socket sd= mysql_socket_getfd(vio->mysql_socket);
672 #if defined(_WIN32)
673  int len;
674  if (ioctlsocket(sd, FIONREAD, &len))
675  return TRUE;
676  *bytes= len;
677  return FALSE;
678 #elif defined(FIONREAD_IN_SYS_IOCTL) || defined(FIONREAD_IN_SYS_FILIO)
679  int len;
680  if (ioctl(sd, FIONREAD, &len) < 0)
681  return TRUE;
682  *bytes= len;
683  return FALSE;
684 #else
685  char buf[1024];
686  ssize_t res= recv(sd, &buf, sizeof(buf), MSG_PEEK);
687  if (res < 0)
688  return TRUE;
689  *bytes= res;
690  return FALSE;
691 #endif
692 }
693 
694 #ifndef _WIN32
695 
700 /*
701  Linux specific flag used to detect connection shutdown. The flag is
702  also used for half-closed notification, which here is interpreted as
703  if there is data available to be read from the socket.
704 */
705 #ifndef POLLRDHUP
706 #define POLLRDHUP 0
707 #endif
708 
709 /* Data may be read. */
710 #define MY_POLL_SET_IN (POLLIN | POLLPRI)
711 /* Data may be written. */
712 #define MY_POLL_SET_OUT (POLLOUT)
713 /* An error or hangup. */
714 #define MY_POLL_SET_ERR (POLLERR | POLLHUP | POLLNVAL)
715 
716 #endif
717 
734 #if !defined(_WIN32) && !defined(__APPLE__)
735 int vio_io_wait(Vio *vio, enum enum_vio_io_event event, int timeout)
736 {
737  int ret;
738  short revents= 0;
739  struct pollfd pfd;
740  my_socket sd= mysql_socket_getfd(vio->mysql_socket);
741  MYSQL_SOCKET_WAIT_VARIABLES(locker, state) /* no ';' */
742  DBUG_ENTER("vio_io_wait");
743 
744  memset(&pfd, 0, sizeof(pfd));
745 
746  pfd.fd= sd;
747 
748  /*
749  Set the poll bitmask describing the type of events.
750  The error flags are only valid in the revents bitmask.
751  */
752  switch (event)
753  {
754  case VIO_IO_EVENT_READ:
755  pfd.events= MY_POLL_SET_IN;
756  revents= MY_POLL_SET_IN | MY_POLL_SET_ERR | POLLRDHUP;
757  break;
758  case VIO_IO_EVENT_WRITE:
759  case VIO_IO_EVENT_CONNECT:
760  pfd.events= MY_POLL_SET_OUT;
761  revents= MY_POLL_SET_OUT | MY_POLL_SET_ERR;
762  break;
763  }
764 
765  MYSQL_START_SOCKET_WAIT(locker, &state, vio->mysql_socket, PSI_SOCKET_SELECT, 0);
766 
767  /*
768  Wait for the I/O event and return early in case of
769  error or timeout.
770  */
771  switch ((ret= poll(&pfd, 1, timeout)))
772  {
773  case -1:
774  /* On error, -1 is returned. */
775  break;
776  case 0:
777  /*
778  Set errno to indicate a timeout error.
779  (This is not compiled in on WIN32.)
780  */
781  errno= SOCKET_ETIMEDOUT;
782  break;
783  default:
784  /* Ensure that the requested I/O event has completed. */
785  DBUG_ASSERT(pfd.revents & revents);
786  break;
787  }
788 
789  MYSQL_END_SOCKET_WAIT(locker, 0);
790  DBUG_RETURN(ret);
791 }
792 
793 #else
794 
795 int vio_io_wait(Vio *vio, enum enum_vio_io_event event, int timeout)
796 {
797  int ret;
798  struct timeval tm;
799  my_socket fd= mysql_socket_getfd(vio->mysql_socket);
800  fd_set readfds, writefds, exceptfds;
801  MYSQL_SOCKET_WAIT_VARIABLES(locker, state) /* no ';' */
802  DBUG_ENTER("vio_io_wait");
803 
804  /* Convert the timeout, in milliseconds, to seconds and microseconds. */
805  if (timeout >= 0)
806  {
807  tm.tv_sec= timeout / 1000;
808  tm.tv_usec= (timeout % 1000) * 1000;
809  }
810 
811  FD_ZERO(&readfds);
812  FD_ZERO(&writefds);
813  FD_ZERO(&exceptfds);
814 
815  /* Always receive notification of exceptions. */
816  FD_SET(fd, &exceptfds);
817 
818  switch (event)
819  {
820  case VIO_IO_EVENT_READ:
821  /* Readiness for reading. */
822  FD_SET(fd, &readfds);
823  break;
824  case VIO_IO_EVENT_WRITE:
825  case VIO_IO_EVENT_CONNECT:
826  /* Readiness for writing. */
827  FD_SET(fd, &writefds);
828  break;
829  }
830 
831  MYSQL_START_SOCKET_WAIT(locker, &state, vio->mysql_socket, PSI_SOCKET_SELECT, 0);
832 
833  /* The first argument is ignored on Windows. */
834  ret= select(fd + 1, &readfds, &writefds, &exceptfds,
835  (timeout >= 0) ? &tm : NULL);
836 
837  MYSQL_END_SOCKET_WAIT(locker, 0);
838 
839  /* Set error code to indicate a timeout error. */
840  if (ret == 0)
841 #if defined(_WIN32)
842  WSASetLastError(SOCKET_ETIMEDOUT);
843 #elif defined(__APPLE__)
844  errno= SOCKET_ETIMEDOUT;
845 #else
846 #error Oops...Wrong OS
847 #endif
848 
849  /* Error or timeout? */
850  if (ret <= 0)
851  DBUG_RETURN(ret);
852 
853  /* The requested I/O event is ready? */
854  switch (event)
855  {
856  case VIO_IO_EVENT_READ:
857  ret= test(FD_ISSET(fd, &readfds));
858  break;
859  case VIO_IO_EVENT_WRITE:
860  case VIO_IO_EVENT_CONNECT:
861  ret= test(FD_ISSET(fd, &writefds));
862  break;
863  }
864 
865  /* Error conditions pending? */
866  ret|= test(FD_ISSET(fd, &exceptfds));
867 
868  /* Not a timeout, ensure that a condition was met. */
869  DBUG_ASSERT(ret);
870 
871  DBUG_RETURN(ret);
872 }
873 
874 #endif /* _WIN32 */
875 
876 
890 my_bool
891 vio_socket_connect(Vio *vio, struct sockaddr *addr, socklen_t len, int timeout)
892 {
893  int ret, wait;
894  DBUG_ENTER("vio_socket_connect");
895 
896  /* Only for socket-based transport types. */
897  DBUG_ASSERT(vio->type == VIO_TYPE_SOCKET || vio->type == VIO_TYPE_TCPIP);
898 
899  /* If timeout is not infinite, set socket to non-blocking mode. */
900  if ((timeout > -1) && vio_set_blocking(vio, FALSE))
901  DBUG_RETURN(TRUE);
902 
903  /* Initiate the connection. */
904  ret= mysql_socket_connect(vio->mysql_socket, addr, len);
905 
906 #ifdef _WIN32
907  wait= (ret == SOCKET_ERROR) &&
908  (WSAGetLastError() == WSAEINPROGRESS ||
909  WSAGetLastError() == WSAEWOULDBLOCK);
910 #else
911  wait= (ret == -1) && (errno == EINPROGRESS || errno == EALREADY);
912 #endif
913 
914  /*
915  The connection is in progress. The vio_io_wait() call can be used
916  to wait up to a specified period of time for the connection to
917  succeed.
918 
919  If vio_io_wait() returns 0 (after waiting however many seconds),
920  the socket never became writable (host is probably unreachable.)
921  Otherwise, if vio_io_wait() returns 1, then one of two conditions
922  exist:
923 
924  1. An error occurred. Use getsockopt() to check for this.
925  2. The connection was set up successfully: getsockopt() will
926  return 0 as an error.
927  */
928  if (wait && (vio_io_wait(vio, VIO_IO_EVENT_CONNECT, timeout) == 1))
929  {
930  int error;
931  IF_WIN(int, socklen_t) optlen= sizeof(error);
932  IF_WIN(char, void) *optval= (IF_WIN(char, void) *) &error;
933 
934  /*
935  At this point, we know that something happened on the socket.
936  But this does not means that everything is alright. The connect
937  might have failed. We need to retrieve the error code from the
938  socket layer. We must return success only if we are sure that
939  it was really a success. Otherwise we might prevent the caller
940  from trying another address to connect to.
941  */
942  if (!(ret= mysql_socket_getsockopt(vio->mysql_socket, SOL_SOCKET, SO_ERROR, optval, &optlen)))
943  {
944 #ifdef _WIN32
945  WSASetLastError(error);
946 #else
947  errno= error;
948 #endif
949  ret= test(error);
950  }
951  }
952 
953  /* If necessary, restore the blocking mode, but only if connect succeeded. */
954  if ((timeout > -1) && (ret == 0))
955  {
956  if (vio_set_blocking(vio, TRUE))
957  DBUG_RETURN(TRUE);
958  }
959 
960  DBUG_RETURN(test(ret));
961 }
962 
963 
976 my_bool vio_is_connected(Vio *vio)
977 {
978  uint bytes= 0;
979  DBUG_ENTER("vio_is_connected");
980 
981  /*
982  The first step of detecting an EOF condition is verifying
983  whether there is data to read. Data in this case would be
984  the EOF. An exceptional condition event and/or errors are
985  interpreted as if there is data to read.
986  */
987  if (!vio_io_wait(vio, VIO_IO_EVENT_READ, 0))
988  DBUG_RETURN(TRUE);
989 
990  /*
991  The second step is read() or recv() from the socket returning
992  0 (EOF). Unfortunately, it's not possible to call read directly
993  as we could inadvertently read meaningful connection data.
994  Simulate a read by retrieving the number of bytes available to
995  read -- 0 meaning EOF. In the presence of unrecoverable errors,
996  the socket is assumed to be disconnected.
997  */
998  while (socket_peek_read(vio, &bytes))
999  {
1000  if (socket_errno != SOCKET_EINTR)
1001  DBUG_RETURN(FALSE);
1002  }
1003 
1004 #ifdef HAVE_OPENSSL
1005  /* There might be buffered data at the SSL layer. */
1006  if (!bytes && vio->type == VIO_TYPE_SSL)
1007  bytes= SSL_pending((SSL*) vio->ssl_arg);
1008 #endif
1009 
1010  DBUG_RETURN(bytes ? TRUE : FALSE);
1011 }
1012 
1013 #ifndef DBUG_OFF
1014 
1023 ssize_t vio_pending(Vio *vio)
1024 {
1025  uint bytes= 0;
1026 
1027  /* Data pending on the read buffer. */
1028  if (vio->read_pos < vio->read_end)
1029  return vio->read_end - vio->read_pos;
1030 
1031  /* Skip non-socket based transport types. */
1032  if (vio->type == VIO_TYPE_TCPIP || vio->type == VIO_TYPE_SOCKET)
1033  {
1034  /* Obtain number of readable bytes in the socket buffer. */
1035  if (socket_peek_read(vio, &bytes))
1036  return -1;
1037  }
1038 
1039  /*
1040  SSL not checked due to a yaSSL bug in SSL_pending that
1041  causes it to attempt to read from the socket.
1042  */
1043 
1044  return (ssize_t) bytes;
1045 }
1046 
1047 #endif
1048 
1063 my_bool vio_is_no_name_error(int err_code)
1064 {
1065 #ifdef _WIN32
1066 
1067  return err_code == WSANO_DATA || err_code == EAI_NONAME;
1068 
1069 #else
1070 
1071  return err_code == EAI_NONAME;
1072 
1073 #endif
1074 }
1075 
1076 
1086 int vio_getnameinfo(const struct sockaddr *sa,
1087  char *hostname, size_t hostname_size,
1088  char *port, size_t port_size,
1089  int flags)
1090 {
1091  int sa_length= 0;
1092 
1093  switch (sa->sa_family) {
1094  case AF_INET:
1095  sa_length= sizeof (struct sockaddr_in);
1096 #ifdef HAVE_SOCKADDR_IN_SIN_LEN
1097  ((struct sockaddr_in *) sa)->sin_len= sa_length;
1098 #endif /* HAVE_SOCKADDR_IN_SIN_LEN */
1099  break;
1100 
1101 #ifdef HAVE_IPV6
1102  case AF_INET6:
1103  sa_length= sizeof (struct sockaddr_in6);
1104 # ifdef HAVE_SOCKADDR_IN6_SIN6_LEN
1105  ((struct sockaddr_in6 *) sa)->sin6_len= sa_length;
1106 # endif /* HAVE_SOCKADDR_IN6_SIN6_LEN */
1107  break;
1108 #endif /* HAVE_IPV6 */
1109  }
1110 
1111  return getnameinfo(sa, sa_length,
1112  hostname, hostname_size,
1113  port, port_size,
1114  flags);
1115 }