From 354bb40e75d94466e91fe6960523612c9d17ccfb Mon Sep 17 00:00:00 2001 From: Karen Arutyunov Date: Thu, 2 Nov 2017 23:11:29 +0300 Subject: Add implementation --- mysql/extra/yassl/src/socket_wrapper.cpp | 238 +++++++++++++++++++++++++++++++ 1 file changed, 238 insertions(+) create mode 100644 mysql/extra/yassl/src/socket_wrapper.cpp (limited to 'mysql/extra/yassl/src/socket_wrapper.cpp') diff --git a/mysql/extra/yassl/src/socket_wrapper.cpp b/mysql/extra/yassl/src/socket_wrapper.cpp new file mode 100644 index 0000000..a23c1c1 --- /dev/null +++ b/mysql/extra/yassl/src/socket_wrapper.cpp @@ -0,0 +1,238 @@ +/* + Copyright (c) 2005, 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 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; see the file COPYING. If not, write to the + Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, + MA 02110-1301 USA. +*/ + + +/* The socket wrapper source implements a Socket class that hides the + * differences between Berkely style sockets and Windows sockets, allowing + * transparent TCP access. + */ + + +#include "runtime.hpp" +#include "socket_wrapper.hpp" + +#ifndef _WIN32 + #include + #include + #include + #include + #include + #include + #include + #include +#endif // _WIN32 + +#if defined(__sun) || defined(__SCO_VERSION__) + #include +#endif + +#ifdef _WIN32 + const int SOCKET_EINVAL = WSAEINVAL; + const int SOCKET_EWOULDBLOCK = WSAEWOULDBLOCK; + const int SOCKET_EAGAIN = WSAEWOULDBLOCK; +#else + const int SOCKET_EINVAL = EINVAL; + const int SOCKET_EWOULDBLOCK = EWOULDBLOCK; + const int SOCKET_EAGAIN = EAGAIN; +#endif // _WIN32 + + +namespace { + + +extern "C" long system_recv(void *ptr, void *buf, size_t count) +{ + yaSSL::socket_t *socket = (yaSSL::socket_t *) ptr; + return ::recv(*socket, reinterpret_cast(buf), count, 0); +} + + +extern "C" long system_send(void *ptr, const void *buf, size_t count) +{ + yaSSL::socket_t *socket = (yaSSL::socket_t *) ptr; + return ::send(*socket, reinterpret_cast(buf), count, 0); +} + + +} + + +namespace yaSSL { + + +Socket::Socket(socket_t s) + : socket_(s), wouldBlock_(false), nonBlocking_(false), + ptr_(&socket_), send_func_(system_send), recv_func_(system_recv) +{} + + +void Socket::set_fd(socket_t s) +{ + socket_ = s; +} + + +socket_t Socket::get_fd() const +{ + return socket_; +} + + +Socket::~Socket() +{ + // don't close automatically now +} + + +void Socket::closeSocket() +{ + if (socket_ != INVALID_SOCKET) { +#ifdef _WIN32 + closesocket(socket_); +#else + close(socket_); +#endif + socket_ = INVALID_SOCKET; + } +} + + +uint Socket::get_ready() const +{ +#ifdef _WIN32 + unsigned long ready = 0; + ioctlsocket(socket_, FIONREAD, &ready); +#else + /* + 64-bit Solaris requires the variable passed to + FIONREAD be a 32-bit value. + */ + unsigned int ready = 0; + ioctl(socket_, FIONREAD, &ready); +#endif + + return ready; +} + + +void Socket::set_transport_ptr(void *ptr) +{ + ptr_ = ptr; +} + + +void Socket::set_transport_recv_function(yaSSL_recv_func_t recv_func) +{ + recv_func_ = recv_func; +} + + +void Socket::set_transport_send_function(yaSSL_send_func_t send_func) +{ + send_func_ = send_func; +} + + +uint Socket::send(const byte* buf, unsigned int sz, unsigned int& written) +{ + const byte* pos = buf; + const byte* end = pos + sz; + + wouldBlock_ = false; + + /* Remove send()/recv() hooks once non-blocking send is implemented. */ + while (pos != end) { + int sent = send_func_(ptr_, pos, static_cast(end - pos)); + if (sent == -1) { + if (get_lastError() == SOCKET_EWOULDBLOCK || + get_lastError() == SOCKET_EAGAIN) { + wouldBlock_ = true; // would have blocked this time only + nonBlocking_ = true; // nonblocking, win32 only way to tell + return 0; + } + return static_cast(-1); + } + pos += sent; + written += sent; + } + + return sz; +} + + +uint Socket::receive(byte* buf, unsigned int sz) +{ + wouldBlock_ = false; + + int recvd = recv_func_(ptr_, buf, sz); + + // idea to seperate error from would block by arnetheduck@gmail.com + if (recvd == -1) { + if (get_lastError() == SOCKET_EWOULDBLOCK || + get_lastError() == SOCKET_EAGAIN) { + wouldBlock_ = true; // would have blocked this time only + nonBlocking_ = true; // socket nonblocking, win32 only way to tell + return 0; + } + } + else if (recvd == 0) + return static_cast(-1); + + return recvd; +} + + +void Socket::shutDown(int how) +{ + shutdown(socket_, how); +} + + +int Socket::get_lastError() +{ +#ifdef _WIN32 + return WSAGetLastError(); +#else + return errno; +#endif +} + + +bool Socket::WouldBlock() const +{ + return wouldBlock_; +} + + +bool Socket::IsNonBlocking() const +{ + return nonBlocking_; +} + + +void Socket::set_lastError(int errorCode) +{ +#ifdef _WIN32 + WSASetLastError(errorCode); +#else + errno = errorCode; +#endif +} + + +} // namespace -- cgit v1.1