diff options
Diffstat (limited to 'vio')
-rw-r--r-- | vio/.cvsignore | 1 | ||||
-rw-r--r--[-rwxr-xr-x] | vio/CMakeLists.txt | 20 | ||||
-rw-r--r-- | vio/Makefile.am | 28 | ||||
-rw-r--r-- | vio/test-ssl.c | 39 | ||||
-rw-r--r-- | vio/test-sslclient.c | 18 | ||||
-rw-r--r-- | vio/test-sslserver.c | 11 | ||||
-rw-r--r-- | vio/vio.c | 81 | ||||
-rw-r--r-- | vio/vio_priv.h | 33 | ||||
-rw-r--r-- | vio/viosocket.c | 514 | ||||
-rw-r--r-- | vio/viossl.c | 60 | ||||
-rw-r--r-- | vio/viosslfactories.c | 60 | ||||
-rw-r--r-- | vio/viotest-ssl.c | 37 |
12 files changed, 645 insertions, 257 deletions
diff --git a/vio/.cvsignore b/vio/.cvsignore deleted file mode 100644 index c17bb8b88e1..00000000000 --- a/vio/.cvsignore +++ /dev/null @@ -1 +0,0 @@ -skr99 diff --git a/vio/CMakeLists.txt b/vio/CMakeLists.txt index 164bcde7c4b..e61281a43d8 100755..100644 --- a/vio/CMakeLists.txt +++ b/vio/CMakeLists.txt @@ -1,4 +1,4 @@ -# Copyright (C) 2006 MySQL AB +# Copyright (c) 2006, 2010, Oracle and/or its affiliates. All rights reserved. # # 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 @@ -11,18 +11,12 @@ # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software -# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA -SET(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -D_DEBUG -DSAFEMALLOC -DSAFE_MUTEX") -SET(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} -D_DEBUG -DSAFEMALLOC -DSAFE_MUTEX") - -ADD_DEFINITIONS(-DUSE_SYMDIR) -INCLUDE_DIRECTORIES(${CMAKE_SOURCE_DIR}/include ${CMAKE_SOURCE_DIR}/extra/yassl/include) +INCLUDE_DIRECTORIES(${CMAKE_SOURCE_DIR}/include +${SSL_INCLUDE_DIRS}) +ADD_DEFINITIONS(${SSL_DEFINES}) SET(VIO_SOURCES vio.c viosocket.c viossl.c viosslfactories.c) - -IF(NOT SOURCE_SUBLIBS) - ADD_LIBRARY(vio ${VIO_SOURCES}) - ADD_DEPENDENCIES(vio GenError) -ENDIF(NOT SOURCE_SUBLIBS) - +ADD_CONVENIENCE_LIBRARY(vio ${VIO_SOURCES}) +TARGET_LINK_LIBRARIES(vio ${LIBSOCKET}) diff --git a/vio/Makefile.am b/vio/Makefile.am deleted file mode 100644 index 27596bb2fa4..00000000000 --- a/vio/Makefile.am +++ /dev/null @@ -1,28 +0,0 @@ -# Copyright (C) 2000-2003, 2005, 2006 MySQL 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 -# the Free Software Foundation; version 2 of the License. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - -INCLUDES = -I$(top_builddir)/include -I$(top_srcdir)/include \ - $(openssl_includes) -LDADD = @CLIENT_EXTRA_LDFLAGS@ $(openssl_libs) $(yassl_libs) -pkglib_LIBRARIES = libvio.a - -noinst_HEADERS = vio_priv.h - -libvio_a_SOURCES = vio.c viosocket.c viossl.c viosslfactories.c - -EXTRA_DIST= CMakeLists.txt - -# Don't update the files from bitkeeper -%::SCCS/s.% diff --git a/vio/test-ssl.c b/vio/test-ssl.c index 855dc5fbb3e..c99f5071055 100644 --- a/vio/test-ssl.c +++ b/vio/test-ssl.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2000 MySQL AB +/* Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved. 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 @@ -11,10 +11,10 @@ You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #include <my_global.h> -#if defined(HAVE_OPENSSL) && !defined(__NETWARE__) +#if defined(HAVE_OPENSSL) #include <my_sys.h> #include <m_string.h> #include <m_ctype.h> @@ -59,6 +59,9 @@ main(int argc, char** argv) struct st_VioSSLFd* ssl_acceptor= 0; struct st_VioSSLFd* ssl_connector= 0; Vio* client_vio=0, *server_vio=0; + enum enum_ssl_init_error ssl_init_error; + unsigned long ssl_error; + MY_INIT(argv[0]); DBUG_PROCESS(argv[0]); DBUG_PUSH(default_dbug_option); @@ -91,23 +94,23 @@ main(int argc, char** argv) ssl_acceptor = new_VioSSLAcceptorFd(server_key, server_cert, ca_file, ca_path, cipher); ssl_connector = new_VioSSLConnectorFd(client_key, client_cert, ca_file, - ca_path, cipher); + ca_path, cipher, &ssl_init_error); client_vio = (struct st_vio*)my_malloc(sizeof(struct st_vio),MYF(0)); client_vio->sd = sv[0]; client_vio->vioblocking(client_vio, 0, &unused); - sslconnect(ssl_connector,client_vio,60L); + sslconnect(ssl_connector,client_vio,60L,&ssl_error); server_vio = (struct st_vio*)my_malloc(sizeof(struct st_vio),MYF(0)); server_vio->sd = sv[1]; server_vio->vioblocking(client_vio, 0, &unused); - sslaccept(ssl_acceptor,server_vio,60L); + sslaccept(ssl_acceptor,server_vio,60L, &ssl_error); printf("Socketpair: %d , %d\n", client_vio->sd, server_vio->sd); child_pid = fork(); if (child_pid==-1) { - my_free((uchar*)ssl_acceptor,MYF(0)); - my_free((uchar*)ssl_connector,MYF(0)); + my_free(ssl_acceptor); + my_free(ssl_connector); fatal_error("fork"); } if (child_pid==0) @@ -116,28 +119,28 @@ main(int argc, char** argv) char xbuf[100]; int r = vio_read(client_vio,xbuf, sizeof(xbuf)); if (r<=0) { - my_free((uchar*)ssl_acceptor,MYF(0)); - my_free((uchar*)ssl_connector,MYF(0)); + my_free(ssl_acceptor); + my_free(ssl_connector); fatal_error("client:SSL_read"); } xbuf[r] = 0; printf("client:got %s\n", xbuf); - my_free((uchar*)client_vio,MYF(0)); - my_free((uchar*)ssl_acceptor,MYF(0)); - my_free((uchar*)ssl_connector,MYF(0)); + my_free(client_vio); + my_free(ssl_acceptor); + my_free(ssl_connector); } else { const char* s = "Huhuhuh"; int r = vio_write(server_vio,(uchar*)s, strlen(s)); if (r<=0) { - my_free((uchar*)ssl_acceptor,MYF(0)); - my_free((uchar*)ssl_connector,MYF(0)); + my_free(ssl_acceptor); + my_free(ssl_connector); fatal_error("server:SSL_write"); } - my_free((uchar*)server_vio,MYF(0)); - my_free((uchar*)ssl_acceptor,MYF(0)); - my_free((uchar*)ssl_connector,MYF(0)); + my_free(server_vio); + my_free(ssl_acceptor); + my_free(ssl_connector); } return 0; } diff --git a/vio/test-sslclient.c b/vio/test-sslclient.c index e1b8461397b..93fdb063754 100644 --- a/vio/test-sslclient.c +++ b/vio/test-sslclient.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2000 MySQL AB +/* Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved. 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 @@ -11,7 +11,7 @@ You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #include <my_global.h> #ifdef HAVE_OPENSSL @@ -50,6 +50,9 @@ main( int argc __attribute__((unused)), Vio* client_vio=0; int err; char xbuf[100]="Ohohhhhoh1234"; + enum enum_ssl_init_error ssl_init_error; + unsigned long ssl_error; + MY_INIT(argv[0]); DBUG_PROCESS(argv[0]); DBUG_PUSH(default_dbug_option); @@ -60,7 +63,8 @@ main( int argc __attribute__((unused)), if (ca_path!=0) printf("CApath : %s\n", ca_path); - ssl_connector = new_VioSSLConnectorFd(client_key, client_cert, ca_file, ca_path, cipher); + ssl_connector = new_VioSSLConnectorFd(client_key, client_cert, ca_file, ca_path, cipher, + &ssl_init_error); if(!ssl_connector) { fatal_error("client:new_VioSSLConnectorFd failed"); } @@ -81,16 +85,16 @@ main( int argc __attribute__((unused)), /* ----------------------------------------------- */ /* Now we have TCP conncetion. Start SSL negotiation. */ read(client_vio->sd,xbuf, sizeof(xbuf)); - sslconnect(ssl_connector,client_vio,60L); + sslconnect(ssl_connector,client_vio,60L,&ssl_error); err = vio_read(client_vio,xbuf, sizeof(xbuf)); if (err<=0) { - my_free((uchar*)ssl_connector,MYF(0)); + my_free(ssl_connector); fatal_error("client:SSL_read"); } xbuf[err] = 0; printf("client:got %s\n", xbuf); - my_free((uchar*)client_vio,MYF(0)); - my_free((uchar*)ssl_connector,MYF(0)); + my_free(client_vio); + my_free(ssl_connector); return 0; } #else /* HAVE_OPENSSL */ diff --git a/vio/test-sslserver.c b/vio/test-sslserver.c index f55b5bae53a..c81dc03dc58 100644 --- a/vio/test-sslserver.c +++ b/vio/test-sslserver.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2000 MySQL AB +/* Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved. 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 @@ -11,7 +11,7 @@ You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #include <my_global.h> #ifdef HAVE_OPENSSL @@ -52,6 +52,7 @@ do_ssl_stuff( TH_ARGS* args) const char* s = "Huhuhuhuuu"; Vio* server_vio; int err; + unsigned long ssl_error; DBUG_ENTER("do_ssl_stuff"); server_vio = vio_new(args->sd, VIO_TYPE_TCPIP, TRUE); @@ -60,7 +61,7 @@ do_ssl_stuff( TH_ARGS* args) /* TCP connection is ready. Do server side SSL. */ err = write(server_vio->sd,(uchar*)s, strlen(s)); - sslaccept(args->ssl_acceptor,server_vio,60L); + sslaccept(args->ssl_acceptor,server_vio,60L,&ssl_error); err = server_vio->write(server_vio,(uchar*)s, strlen(s)); DBUG_VOID_RETURN; } @@ -139,12 +140,12 @@ main(int argc __attribute__((unused)), char** argv) #if 0 if (err<=0) { - my_free((uchar*)ssl_acceptor,MYF(0)); + my_free(ssl_acceptor); fatal_error("server:SSL_write"); } #endif /* 0 */ - my_free((uchar*)ssl_acceptor,MYF(0)); + my_free(ssl_acceptor); return 0; } #else /* HAVE_OPENSSL */ diff --git a/vio/vio.c b/vio/vio.c index 486fe63da05..b8bc7bdae08 100644 --- a/vio/vio.c +++ b/vio/vio.c @@ -1,5 +1,4 @@ -/* Copyright (c) 2000-2007 MySQL AB, 2009 Sun Microsystems, Inc. - Use is subject to license terms. +/* Copyright (c) 2000, 2010, Oracle and/or its affiliates. All rights reserved. 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 @@ -23,6 +22,33 @@ #include "vio_priv.h" +#if defined(__WIN__) || defined(HAVE_SMEM) + +/** + Stub poll_read method that defaults to indicate that there + is data to read. + + Used for named pipe and shared memory VIO types. + + @param vio Unused. + @param timeout Unused. + + @retval FALSE There is data to read. +*/ + +static my_bool no_poll_read(Vio *vio __attribute__((unused)), + uint timeout __attribute__((unused))) +{ + return FALSE; +} + +#endif + +static my_bool has_no_data(Vio *vio __attribute__((unused))) +{ + return FALSE; +} + /* * Helper to fill most of the Vio* with defaults. */ @@ -57,10 +83,13 @@ static void vio_init(Vio* vio, enum enum_vio_type type, vio->was_interrupted=vio_was_interrupted; vio->vioclose =vio_close_pipe; vio->peer_addr =vio_peer_addr; - vio->in_addr =vio_in_addr; vio->vioblocking =vio_blocking; vio->is_blocking =vio_is_blocking; + vio->poll_read =no_poll_read; + vio->is_connected =vio_is_connected_pipe; + vio->has_data =has_no_data; + vio->timeout=vio_win32_timeout; /* Set default timeout */ vio->read_timeout_ms= INFINITE; @@ -82,10 +111,13 @@ static void vio_init(Vio* vio, enum enum_vio_type type, vio->was_interrupted=vio_was_interrupted; vio->vioclose =vio_close_shared_memory; vio->peer_addr =vio_peer_addr; - vio->in_addr =vio_in_addr; vio->vioblocking =vio_blocking; vio->is_blocking =vio_is_blocking; + vio->poll_read =no_poll_read; + vio->is_connected =vio_is_connected_shared_memory; + vio->has_data =has_no_data; + /* Currently, shared memory is on Windows only, hence the below is ok*/ vio->timeout= vio_win32_timeout; /* Set default timeout */ @@ -107,27 +139,32 @@ static void vio_init(Vio* vio, enum enum_vio_type type, vio->was_interrupted=vio_was_interrupted; vio->vioclose =vio_ssl_close; vio->peer_addr =vio_peer_addr; - vio->in_addr =vio_in_addr; vio->vioblocking =vio_ssl_blocking; vio->is_blocking =vio_is_blocking; vio->timeout =vio_timeout; + vio->poll_read =vio_poll_read; + vio->is_connected =vio_is_connected; + vio->has_data =vio_ssl_has_data; DBUG_VOID_RETURN; } #endif /* HAVE_OPENSSL */ - vio->viodelete =vio_delete; - vio->vioerrno =vio_errno; - vio->read= (flags & VIO_BUFFERED_READ) ? vio_read_buff : vio_read; - vio->write =vio_write; - vio->fastsend =vio_fastsend; - vio->viokeepalive =vio_keepalive; - vio->should_retry =vio_should_retry; - vio->was_interrupted=vio_was_interrupted; - vio->vioclose =vio_close; - vio->peer_addr =vio_peer_addr; - vio->in_addr =vio_in_addr; - vio->vioblocking =vio_blocking; - vio->is_blocking =vio_is_blocking; - vio->timeout =vio_timeout; + vio->viodelete =vio_delete; + vio->vioerrno =vio_errno; + vio->read= (flags & VIO_BUFFERED_READ) ? vio_read_buff : vio_read; + vio->write =vio_write; + vio->fastsend =vio_fastsend; + vio->viokeepalive =vio_keepalive; + vio->should_retry =vio_should_retry; + vio->was_interrupted =vio_was_interrupted; + vio->vioclose =vio_close; + vio->peer_addr =vio_peer_addr; + vio->vioblocking =vio_blocking; + vio->is_blocking =vio_is_blocking; + vio->timeout =vio_timeout; + vio->poll_read =vio_poll_read; + vio->is_connected =vio_is_connected; + vio->has_data= (flags & VIO_BUFFERED_READ) ? + vio_buff_has_data : has_no_data; DBUG_VOID_RETURN; } @@ -137,7 +174,7 @@ static void vio_init(Vio* vio, enum enum_vio_type type, void vio_reset(Vio* vio, enum enum_vio_type type, my_socket sd, HANDLE hPipe, uint flags) { - my_free(vio->read_buffer, MYF(MY_ALLOW_ZERO_PTR)); + my_free(vio->read_buffer); vio_init(vio, type, sd, hPipe, flags); } @@ -236,8 +273,8 @@ void vio_delete(Vio* vio) if (vio->type != VIO_CLOSED) vio->vioclose(vio); - my_free((uchar*) vio->read_buffer, MYF(MY_ALLOW_ZERO_PTR)); - my_free((uchar*) vio,MYF(0)); + my_free(vio->read_buffer); + my_free(vio); } diff --git a/vio/vio_priv.h b/vio/vio_priv.h index 91fb641d0d3..702ba4de38a 100644 --- a/vio/vio_priv.h +++ b/vio/vio_priv.h @@ -1,6 +1,7 @@ -/* - Copyright (c) 2003, 2005-2007 MySQL AB, 2009 Sun Microsystems, Inc. - Use is subject to license terms. +#ifndef VIO_PRIV_INCLUDED +#define VIO_PRIV_INCLUDED + +/* Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved. 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 @@ -13,8 +14,7 @@ You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA -*/ + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ /* Structures and functions private to the vio package */ @@ -25,11 +25,31 @@ #include <m_string.h> #include <violite.h> +#ifndef __WIN__ +#include <sys/socket.h> +#include <netdb.h> +#endif + #ifdef _WIN32 void vio_win32_timeout(Vio *vio, uint which, uint timeout); #endif +#ifdef __WIN__ +size_t vio_read_pipe(Vio *vio, uchar * buf, size_t size); +size_t vio_write_pipe(Vio *vio, const uchar * buf, size_t size); +my_bool vio_is_connected_pipe(Vio *vio); +int vio_close_pipe(Vio * vio); +#endif + +#ifdef HAVE_SMEM +size_t vio_read_shared_memory(Vio *vio, uchar * buf, size_t size); +size_t vio_write_shared_memory(Vio *vio, const uchar * buf, size_t size); +my_bool vio_is_connected_shared_memory(Vio *vio); +int vio_close_shared_memory(Vio * vio); +#endif + void vio_timeout(Vio *vio,uint which, uint timeout); +my_bool vio_buff_has_data(Vio *vio); #ifdef HAVE_OPENSSL #include "my_net.h" /* needed because of struct in_addr */ @@ -43,4 +63,7 @@ void vio_ssl_delete(Vio *vio); int vio_ssl_blocking(Vio *vio, my_bool set_blocking_mode, my_bool *old_mode); +my_bool vio_ssl_has_data(Vio *vio); + #endif /* HAVE_OPENSSL */ +#endif /* VIO_PRIV_INCLUDED */ diff --git a/vio/viosocket.c b/vio/viosocket.c index 9633a01f689..56aa84df5fc 100644 --- a/vio/viosocket.c +++ b/vio/viosocket.c @@ -1,5 +1,5 @@ /* - Copyright (c) 2001, 2011, Oracle and/or its affiliates. All rights reserved. + Copyright (c) 2001, 2012, Oracle and/or its affiliates. All rights reserved. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License @@ -13,8 +13,8 @@ You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA -*/ + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + 02110-1301 USA */ /* Note that we can't have assertion on file descriptors; The reason for @@ -30,7 +30,9 @@ #endif #include "vio_priv.h" - +#ifdef FIONREAD_IN_SYS_FILIO +# include <sys/filio.h> +#endif int vio_errno(Vio *vio __attribute__((unused))) { @@ -108,6 +110,10 @@ size_t vio_read_buff(Vio *vio, uchar* buf, size_t size) #undef VIO_UNBUFFERED_READ_MIN_SIZE } +my_bool vio_buff_has_data(Vio *vio) +{ + return (vio->read_pos != vio->read_end); +} size_t vio_write(Vio * vio, const uchar* buf, size_t size) { @@ -218,7 +224,7 @@ int vio_fastsend(Vio * vio __attribute__((unused))) #endif r= setsockopt(vio->sd, IPPROTO_TCP, TCP_NODELAY, - IF_WIN(const char*, void*) &nodelay, + IF_WIN((const char*), (void*)) &nodelay, sizeof(nodelay)); } @@ -250,11 +256,20 @@ int vio_keepalive(Vio* vio, my_bool set_keep_alive) my_bool -vio_should_retry(Vio * vio __attribute__((unused))) +vio_should_retry(Vio * vio) { int en = socket_errno; - return (en == SOCKET_EAGAIN || en == SOCKET_EINTR || - en == SOCKET_EWOULDBLOCK); + /* + man 2 read write + EAGAIN or EWOULDBLOCK when a socket is a non-blocking mode means + that the read/write would block. + man 7 socket + EAGAIN or EWOULDBLOCK when a socket is in a blocking mode means + that the corresponding receiving or sending timeout was reached. + */ + return en == SOCKET_EINTR || + (!vio_is_blocking(vio) && + (en == SOCKET_EAGAIN || en == SOCKET_EWOULDBLOCK)); } @@ -341,78 +356,370 @@ my_socket vio_fd(Vio* vio) return vio->sd; } +/** + Convert a sock-address (AF_INET or AF_INET6) into the "normalized" form, + which is the IPv4 form for IPv4-mapped or IPv4-compatible IPv6 addresses. + + @note Background: when IPv4 and IPv6 are used simultaneously, IPv4 + addresses may be written in a form of IPv4-mapped or IPv4-compatible IPv6 + addresses. That means, one address (a.b.c.d) can be written in three forms: + - IPv4: a.b.c.d; + - IPv4-compatible IPv6: ::a.b.c.d; + - IPv4-mapped IPv4: ::ffff:a.b.c.d; + + Having three forms of one address makes it a little difficult to compare + addresses with each other (the IPv4-compatible IPv6-address of foo.bar + will be different from the IPv4-mapped IPv6-address of foo.bar). + + @note This function can be made public when it's needed. + + @param src [in] source IP address (AF_INET or AF_INET6). + @param src_length [in] length of the src. + @param dst [out] a buffer to store normalized IP address + (sockaddr_storage). + @param dst_length [out] actual length of the normalized IP address. +*/ +static void vio_get_normalized_ip(const struct sockaddr *src, + int src_length, + struct sockaddr *dst, + int *dst_length) +{ + switch (src->sa_family) { + case AF_INET: + memcpy(dst, src, src_length); + *dst_length= src_length; + break; + +#ifdef HAVE_IPV6 + case AF_INET6: + { + const struct sockaddr_in6 *src_addr6= (const struct sockaddr_in6 *) src; + const struct in6_addr *src_ip6= &(src_addr6->sin6_addr); + const uint32 *src_ip6_int32= (uint32 *) src_ip6->s6_addr; + + if (IN6_IS_ADDR_V4MAPPED(src_ip6) || IN6_IS_ADDR_V4COMPAT(src_ip6)) + { + struct sockaddr_in *dst_ip4= (struct sockaddr_in *) dst; + + /* + This is an IPv4-mapped or IPv4-compatible IPv6 address. It should + be converted to the IPv4 form. + */ + + *dst_length= sizeof (struct sockaddr_in); + + memset(dst_ip4, 0, *dst_length); + dst_ip4->sin_family= AF_INET; + dst_ip4->sin_port= src_addr6->sin6_port; + + /* + In an IPv4 mapped or compatible address, the last 32 bits represent + the IPv4 address. The byte orders for IPv6 and IPv4 addresses are + the same, so a simple copy is possible. + */ + dst_ip4->sin_addr.s_addr= src_ip6_int32[3]; + } + else + { + /* This is a "native" IPv6 address. */ + + memcpy(dst, src, src_length); + *dst_length= src_length; + } + + break; + } +#endif /* HAVE_IPV6 */ + } +} + + +/** + Return the normalized IP address string for a sock-address. + + The idea is to return an IPv4-address for an IPv4-mapped and + IPv4-compatible IPv6 address. -my_bool vio_peer_addr(Vio * vio, char *buf, uint16 *port) + The function writes the normalized IP address to the given buffer. + The buffer should have enough space, otherwise error flag is returned. + The system constant INET6_ADDRSTRLEN can be used to reserve buffers of + the right size. + + @param addr [in] sockaddr object (AF_INET or AF_INET6). + @param addr_length [in] length of the addr. + @param ip_string [out] buffer to write normalized IP address. + @param ip_string_size [in] size of the ip_string. + + @return Error status. + @retval TRUE in case of error (the ip_string buffer is not enough). + @retval FALSE on success. +*/ + +my_bool vio_get_normalized_ip_string(const struct sockaddr *addr, + int addr_length, + char *ip_string, + size_t ip_string_size) +{ + struct sockaddr_storage norm_addr_storage; + struct sockaddr *norm_addr= (struct sockaddr *) &norm_addr_storage; + int norm_addr_length; + int err_code; + + vio_get_normalized_ip(addr, addr_length, norm_addr, &norm_addr_length); + + err_code= vio_getnameinfo(norm_addr, ip_string, ip_string_size, NULL, 0, + NI_NUMERICHOST); + + if (!err_code) + return FALSE; + + DBUG_PRINT("error", ("getnameinfo() failed with %d (%s).", + (int) err_code, + (const char *) gai_strerror(err_code))); + return TRUE; +} + + +/** + Return IP address and port of a VIO client socket. + + The function returns an IPv4 address if IPv6 support is disabled. + + The function returns an IPv4 address if the client socket is associated + with an IPv4-compatible or IPv4-mapped IPv6 address. Otherwise, the native + IPv6 address is returned. +*/ + +my_bool vio_peer_addr(Vio *vio, char *ip_buffer, uint16 *port, + size_t ip_buffer_size) { DBUG_ENTER("vio_peer_addr"); - DBUG_PRINT("enter", ("sd: %d", vio->sd)); + DBUG_PRINT("enter", ("Client socked fd: %d", (int) vio->sd)); + if (vio->localhost) { - strmov(buf,"127.0.0.1"); + /* + Initialize vio->remote and vio->addLen. Set vio->remote to IPv4 loopback + address. + */ + struct in_addr *ip4= &((struct sockaddr_in *) &(vio->remote))->sin_addr; + + vio->remote.ss_family= AF_INET; + vio->addrLen= sizeof (struct sockaddr_in); + + ip4->s_addr= htonl(INADDR_LOOPBACK); + + /* Initialize ip_buffer and port. */ + + strmov(ip_buffer, "127.0.0.1"); *port= 0; } else { - size_socket addrLen = sizeof(vio->remote); - if (getpeername(vio->sd, (struct sockaddr *) (&vio->remote), - &addrLen) != 0) + int err_code; + char port_buffer[NI_MAXSERV]; + + struct sockaddr_storage addr_storage; + struct sockaddr *addr= (struct sockaddr *) &addr_storage; + size_socket addr_length= sizeof (addr_storage); + + /* Get sockaddr by socked fd. */ + + err_code= getpeername(vio->sd, addr, &addr_length); + + if (err_code) { - DBUG_PRINT("exit", ("getpeername gave error: %d", socket_errno)); - DBUG_RETURN(1); + DBUG_PRINT("exit", ("getpeername() gave error: %d", socket_errno)); + DBUG_RETURN(TRUE); } - my_inet_ntoa(vio->remote.sin_addr,buf); - *port= ntohs(vio->remote.sin_port); - } - DBUG_PRINT("exit", ("addr: %s", buf)); - DBUG_RETURN(0); -} + /* Normalize IP address. */ -/* - Get in_addr for a TCP/IP connection + vio_get_normalized_ip(addr, addr_length, + (struct sockaddr *) &vio->remote, &vio->addrLen); - SYNOPSIS - vio_in_addr() - vio vio handle - in put in_addr here + /* Get IP address & port number. */ - NOTES - one must call vio_peer_addr() before calling this one -*/ + err_code= vio_getnameinfo((struct sockaddr *) &vio->remote, + ip_buffer, ip_buffer_size, + port_buffer, NI_MAXSERV, + NI_NUMERICHOST | NI_NUMERICSERV); -void vio_in_addr(Vio *vio, struct in_addr *in) -{ - DBUG_ENTER("vio_in_addr"); - if (vio->localhost) - bzero((char*) in, sizeof(*in)); - else - *in=vio->remote.sin_addr; - DBUG_VOID_RETURN; + if (err_code) + { + DBUG_PRINT("exit", ("getnameinfo() gave error: %s", + gai_strerror(err_code))); + DBUG_RETURN(TRUE); + } + + *port= (uint16) strtol(port_buffer, NULL, 10); + } + + DBUG_PRINT("exit", ("Client IP address: %s; port: %d", + (const char *) ip_buffer, + (int) *port)); + DBUG_RETURN(FALSE); } -/* Return 0 if there is data to be read */ +/** + Indicate whether there is data to read on a given socket. + + @note An exceptional condition event and/or errors are + interpreted as if there is data to read. + + @param sd A connected socket. + @param timeout Maximum time in seconds to poll. + + @retval FALSE There is data to read. + @retval TRUE There is no data to read. +*/ -my_bool vio_poll_read(Vio *vio,uint timeout) +static my_bool socket_poll_read(my_socket sd, uint timeout) { -#ifndef HAVE_POLL - return 0; -#else +#ifdef __WIN__ + int res; + my_socket fd= sd; + fd_set readfds, errorfds; + struct timeval tm; + DBUG_ENTER("socket_poll_read"); + tm.tv_sec= timeout; + tm.tv_usec= 0; + FD_ZERO(&readfds); + FD_ZERO(&errorfds); + FD_SET(fd, &readfds); + FD_SET(fd, &errorfds); + /* The first argument is ignored on Windows, so a conversion to int is OK */ + if ((res= select((int) fd, &readfds, NULL, &errorfds, &tm) <= 0)) + { + DBUG_RETURN(res < 0 ? 0 : 1); + } + res= FD_ISSET(fd, &readfds) || FD_ISSET(fd, &errorfds); + DBUG_RETURN(!res); +#elif defined(HAVE_POLL) struct pollfd fds; int res; - DBUG_ENTER("vio_poll"); - fds.fd=vio->sd; + DBUG_ENTER("socket_poll_read"); + fds.fd=sd; fds.events=POLLIN; fds.revents=0; if ((res=poll(&fds,1,(int) timeout*1000)) <= 0) { DBUG_RETURN(res < 0 ? 0 : 1); /* Don't return 1 on errors */ } - DBUG_RETURN(fds.revents & POLLIN ? 0 : 1); + DBUG_RETURN(fds.revents & (POLLIN | POLLERR | POLLHUP) ? 0 : 1); +#else + return 0; #endif } +/** + Retrieve the amount of data that can be read from a socket. + + @param vio A VIO object. + @param bytes[out] The amount of bytes available. + + @retval FALSE Success. + @retval TRUE Failure. +*/ + +static my_bool socket_peek_read(Vio *vio, uint *bytes) +{ +#if defined(_WIN32) + int len; + if (ioctlsocket(vio->sd, FIONREAD, &len)) + return TRUE; + *bytes= len; + return FALSE; +#elif defined(FIONREAD_IN_SYS_IOCTL) || defined(FIONREAD_IN_SYS_FILIO) + int len; + if (ioctl(vio->sd, FIONREAD, &len) < 0) + return TRUE; + *bytes= len; + return FALSE; +#else + char buf[1024]; + ssize_t res= recv(vio->sd, &buf, sizeof(buf), MSG_PEEK); + if (res < 0) + return TRUE; + *bytes= res; + return FALSE; +#endif +} + + +/** + Indicate whether there is data to read on a given socket. + + @remark Errors are interpreted as if there is data to read. + + @param sd A connected socket. + @param timeout Maximum time in seconds to wait. + + @retval FALSE There is data (or EOF) to read. Also FALSE if error. + @retval TRUE There is _NO_ data to read or timed out. +*/ + +my_bool vio_poll_read(Vio *vio, uint timeout) +{ + my_socket sd= vio->sd; + DBUG_ENTER("vio_poll_read"); +#ifdef HAVE_OPENSSL + if (vio->type == VIO_TYPE_SSL) + sd= SSL_get_fd((SSL*) vio->ssl_arg); +#endif + DBUG_RETURN(socket_poll_read(sd, timeout)); +} + + +/** + Determine if the endpoint of a connection is still available. + + @remark The socket is assumed to be disconnected if an EOF + condition is encountered. + + @param vio The VIO object. + + @retval TRUE EOF condition not found. + @retval FALSE EOF condition is signaled. +*/ + +my_bool vio_is_connected(Vio *vio) +{ + uint bytes= 0; + DBUG_ENTER("vio_is_connected"); + + /* In the presence of errors the socket is assumed to be connected. */ + + /* + The first step of detecting a EOF condition is veryfing + whether there is data to read. Data in this case would + be the EOF. + */ + if (vio_poll_read(vio, 0)) + DBUG_RETURN(TRUE); + + /* + The second step is read() or recv() from the socket returning + 0 (EOF). Unfortunelly, it's not possible to call read directly + as we could inadvertently read meaningful connection data. + Simulate a read by retrieving the number of bytes available to + read -- 0 meaning EOF. + */ + if (socket_peek_read(vio, &bytes)) + DBUG_RETURN(TRUE); + +#ifdef HAVE_OPENSSL + /* There might be buffered data at the SSL layer. */ + if (!bytes && vio->type == VIO_TYPE_SSL) + bytes= SSL_pending((SSL*) vio->ssl_arg); +#endif + + DBUG_RETURN(bytes ? TRUE : FALSE); +} + + void vio_timeout(Vio *vio, uint which, uint timeout) { #if defined(SO_SNDTIMEO) && defined(SO_RCVTIMEO) @@ -431,15 +738,13 @@ void vio_timeout(Vio *vio, uint which, uint timeout) #endif r= setsockopt(vio->sd, SOL_SOCKET, which ? SO_SNDTIMEO : SO_RCVTIMEO, - IF_WIN(const char*, const void*)&wait_timeout, + IF_WIN((const char*), (const void*))&wait_timeout, sizeof(wait_timeout)); } -#ifndef DBUG_OFF if (r != 0) DBUG_PRINT("error", ("setsockopt failed: %d, errno: %d", r, socket_errno)); -#endif DBUG_VOID_RETURN; #else @@ -544,11 +849,21 @@ size_t vio_write_pipe(Vio * vio, const uchar* buf, size_t size) } +my_bool vio_is_connected_pipe(Vio *vio) +{ + if (PeekNamedPipe(vio->hPipe, NULL, 0, NULL, NULL, NULL)) + return TRUE; + else + return (GetLastError() != ERROR_BROKEN_PIPE); +} + + int vio_close_pipe(Vio * vio) { int r; DBUG_ENTER("vio_close_pipe"); + CancelIo(vio->hPipe); CloseHandle(vio->pipe_overlapped.hEvent); DisconnectNamedPipe(vio->hPipe); r= CloseHandle(vio->hPipe); @@ -694,6 +1009,12 @@ size_t vio_write_shared_memory(Vio * vio, const uchar* buf, size_t size) } +my_bool vio_is_connected_shared_memory(Vio *vio) +{ + return (WaitForSingleObject(vio->event_conn_closed, 0) != WAIT_OBJECT_0); +} + + /** Close shared memory and DBUG_PRINT any errors that happen on closing. @return Zero if all closing functions succeed, and nonzero otherwise. @@ -755,3 +1076,96 @@ int vio_close_shared_memory(Vio * vio) } #endif /* HAVE_SMEM */ #endif /* __WIN__ */ + + +/** + Number of bytes in the read buffer. + + @return number of bytes in the read buffer or < 0 if error. +*/ + +ssize_t vio_pending(Vio *vio) +{ +#ifdef HAVE_OPENSSL + SSL *ssl= (SSL*) vio->ssl_arg; +#endif + + if (vio->read_pos < vio->read_end) + return vio->read_end - vio->read_pos; + +#ifdef HAVE_OPENSSL + if (ssl) + return SSL_pending(ssl); +#endif + + return 0; +} + + +/** + Checks if the error code, returned by vio_getnameinfo(), means it was the + "No-name" error. + + Windows-specific note: getnameinfo() returns WSANO_DATA instead of + EAI_NODATA or EAI_NONAME when no reverse mapping is available at the host + (i.e. Windows can't get hostname by IP-address). This error should be + treated as EAI_NONAME. + + @return if the error code is actually EAI_NONAME. + @retval true if the error code is EAI_NONAME. + @retval false otherwise. +*/ + +my_bool vio_is_no_name_error(int err_code) +{ +#ifdef _WIN32 + + return err_code == WSANO_DATA || err_code == EAI_NONAME; + +#else + + return err_code == EAI_NONAME; + +#endif +} + + +/** + This is a wrapper for the system getnameinfo(), because different OS + differ in the getnameinfo() implementation: + - Solaris 10 requires that the 2nd argument (salen) must match the + actual size of the struct sockaddr_storage passed to it; + - Mac OS X has sockaddr_in::sin_len and sockaddr_in6::sin6_len and + requires them to be filled. +*/ + +int vio_getnameinfo(const struct sockaddr *sa, + char *hostname, size_t hostname_size, + char *port, size_t port_size, + int flags) +{ + int sa_length= 0; + + switch (sa->sa_family) { + case AF_INET: + sa_length= sizeof (struct sockaddr_in); +#ifdef HAVE_SOCKADDR_IN_SIN_LEN + ((struct sockaddr_in *) sa)->sin_len= sa_length; +#endif /* HAVE_SOCKADDR_IN_SIN_LEN */ + break; + +#ifdef HAVE_IPV6 + case AF_INET6: + sa_length= sizeof (struct sockaddr_in6); +# ifdef HAVE_SOCKADDR_IN6_SIN6_LEN + ((struct sockaddr_in6 *) sa)->sin6_len= sa_length; +# endif /* HAVE_SOCKADDR_IN6_SIN6_LEN */ + break; +#endif /* HAVE_IPV6 */ + } + + return getnameinfo(sa, sa_length, + hostname, hostname_size, + port, port_size, + flags); +} diff --git a/vio/viossl.c b/vio/viossl.c index 0651fd8b7a3..e7ab7e4c6d1 100644 --- a/vio/viossl.c +++ b/vio/viossl.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2000 MySQL AB +/* Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved. 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 @@ -11,7 +11,7 @@ You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ /* Note that we can't have assertion on file descriptors; The reason for @@ -24,35 +24,7 @@ #ifdef HAVE_OPENSSL -#ifdef __NETWARE__ - -/* yaSSL already uses BSD sockets */ -#ifndef HAVE_YASSL - -/* - The default OpenSSL implementation on NetWare uses WinSock. - This code allows us to use the BSD sockets. -*/ - -static int SSL_set_fd_bsd(SSL *s, int fd) -{ - int result= -1; - BIO_METHOD *BIO_s_bsdsocket(); - BIO *bio; - - if ((bio= BIO_new(BIO_s_bsdsocket()))) - { - result= BIO_set_fd(bio, fd, BIO_NOCLOSE); - SSL_set_bio(s, bio, bio); - } - return result; -} - -#define SSL_set_fd(A, B) SSL_set_fd_bsd((A), (B)) - -#endif /* HAVE_YASSL */ -#endif /* __NETWARE__ */ - +#ifndef DBUG_OFF static void report_errors(SSL* ssl) @@ -61,9 +33,7 @@ report_errors(SSL* ssl) const char *file; const char *data; int line, flags; -#ifndef DBUG_OFF char buf[512]; -#endif DBUG_ENTER("report_errors"); @@ -81,6 +51,8 @@ report_errors(SSL* ssl) DBUG_VOID_RETURN; } +#endif + size_t vio_ssl_read(Vio *vio, uchar* buf, size_t size) { @@ -174,8 +146,9 @@ void vio_ssl_delete(Vio *vio) static int ssl_do(struct st_VioSSLFd *ptr, Vio *vio, long timeout, - int (*connect_accept_func)(SSL*)) + int (*connect_accept_func)(SSL*), unsigned long *errptr) { + int r; SSL *ssl; my_bool unused; my_bool was_blocking; @@ -190,7 +163,7 @@ static int ssl_do(struct st_VioSSLFd *ptr, Vio *vio, long timeout, if (!(ssl= SSL_new(ptr->ssl_context))) { DBUG_PRINT("error", ("SSL_new failure")); - report_errors(ssl); + *errptr= ERR_get_error(); vio_blocking(vio, was_blocking, &unused); DBUG_RETURN(1); } @@ -199,10 +172,10 @@ static int ssl_do(struct st_VioSSLFd *ptr, Vio *vio, long timeout, SSL_SESSION_set_timeout(SSL_get_session(ssl), timeout); SSL_set_fd(ssl, vio->sd); - if (connect_accept_func(ssl) < 1) + if ((r= connect_accept_func(ssl)) < 1) { DBUG_PRINT("error", ("SSL_connect/accept failure")); - report_errors(ssl); + *errptr= SSL_get_error(ssl, r); SSL_free(ssl); vio_blocking(vio, was_blocking, &unused); DBUG_RETURN(1); @@ -250,17 +223,17 @@ static int ssl_do(struct st_VioSSLFd *ptr, Vio *vio, long timeout, } -int sslaccept(struct st_VioSSLFd *ptr, Vio *vio, long timeout) +int sslaccept(struct st_VioSSLFd *ptr, Vio *vio, long timeout, unsigned long *errptr) { DBUG_ENTER("sslaccept"); - DBUG_RETURN(ssl_do(ptr, vio, timeout, SSL_accept)); + DBUG_RETURN(ssl_do(ptr, vio, timeout, SSL_accept, errptr)); } -int sslconnect(struct st_VioSSLFd *ptr, Vio *vio, long timeout) +int sslconnect(struct st_VioSSLFd *ptr, Vio *vio, long timeout, unsigned long *errptr) { DBUG_ENTER("sslconnect"); - DBUG_RETURN(ssl_do(ptr, vio, timeout, SSL_connect)); + DBUG_RETURN(ssl_do(ptr, vio, timeout, SSL_connect, errptr)); } @@ -274,6 +247,9 @@ int vio_ssl_blocking(Vio *vio __attribute__((unused)), return (set_blocking_mode ? 0 : 1); } - +my_bool vio_ssl_has_data(Vio *vio) +{ + return SSL_pending(vio->ssl_arg) > 0 ? TRUE : FALSE; +} #endif /* HAVE_OPENSSL */ diff --git a/vio/viosslfactories.c b/vio/viosslfactories.c index 037c34802e9..43975b9e3c4 100644 --- a/vio/viosslfactories.c +++ b/vio/viosslfactories.c @@ -1,6 +1,4 @@ -/* - Copyright (c) 2000-2008 MySQL AB, 2009 Sun Microsystems, Inc. - Use is subject to license terms. +/* Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved. 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 @@ -13,8 +11,7 @@ You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA -*/ + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #include "vio_priv.h" @@ -150,36 +147,6 @@ vio_set_cert_stuff(SSL_CTX *ctx, const char *cert_file, const char *key_file, } -#ifdef __NETWARE__ - -/* NetWare SSL cleanup */ -void netware_ssl_cleanup() -{ - /* free memory from SSL_library_init() */ - EVP_cleanup(); - -/* OpenSSL NetWare port specific functions */ -#ifndef HAVE_YASSL - - /* free global X509 method */ - X509_STORE_method_cleanup(); - - /* free the thread_hash error table */ - ERR_free_state_table(); -#endif -} - - -/* NetWare SSL initialization */ -static void netware_ssl_init() -{ - /* cleanup OpenSSL library */ - NXVmRegisterExitHandler(netware_ssl_cleanup, NULL); -} - -#endif /* __NETWARE__ */ - - static void check_ssl_init() { if (!ssl_algorithms_added) @@ -190,10 +157,6 @@ static void check_ssl_init() } -#ifdef __NETWARE__ - netware_ssl_init(); -#endif - if (!ssl_error_strings_loaded) { ssl_error_strings_loaded= TRUE; @@ -205,7 +168,7 @@ static void check_ssl_init() static struct st_VioSSLFd * new_VioSSLFd(const char *key_file, const char *cert_file, const char *ca_file, const char *ca_path, - const char *cipher, my_bool is_client_method, + const char *cipher, my_bool is_client_method, enum enum_ssl_init_error* error) { DH *dh; @@ -233,7 +196,7 @@ new_VioSSLFd(const char *key_file, const char *cert_file, *error= SSL_INITERR_MEMFAIL; DBUG_PRINT("error", ("%s", sslGetErrString(*error))); report_errors(); - my_free((void*)ssl_fd,MYF(0)); + my_free(ssl_fd); DBUG_RETURN(0); } @@ -249,7 +212,7 @@ new_VioSSLFd(const char *key_file, const char *cert_file, DBUG_PRINT("error", ("%s", sslGetErrString(*error))); report_errors(); SSL_CTX_free(ssl_fd->ssl_context); - my_free((void*)ssl_fd,MYF(0)); + my_free(ssl_fd); DBUG_RETURN(0); } @@ -266,7 +229,7 @@ new_VioSSLFd(const char *key_file, const char *cert_file, sslGetErrString(*error))); report_errors(); SSL_CTX_free(ssl_fd->ssl_context); - my_free((void*)ssl_fd,MYF(0)); + my_free(ssl_fd); DBUG_RETURN(0); } @@ -277,7 +240,7 @@ new_VioSSLFd(const char *key_file, const char *cert_file, DBUG_PRINT("error", ("%s", sslGetErrString(*error))); report_errors(); SSL_CTX_free(ssl_fd->ssl_context); - my_free((void*)ssl_fd,MYF(0)); + my_free(ssl_fd); DBUG_RETURN(0); } } @@ -287,7 +250,7 @@ new_VioSSLFd(const char *key_file, const char *cert_file, DBUG_PRINT("error", ("vio_set_cert_stuff failed")); report_errors(); SSL_CTX_free(ssl_fd->ssl_context); - my_free((void*)ssl_fd,MYF(0)); + my_free(ssl_fd); DBUG_RETURN(0); } @@ -306,11 +269,10 @@ new_VioSSLFd(const char *key_file, const char *cert_file, struct st_VioSSLFd * new_VioSSLConnectorFd(const char *key_file, const char *cert_file, const char *ca_file, const char *ca_path, - const char *cipher) + const char *cipher, enum enum_ssl_init_error* error) { struct st_VioSSLFd *ssl_fd; int verify= SSL_VERIFY_PEER; - enum enum_ssl_init_error dummy; /* Turn off verification of servers certificate if both @@ -320,7 +282,7 @@ new_VioSSLConnectorFd(const char *key_file, const char *cert_file, verify= SSL_VERIFY_NONE; if (!(ssl_fd= new_VioSSLFd(key_file, cert_file, ca_file, - ca_path, cipher, TRUE, &dummy))) + ca_path, cipher, TRUE, error))) { return 0; } @@ -367,6 +329,6 @@ new_VioSSLAcceptorFd(const char *key_file, const char *cert_file, void free_vio_ssl_acceptor_fd(struct st_VioSSLFd *fd) { SSL_CTX_free(fd->ssl_context); - my_free((uchar*) fd, MYF(0)); + my_free(fd); } #endif /* HAVE_OPENSSL */ diff --git a/vio/viotest-ssl.c b/vio/viotest-ssl.c index b8abbac4ed6..51d171d6923 100644 --- a/vio/viotest-ssl.c +++ b/vio/viotest-ssl.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2000 MySQL AB +/* Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved. 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 @@ -11,7 +11,7 @@ You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #include <my_global.h> #ifdef HAVE_OPENSSL @@ -60,6 +60,9 @@ int main(int argc, char **argv) struct st_VioSSLConnectorFd* ssl_connector=0; Vio* client_vio=0; Vio* server_vio=0; + enum enum_ssl_init_error ssl_init_error; + unsigned long ssl_error; + MY_INIT(argv[0]); DBUG_PROCESS(argv[0]); DBUG_PUSH(default_dbug_option); @@ -92,22 +95,22 @@ int main(int argc, char **argv) ssl_acceptor = new_VioSSLAcceptorFd(server_key, server_cert, ca_file, ca_path); ssl_connector = new_VioSSLConnectorFd(client_key, client_cert, ca_file, - ca_path); + ca_path, &ssl_init_error); client_vio = (Vio*)my_malloc(sizeof(struct st_vio),MYF(0)); client_vio->sd = sv[0]; - sslconnect(ssl_connector,client_vio); + sslconnect(ssl_connector,client_vio,&ssl_error); server_vio = (Vio*)my_malloc(sizeof(struct st_vio),MYF(0)); server_vio->sd = sv[1]; - sslaccept(ssl_acceptor,server_vio); + sslaccept(ssl_acceptor,server_vio,&ssl_error); printf("Socketpair: %d , %d\n", client_vio->sd, server_vio->sd); child_pid = fork(); if (child_pid==-1) { - my_free((uchar*)ssl_acceptor,MYF(0)); - my_free((uchar*)ssl_connector,MYF(0)); + my_free(ssl_acceptor); + my_free(ssl_connector); fatal_error("fork"); } if (child_pid==0) @@ -116,15 +119,15 @@ int main(int argc, char **argv) char xbuf[100]; int r = vio_ssl_read(client_vio,xbuf, sizeof(xbuf)); if (r<=0) { - my_free((uchar*)ssl_acceptor,MYF(0)); - my_free((uchar*)ssl_connector,MYF(0)); + my_free(ssl_acceptor); + my_free(ssl_connector); fatal_error("client:SSL_read"); } xbuf[r] = 0; printf("client:got %s\n", xbuf); - my_free((uchar*)client_vio,MYF(0)); - my_free((uchar*)ssl_acceptor,MYF(0)); - my_free((uchar*)ssl_connector,MYF(0)); + my_free(client_vio); + my_free(ssl_acceptor); + my_free(ssl_connector); sleep(1); } else @@ -132,13 +135,13 @@ int main(int argc, char **argv) const char* s = "Huhuhuh"; int r = vio_ssl_write(server_vio,(uchar*)s, strlen(s)); if (r<=0) { - my_free((uchar*)ssl_acceptor,MYF(0)); - my_free((uchar*)ssl_connector,MYF(0)); + my_free(ssl_acceptor); + my_free(ssl_connector); fatal_error("server:SSL_write"); } - my_free((uchar*)server_vio,MYF(0)); - my_free((uchar*)ssl_acceptor,MYF(0)); - my_free((uchar*)ssl_connector,MYF(0)); + my_free(server_vio); + my_free(ssl_acceptor); + my_free(ssl_connector); sleep(1); } return 0; |