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