From 00af240dd8679698b61ca699e57a02133a2ae541 Mon Sep 17 00:00:00 2001 From: ihsandemir Date: Tue, 20 Nov 2018 10:08:53 +0300 Subject: [PATCH 1/7] Added `SocketOptions` configuration and increased default tcp read/write buffer size from 32KB to 128 KB. --- .../client/config/ClientNetworkConfig.h | 4 + .../hazelcast/client/config/SocketOptions.h | 141 ++++++++++++++++++ .../client/internal/socket/SSLSocket.h | 17 +-- .../client/internal/socket/SocketInterface.h | 38 +++++ .../client/internal/socket/TcpSocket.h | 21 +-- .../client/config/ClientNetworkConfig.cpp | 4 + .../hazelcast/client/config/SocketOptions.cpp | 71 +++++++++ .../client/internal/socket/SSLSocket.cpp | 31 +++- .../client/internal/socket/SocketFactory.cpp | 10 +- .../client/internal/socket/TcpSocket.cpp | 60 ++++++-- .../test/src/cluster/SocketOptionsTest.cpp | 42 ++++++ 11 files changed, 391 insertions(+), 48 deletions(-) create mode 100644 hazelcast/include/hazelcast/client/config/SocketOptions.h create mode 100644 hazelcast/include/hazelcast/client/internal/socket/SocketInterface.h create mode 100644 hazelcast/src/hazelcast/client/config/SocketOptions.cpp create mode 100644 hazelcast/test/src/cluster/SocketOptionsTest.cpp diff --git a/hazelcast/include/hazelcast/client/config/ClientNetworkConfig.h b/hazelcast/include/hazelcast/client/config/ClientNetworkConfig.h index a39cf631d1..a01e1c6d78 100644 --- a/hazelcast/include/hazelcast/client/config/ClientNetworkConfig.h +++ b/hazelcast/include/hazelcast/client/config/ClientNetworkConfig.h @@ -22,6 +22,7 @@ #include "hazelcast/util/HazelcastDll.h" #include "hazelcast/client/config/SSLConfig.h" #include "hazelcast/client/config/ClientAwsConfig.h" +#include "hazelcast/client/config/SocketOptions.h" #if defined(WIN32) || defined(_WIN32) || defined(WIN64) || defined(_WIN64) #pragma warning(push) @@ -180,6 +181,8 @@ namespace hazelcast { */ ClientNetworkConfig &addAddress(const Address &address); + SocketOptions &getSocketOptions(); + private: static int32_t CONNECTION_ATTEMPT_PERIOD; @@ -194,6 +197,7 @@ namespace hazelcast { std::vector
addressList; + SocketOptions socketOptions; }; } } diff --git a/hazelcast/include/hazelcast/client/config/SocketOptions.h b/hazelcast/include/hazelcast/client/config/SocketOptions.h new file mode 100644 index 0000000000..8942c0b25c --- /dev/null +++ b/hazelcast/include/hazelcast/client/config/SocketOptions.h @@ -0,0 +1,141 @@ +/* + * Copyright (c) 2008-2018, Hazelcast, Inc. All Rights Reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef HAZELCAST_CLIENT_CONFIG_SOCKETOPTIONS_H_ +#define HAZELCAST_CLIENT_CONFIG_SOCKETOPTIONS_H_ + +#include "hazelcast/util/HazelcastDll.h" + +#if defined(WIN32) || defined(_WIN32) || defined(WIN64) || defined(_WIN64) +#pragma warning(push) +#pragma warning(disable: 4251) //for dll export +#endif + +namespace hazelcast { + namespace client { + namespace config { + /** + * TCP Socket options + */ + class HAZELCAST_API SocketOptions { + public: + /** + * constant for kilobyte + */ + static const int KILO_BYTE = 1024; + + /** + * default buffer size of Bytes + */ + static const int DEFAULT_BUFFER_SIZE_BYTE = 128 * KILO_BYTE; + + SocketOptions(); + + /** + * TCP_NODELAY socket option + * + * @return true if enabled + */ + bool isTcpNoDelay() const; + + /** + * Enable/disable TCP_NODELAY socket option. + * + * @param tcpNoDelay + */ + SocketOptions &setTcpNoDelay(bool tcpNoDelay); + + /** + * SO_KEEPALIVE socket option + * + * @return true if enabled + */ + bool isKeepAlive() const; + + /** + * Enable/disable SO_KEEPALIVE socket option. + * + * @param keepAlive enabled if true + * @return SocketOptions configured + */ + SocketOptions &setKeepAlive(bool keepAlive); + + /** + * SO_REUSEADDR socket option. + * + * @return true if enabled + */ + bool isReuseAddress() const; + + /** + * Enable/disable the SO_REUSEADDR socket option. + * + * @param reuseAddress enabled if true + * @return SocketOptions configured + */ + SocketOptions &setReuseAddress(bool reuseAddress); + + /** + * Gets SO_LINGER with the specified linger time in seconds + * @return lingerSeconds value in seconds + */ + int getLingerSeconds() const; + + /** + * Enable/disable SO_LINGER with the specified linger time in seconds + * + * @param lingerSeconds value in seconds + * @return SocketOptions configured + */ + SocketOptions &setLingerSeconds(int lingerSeconds); + + /** + * Gets the SO_SNDBUF and SO_RCVBUF options to the specified value in KB + * @return bufferSize KB value + */ + int getBufferSize() const; + + /** + * Sets the SO_SNDBUF and SO_RCVBUF options to the specified value in KB + * + * @param bufferSize KB value + * @return SocketOptions configured + */ + SocketOptions &setBufferSize(int bufferSize); + + private: + // socket options + + bool tcpNoDelay; + + bool keepAlive; + + bool reuseAddress; + + int lingerSeconds; + + int bufferSize; + + }; + + } + } +} + +#if defined(WIN32) || defined(_WIN32) || defined(WIN64) || defined(_WIN64) +#pragma warning(pop) +#endif + +#endif /* HAZELCAST_CLIENT_CONFIG_SOCKETOPTIONS_H_ */ diff --git a/hazelcast/include/hazelcast/client/internal/socket/SSLSocket.h b/hazelcast/include/hazelcast/client/internal/socket/SSLSocket.h index b0d2334a01..b150e7a30c 100644 --- a/hazelcast/include/hazelcast/client/internal/socket/SSLSocket.h +++ b/hazelcast/include/hazelcast/client/internal/socket/SSLSocket.h @@ -21,7 +21,7 @@ #include #include -#include "hazelcast/client/Socket.h" +#include "hazelcast/client/internal/socket/SocketInterface.h" #include "hazelcast/client/Address.h" #include "hazelcast/util/AtomicBoolean.h" @@ -29,12 +29,6 @@ # define MSG_NOSIGNAL 0 #endif -#if defined(WIN32) || defined(_WIN32) || defined(WIN64) || defined(_WIN64) -#pragma warning(push) -#pragma warning(disable: 4251) //for dll export -#pragma warning(disable: 4003) //for not enough actual parameters for macro 'min' in asio wait_traits -#endif - namespace hazelcast { namespace client { namespace internal { @@ -42,7 +36,7 @@ namespace hazelcast { /** * SSL Socket using asio library */ - class HAZELCAST_API SSLSocket : public Socket { + class SSLSocket : public SocketInterface { public: struct CipherInfo { std::string name; @@ -107,6 +101,9 @@ namespace hazelcast { std::vector getCiphers() const; std::auto_ptr
localSocketAddress() const; + + virtual SocketInterface &setSocketOptions(const client::config::SocketOptions &socketOptions); + private: SSLSocket(const Socket &rhs); @@ -153,10 +150,6 @@ namespace hazelcast { } } -#if defined(WIN32) || defined(_WIN32) || defined(WIN64) || defined(_WIN64) -#pragma warning(pop) -#endif - #endif /* HZ_BUILD_WITH_SSL */ #endif /* HAZELCAST_CLIENT_INTERNAL_SOCKET_SSLSOCKET_H_ */ diff --git a/hazelcast/include/hazelcast/client/internal/socket/SocketInterface.h b/hazelcast/include/hazelcast/client/internal/socket/SocketInterface.h new file mode 100644 index 0000000000..8c8410ae7a --- /dev/null +++ b/hazelcast/include/hazelcast/client/internal/socket/SocketInterface.h @@ -0,0 +1,38 @@ +/* + * Copyright (c) 2008-2018, Hazelcast, Inc. All Rights Reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef HAZELCAST_CLIENT_INTERNAL_SOCKET_SOCKETINTERFACE_H_ +#define HAZELCAST_CLIENT_INTERNAL_SOCKET_SOCKETINTERFACE_H_ + +#include "hazelcast/client/Socket.h" +#include "hazelcast/client/config/SocketOptions.h" + +namespace hazelcast { + namespace client { + namespace internal { + namespace socket { + /** + * This interface is used to hide the methods here from public Socket interface. + */ + class SocketInterface : public Socket { + public: + virtual SocketInterface &setSocketOptions(const client::config::SocketOptions &socketOptions) = 0; + }; + } + } + } +} + +#endif /* HAZELCAST_CLIENT_INTERNAL_SOCKET_SOCKETINTERFACE_H_ */ diff --git a/hazelcast/include/hazelcast/client/internal/socket/TcpSocket.h b/hazelcast/include/hazelcast/client/internal/socket/TcpSocket.h index a5acb9bc01..7748744d51 100644 --- a/hazelcast/include/hazelcast/client/internal/socket/TcpSocket.h +++ b/hazelcast/include/hazelcast/client/internal/socket/TcpSocket.h @@ -35,20 +35,16 @@ typedef int socklen_t; #include #include #include +#include #endif -#include "hazelcast/client/Socket.h" - -#include "hazelcast/client/Address.h" -#include "hazelcast/util/AtomicBoolean.h" #include #include -#if defined(WIN32) || defined(_WIN32) || defined(WIN64) || defined(_WIN64) -#pragma warning(push) -#pragma warning(disable: 4251) //for dll export -#endif +#include "hazelcast/client/internal/socket/SocketInterface.h" +#include "hazelcast/client/Address.h" +#include "hazelcast/util/AtomicBoolean.h" #if !defined(MSG_NOSIGNAL) # define MSG_NOSIGNAL 0 @@ -61,7 +57,7 @@ namespace hazelcast { /** * c Sockets wrapper class. */ - class HAZELCAST_API TcpSocket : public Socket { + class TcpSocket : public SocketInterface { public: /** * Constructor @@ -119,6 +115,9 @@ namespace hazelcast { void setBlocking(bool blocking); std::auto_ptr
localSocketAddress() const; + + virtual SocketInterface &setSocketOptions(const client::config::SocketOptions &socketOptions); + private: TcpSocket(const Socket &rhs); @@ -143,8 +142,4 @@ namespace hazelcast { } } -#if defined(WIN32) || defined(_WIN32) || defined(WIN64) || defined(_WIN64) -#pragma warning(pop) -#endif - #endif /* HAZELCAST_CLIENT_INTERNAL_SOCKET_TCPSOCKET_H_ */ diff --git a/hazelcast/src/hazelcast/client/config/ClientNetworkConfig.cpp b/hazelcast/src/hazelcast/client/config/ClientNetworkConfig.cpp index 5d0b7c8575..5278ee3565 100644 --- a/hazelcast/src/hazelcast/client/config/ClientNetworkConfig.cpp +++ b/hazelcast/src/hazelcast/client/config/ClientNetworkConfig.cpp @@ -108,6 +108,10 @@ namespace hazelcast { addressList.push_back(address); return *this; } + + SocketOptions &ClientNetworkConfig::getSocketOptions() { + return socketOptions; + } } } } diff --git a/hazelcast/src/hazelcast/client/config/SocketOptions.cpp b/hazelcast/src/hazelcast/client/config/SocketOptions.cpp new file mode 100644 index 0000000000..0d1d635906 --- /dev/null +++ b/hazelcast/src/hazelcast/client/config/SocketOptions.cpp @@ -0,0 +1,71 @@ +/* + * Copyright (c) 2008-2018, Hazelcast, Inc. All Rights Reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#include "hazelcast/client/config/SocketOptions.h" + +namespace hazelcast { + namespace client { + namespace config { + SocketOptions::SocketOptions() : tcpNoDelay(true), keepAlive(true), reuseAddress(true), lingerSeconds(3), + bufferSize(DEFAULT_BUFFER_SIZE_BYTE) {} + + bool SocketOptions::isTcpNoDelay() const { + return tcpNoDelay; + } + + SocketOptions &SocketOptions::setTcpNoDelay(bool tcpNoDelay) { + SocketOptions::tcpNoDelay = tcpNoDelay; + return *this; + } + + bool SocketOptions::isKeepAlive() const { + return keepAlive; + } + + SocketOptions &SocketOptions::setKeepAlive(bool keepAlive) { + SocketOptions::keepAlive = keepAlive; + return *this; + } + + bool SocketOptions::isReuseAddress() const { + return reuseAddress; + } + + SocketOptions &SocketOptions::setReuseAddress(bool reuseAddress) { + SocketOptions::reuseAddress = reuseAddress; + return *this; + } + + int SocketOptions::getLingerSeconds() const { + return lingerSeconds; + } + + SocketOptions &SocketOptions::setLingerSeconds(int lingerSeconds) { + SocketOptions::lingerSeconds = lingerSeconds; + return *this; + } + + int SocketOptions::getBufferSize() const { + return bufferSize; + } + + SocketOptions &SocketOptions::setBufferSize(int bufferSize) { + SocketOptions::bufferSize = bufferSize; + return *this; + } + + } + } +} diff --git a/hazelcast/src/hazelcast/client/internal/socket/SSLSocket.cpp b/hazelcast/src/hazelcast/client/internal/socket/SSLSocket.cpp index b000acb4c5..856c73cda8 100644 --- a/hazelcast/src/hazelcast/client/internal/socket/SSLSocket.cpp +++ b/hazelcast/src/hazelcast/client/internal/socket/SSLSocket.cpp @@ -136,13 +136,6 @@ namespace hazelcast { socket->handshake(asio::ssl::stream::client); - int size = 32 * 1024; - socket->lowest_layer().set_option(asio::socket_base::receive_buffer_size(size)); - socket->lowest_layer().set_option(asio::socket_base::send_buffer_size(size)); - - // SO_NOSIGPIPE seems to be internally handled by asio on connect and accept. no such option - // is defined at the api, hence not setting this option - setBlocking(false); socketId = socket->lowest_layer().native_handle(); } catch (asio::system_error &e) { @@ -243,6 +236,30 @@ namespace hazelcast { return (int) numBytes; } + SocketInterface &SSLSocket::setSocketOptions(const client::config::SocketOptions &socketOptions) { + asio::basic_socket > &lowestLayer = + socket->lowest_layer(); + + lowestLayer.set_option(asio::ip::tcp::no_delay(socketOptions.isTcpNoDelay())); + + lowestLayer.set_option(asio::socket_base::keep_alive(socketOptions.isKeepAlive())); + + lowestLayer.set_option(asio::socket_base::reuse_address(socketOptions.isReuseAddress())); + + int lingerSeconds = socketOptions.getLingerSeconds(); + if (lingerSeconds > 0) { + lowestLayer.set_option(asio::socket_base::linger(true, lingerSeconds)); + } + + lowestLayer.set_option(asio::socket_base::receive_buffer_size(socketOptions.getBufferSize())); + lowestLayer.set_option(asio::socket_base::send_buffer_size(socketOptions.getBufferSize())); + + // SO_NOSIGPIPE seems to be internally handled by asio on connect and accept. no such option + // is defined at the api, hence not setting this option + + return *this; + } + SSLSocket::ReadHandler::ReadHandler(size_t &numRead, asio::error_code &ec) : numRead(numRead), errorCode(ec) {} diff --git a/hazelcast/src/hazelcast/client/internal/socket/SocketFactory.cpp b/hazelcast/src/hazelcast/client/internal/socket/SocketFactory.cpp index 228672fb06..cc70e9d2f5 100644 --- a/hazelcast/src/hazelcast/client/internal/socket/SocketFactory.cpp +++ b/hazelcast/src/hazelcast/client/internal/socket/SocketFactory.cpp @@ -90,12 +90,18 @@ namespace hazelcast { } std::auto_ptr SocketFactory::create(const Address &address) const { + std::auto_ptr socket; #ifdef HZ_BUILD_WITH_SSL if (sslContext.get()) { - return std::auto_ptr(new internal::socket::SSLSocket(address, *sslContext)); + socket.reset(new internal::socket::SSLSocket(address, *sslContext)); + } else { + socket.reset(new internal::socket::TcpSocket(address)); } #endif - return std::auto_ptr(new internal::socket::TcpSocket(address)); + + socket->setSocketOptions(clientContext.getClientConfig().getNetworkConfig().getSocketOptions()); + + return std::auto_ptr(socket); } } } diff --git a/hazelcast/src/hazelcast/client/internal/socket/TcpSocket.cpp b/hazelcast/src/hazelcast/client/internal/socket/TcpSocket.cpp index 4346b8ca58..36aaa03e1c 100644 --- a/hazelcast/src/hazelcast/client/internal/socket/TcpSocket.cpp +++ b/hazelcast/src/hazelcast/client/internal/socket/TcpSocket.cpp @@ -34,7 +34,7 @@ namespace hazelcast { namespace socket { TcpSocket::TcpSocket(const client::Address &address) : configAddress(address) { #if defined(WIN32) || defined(_WIN32) || defined(WIN64) || defined(_WIN64) - int n= WSAStartup(MAKEWORD(2, 0), &wsa_data); + int n = WSAStartup(MAKEWORD(2, 0), &wsa_data); if(n == -1) throw exception::IOException("TcpSocket::TcpSocket ", "WSAStartup error"); #endif struct addrinfo hints; @@ -58,19 +58,6 @@ namespace hazelcast { throwIOException("TcpSocket", "[TcpSocket::TcpSocket] Failed to obtain socket."); } isOpen = true; - int size = 32 * 1024; - if (::setsockopt(socketId, SOL_SOCKET, SO_RCVBUF, (char *) &size, sizeof(size))) { - throwIOException("Socket", "Failed set socket receive buffer size."); - } - if (::setsockopt(socketId, SOL_SOCKET, SO_SNDBUF, (char *) &size, sizeof(size))) { - throwIOException("TcpSocket", "Failed set socket send buffer size."); - } - #if defined(SO_NOSIGPIPE) - int on = 1; - if (setsockopt(socketId, SOL_SOCKET, SO_NOSIGPIPE, &on, sizeof(int))) { - throwIOException("TcpSocket", "Failed set socket option SO_NOSIGPIPE."); - } - #endif } TcpSocket::TcpSocket(int socketId) @@ -296,6 +283,51 @@ namespace hazelcast { return std::auto_ptr
(); } } + + SocketInterface &TcpSocket::setSocketOptions(const client::config::SocketOptions &socketOptions) { + int optionValue = socketOptions.getBufferSize(); + if (::setsockopt(socketId, SOL_SOCKET, SO_RCVBUF, (char *) &optionValue, sizeof(optionValue))) { + throwIOException("setSocketOptions", "Failed to set socket receive buffer size."); + } + if (::setsockopt(socketId, SOL_SOCKET, SO_SNDBUF, (char *) &optionValue, sizeof(optionValue))) { + throwIOException("setSocketOptions", "Failed to set socket send buffer size."); + } + + optionValue = socketOptions.isTcpNoDelay(); + if (::setsockopt(socketId, IPPROTO_TCP, TCP_NODELAY, (void *) &optionValue, sizeof(optionValue))) { + throwIOException("setSocketOptions", "Failed to set TCP_NODELAY option on the socket."); + } + + optionValue = socketOptions.isKeepAlive(); + if (::setsockopt(socketId, SOL_SOCKET, TCP_KEEPALIVE, &optionValue, sizeof(optionValue))) { + throwIOException("setSocketOptions", "Failed to set TCP_KEEPALIVE option on the socket."); + } + + optionValue = socketOptions.isReuseAddress(); + if (::setsockopt(socketId, SOL_SOCKET, SO_REUSEADDR, &optionValue, sizeof(optionValue))) { + throwIOException("setSocketOptions", "Failed to set SO_REUSEADDR option on the socket."); + } + + optionValue = socketOptions.getLingerSeconds(); + if (optionValue > 0) { + struct linger so_linger; + so_linger.l_onoff = 1; + so_linger.l_linger = optionValue; + + if (::setsockopt(socketId, SOL_SOCKET, SO_LINGER, &so_linger, sizeof(so_linger))) { + throwIOException("setSocketOptions", "Failed to set SO_LINGER option on the socket."); + } + } + + #if defined(SO_NOSIGPIPE) + optionValue = 1; + if (setsockopt(socketId, SOL_SOCKET, SO_NOSIGPIPE, &optionValue, sizeof(optionValue))) { + throwIOException("TcpSocket", "Failed to set socket option SO_NOSIGPIPE."); + } + #endif + + return *this; + } } } } diff --git a/hazelcast/test/src/cluster/SocketOptionsTest.cpp b/hazelcast/test/src/cluster/SocketOptionsTest.cpp new file mode 100644 index 0000000000..040ee72ae4 --- /dev/null +++ b/hazelcast/test/src/cluster/SocketOptionsTest.cpp @@ -0,0 +1,42 @@ +/* + * Copyright (c) 2008-2018, Hazelcast, Inc. All Rights Reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/** + * This has to be the first include, so that Python.h is the first include. Otherwise, compilation warning such as + * "_POSIX_C_SOURCE" redefined occurs. + */ +#include "HazelcastServerFactory.h" + +#include "ClientTestSupport.h" +#include "HazelcastServer.h" +#include "hazelcast/client/HazelcastClient.h" + +namespace hazelcast { + namespace client { + namespace test { + class SocketOptionsTest : public ClientTestSupport { + }; + + TEST_F(SocketOptionsTest, testConfiguration) { + HazelcastServer instance(*g_srvFactory); + + ClientConfig clientConfig; + clientConfig.getNetworkConfig().getSocketOptions().setKeepAlive(false).setReuseAddress(true).setTcpNoDelay(false).setLingerSeconds(5).setBufferSize(2 * 1024); + + HazelcastClient client(clientConfig); + } + } + } +} From 129103c0adb23144d3eed57ca2cb48e7e87edac9 Mon Sep 17 00:00:00 2001 From: ihsandemir Date: Tue, 20 Nov 2018 11:44:12 +0300 Subject: [PATCH 2/7] Changed to use SO_KEEPALIVE instead of TCP_KEEPALIVE which does not exist at Linux. Also some review comment fixes. --- .../hazelcast/client/config/SocketOptions.h | 20 +++++++++++++++---- .../client/internal/socket/TcpSocket.cpp | 4 ++-- 2 files changed, 18 insertions(+), 6 deletions(-) diff --git a/hazelcast/include/hazelcast/client/config/SocketOptions.h b/hazelcast/include/hazelcast/client/config/SocketOptions.h index 8942c0b25c..24581d4b16 100644 --- a/hazelcast/include/hazelcast/client/config/SocketOptions.h +++ b/hazelcast/include/hazelcast/client/config/SocketOptions.h @@ -96,21 +96,33 @@ namespace hazelcast { /** * Enable/disable SO_LINGER with the specified linger time in seconds * + * if set to a value of 0 or less then it is disabled. + * + * Default value is 3. + * * @param lingerSeconds value in seconds * @return SocketOptions configured */ SocketOptions &setLingerSeconds(int lingerSeconds); /** - * Gets the SO_SNDBUF and SO_RCVBUF options to the specified value in KB - * @return bufferSize KB value + * If set to 0 or less, then it is not set on the socket. + * + * The default value is DEFAULT_BUFFER_SIZE_BYTE + * + * Gets the SO_SNDBUF and SO_RCVBUF options value in bytes + * @return bufferSize Number of bytes */ int getBufferSize() const; /** - * Sets the SO_SNDBUF and SO_RCVBUF options to the specified value in KB + * If set to 0 or less, then it is not set on the socket. + * + * The default value is DEFAULT_BUFFER_SIZE_BYTE + * + * Sets the SO_SNDBUF and SO_RCVBUF options to the specified value in bytes * - * @param bufferSize KB value + * @param bufferSize Number of bytes * @return SocketOptions configured */ SocketOptions &setBufferSize(int bufferSize); diff --git a/hazelcast/src/hazelcast/client/internal/socket/TcpSocket.cpp b/hazelcast/src/hazelcast/client/internal/socket/TcpSocket.cpp index 36aaa03e1c..f8d23fe817 100644 --- a/hazelcast/src/hazelcast/client/internal/socket/TcpSocket.cpp +++ b/hazelcast/src/hazelcast/client/internal/socket/TcpSocket.cpp @@ -299,8 +299,8 @@ namespace hazelcast { } optionValue = socketOptions.isKeepAlive(); - if (::setsockopt(socketId, SOL_SOCKET, TCP_KEEPALIVE, &optionValue, sizeof(optionValue))) { - throwIOException("setSocketOptions", "Failed to set TCP_KEEPALIVE option on the socket."); + if (::setsockopt(socketId, SOL_SOCKET, SO_KEEPALIVE, &optionValue, sizeof(optionValue))) { + throwIOException("setSocketOptions", "Failed to set SO_KEEPALIVE option on the socket."); } optionValue = socketOptions.isReuseAddress(); From 582e8ef06f98c3de4dd16eebcc054ceb44ae5962 Mon Sep 17 00:00:00 2001 From: ihsandemir Date: Tue, 20 Nov 2018 14:07:33 +0300 Subject: [PATCH 3/7] Change setting the socket options after the socket id becomes valid(during SSL connect or after socket call for TcpSocket). --- .../hazelcast/client/connection/IOSelector.h | 6 ++- .../hazelcast/client/connection/InSelector.h | 2 +- .../hazelcast/client/connection/OutSelector.h | 2 +- .../client/internal/socket/SSLSocket.h | 13 ++++--- .../client/internal/socket/SocketInterface.h | 38 ------------------- .../client/internal/socket/TcpSocket.h | 11 +++--- .../ClientConnectionManagerImpl.cpp | 5 ++- .../client/connection/IOSelector.cpp | 6 +-- .../client/connection/InSelector.cpp | 4 +- .../client/connection/OutSelector.cpp | 5 +-- .../client/internal/socket/SSLSocket.cpp | 19 ++++++---- .../client/internal/socket/SocketFactory.cpp | 13 +++---- .../client/internal/socket/TcpSocket.cpp | 21 ++++++---- 13 files changed, 60 insertions(+), 85 deletions(-) delete mode 100644 hazelcast/include/hazelcast/client/internal/socket/SocketInterface.h diff --git a/hazelcast/include/hazelcast/client/connection/IOSelector.h b/hazelcast/include/hazelcast/client/connection/IOSelector.h index 26d4cefa3b..30bb00f903 100644 --- a/hazelcast/include/hazelcast/client/connection/IOSelector.h +++ b/hazelcast/include/hazelcast/client/connection/IOSelector.h @@ -38,6 +38,9 @@ namespace hazelcast { namespace client { class Socket; + namespace config { + class SocketOptions; + } namespace connection { class ListenerTask; @@ -47,7 +50,7 @@ namespace hazelcast { class HAZELCAST_API IOSelector : public util::Runnable { public: - IOSelector(ClientConnectionManagerImpl &connectionManager); + IOSelector(ClientConnectionManagerImpl &connectionManager, const config::SocketOptions &socketOptions); virtual ~IOSelector(); @@ -89,6 +92,7 @@ namespace hazelcast { std::auto_ptr wakeUpSocket; util::ConcurrentQueue listenerTasks; util::AtomicBoolean isAlive; + const config::SocketOptions &socketOptions; }; } } diff --git a/hazelcast/include/hazelcast/client/connection/InSelector.h b/hazelcast/include/hazelcast/client/connection/InSelector.h index 6c4865e12b..3d553385db 100644 --- a/hazelcast/include/hazelcast/client/connection/InSelector.h +++ b/hazelcast/include/hazelcast/client/connection/InSelector.h @@ -28,7 +28,7 @@ namespace hazelcast { namespace connection { class HAZELCAST_API InSelector : public IOSelector { public: - InSelector(ClientConnectionManagerImpl &connectionManager); + InSelector(ClientConnectionManagerImpl &connectionManager, const config::SocketOptions &socketOptions); void listenInternal(); diff --git a/hazelcast/include/hazelcast/client/connection/OutSelector.h b/hazelcast/include/hazelcast/client/connection/OutSelector.h index efb47ec4e8..114c9fc483 100644 --- a/hazelcast/include/hazelcast/client/connection/OutSelector.h +++ b/hazelcast/include/hazelcast/client/connection/OutSelector.h @@ -34,7 +34,7 @@ namespace hazelcast { namespace connection { class HAZELCAST_API OutSelector : public IOSelector { public: - OutSelector(ClientConnectionManagerImpl &connectionManager); + OutSelector(ClientConnectionManagerImpl &connectionManager, const config::SocketOptions &socketOptions); void listenInternal(); diff --git a/hazelcast/include/hazelcast/client/internal/socket/SSLSocket.h b/hazelcast/include/hazelcast/client/internal/socket/SSLSocket.h index b150e7a30c..04b6592fb8 100644 --- a/hazelcast/include/hazelcast/client/internal/socket/SSLSocket.h +++ b/hazelcast/include/hazelcast/client/internal/socket/SSLSocket.h @@ -21,8 +21,9 @@ #include #include -#include "hazelcast/client/internal/socket/SocketInterface.h" +#include "hazelcast/client/Socket.h" #include "hazelcast/client/Address.h" +#include "hazelcast/client/config/SocketOptions.h" #include "hazelcast/util/AtomicBoolean.h" #if !defined(MSG_NOSIGNAL) @@ -36,7 +37,7 @@ namespace hazelcast { /** * SSL Socket using asio library */ - class SSLSocket : public SocketInterface { + class SSLSocket : public Socket { public: struct CipherInfo { std::string name; @@ -48,7 +49,8 @@ namespace hazelcast { /** * Constructor */ - SSLSocket(const client::Address &address, asio::ssl::context &sslContext); + SSLSocket(const client::Address &address, asio::ssl::context &sslContext, + client::config::SocketOptions &socketOptions); /** * Destructor @@ -102,8 +104,6 @@ namespace hazelcast { std::auto_ptr
localSocketAddress() const; - virtual SocketInterface &setSocketOptions(const client::config::SocketOptions &socketOptions); - private: SSLSocket(const Socket &rhs); @@ -134,6 +134,8 @@ namespace hazelcast { void checkDeadline(const asio::error_code &ec); + void setSocketOptions(); + client::Address remoteEndpoint; asio::io_service ioService; @@ -142,6 +144,7 @@ namespace hazelcast { asio::deadline_timer deadline; asio::error_code errorCode; int socketId; + const client::config::SocketOptions &socketOptions; }; std::ostream &operator<<(std::ostream &out, const SSLSocket::CipherInfo &info); diff --git a/hazelcast/include/hazelcast/client/internal/socket/SocketInterface.h b/hazelcast/include/hazelcast/client/internal/socket/SocketInterface.h deleted file mode 100644 index 8c8410ae7a..0000000000 --- a/hazelcast/include/hazelcast/client/internal/socket/SocketInterface.h +++ /dev/null @@ -1,38 +0,0 @@ -/* - * Copyright (c) 2008-2018, Hazelcast, Inc. All Rights Reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -#ifndef HAZELCAST_CLIENT_INTERNAL_SOCKET_SOCKETINTERFACE_H_ -#define HAZELCAST_CLIENT_INTERNAL_SOCKET_SOCKETINTERFACE_H_ - -#include "hazelcast/client/Socket.h" -#include "hazelcast/client/config/SocketOptions.h" - -namespace hazelcast { - namespace client { - namespace internal { - namespace socket { - /** - * This interface is used to hide the methods here from public Socket interface. - */ - class SocketInterface : public Socket { - public: - virtual SocketInterface &setSocketOptions(const client::config::SocketOptions &socketOptions) = 0; - }; - } - } - } -} - -#endif /* HAZELCAST_CLIENT_INTERNAL_SOCKET_SOCKETINTERFACE_H_ */ diff --git a/hazelcast/include/hazelcast/client/internal/socket/TcpSocket.h b/hazelcast/include/hazelcast/client/internal/socket/TcpSocket.h index 7748744d51..cfc1a59ad5 100644 --- a/hazelcast/include/hazelcast/client/internal/socket/TcpSocket.h +++ b/hazelcast/include/hazelcast/client/internal/socket/TcpSocket.h @@ -42,7 +42,8 @@ typedef int socklen_t; #include #include -#include "hazelcast/client/internal/socket/SocketInterface.h" +#include "hazelcast/client/Socket.h" +#include "hazelcast/client/config/SocketOptions.h" #include "hazelcast/client/Address.h" #include "hazelcast/util/AtomicBoolean.h" @@ -57,7 +58,7 @@ namespace hazelcast { /** * c Sockets wrapper class. */ - class TcpSocket : public SocketInterface { + class TcpSocket : public Socket { public: /** * Constructor @@ -67,7 +68,7 @@ namespace hazelcast { /** * Constructor */ - TcpSocket(const client::Address &address); + TcpSocket(const client::Address &address, const client::config::SocketOptions *socketOptions); /** * Destructor @@ -116,8 +117,6 @@ namespace hazelcast { std::auto_ptr
localSocketAddress() const; - virtual SocketInterface &setSocketOptions(const client::config::SocketOptions &socketOptions); - private: TcpSocket(const Socket &rhs); @@ -127,6 +126,8 @@ namespace hazelcast { void throwIOException(int error, const char *methodName, const char *prefix) const; + void setSocketOptions(const client::config::SocketOptions &socketOptions); + const Address configAddress; struct addrinfo *serverInfo; diff --git a/hazelcast/src/hazelcast/client/connection/ClientConnectionManagerImpl.cpp b/hazelcast/src/hazelcast/client/connection/ClientConnectionManagerImpl.cpp index 4f597aa516..b745f82c86 100644 --- a/hazelcast/src/hazelcast/client/connection/ClientConnectionManagerImpl.cpp +++ b/hazelcast/src/hazelcast/client/connection/ClientConnectionManagerImpl.cpp @@ -66,8 +66,9 @@ namespace hazelcast { const boost::shared_ptr &addressTranslator, const std::vector > &addressProviders) : logger(client.getLogger()), client(client), - socketInterceptor(client.getClientConfig().getSocketInterceptor()), inSelector(*this), - outSelector(*this), + socketInterceptor(client.getClientConfig().getSocketInterceptor()), + inSelector(*this, client.getClientConfig().getNetworkConfig().getSocketOptions()), + outSelector(*this, client.getClientConfig().getNetworkConfig().getSocketOptions()), inSelectorThread(boost::shared_ptr(new util::RunnableDelegator(inSelector)), logger), outSelectorThread(boost::shared_ptr(new util::RunnableDelegator(outSelector)), logger), executionService(client.getClientExecutionService()), diff --git a/hazelcast/src/hazelcast/client/connection/IOSelector.cpp b/hazelcast/src/hazelcast/client/connection/IOSelector.cpp index fe40cf34cf..c21972fa16 100644 --- a/hazelcast/src/hazelcast/client/connection/IOSelector.cpp +++ b/hazelcast/src/hazelcast/client/connection/IOSelector.cpp @@ -38,9 +38,9 @@ namespace hazelcast { namespace client { namespace connection { - IOSelector::IOSelector(ClientConnectionManagerImpl &connectionManager) + IOSelector::IOSelector(ClientConnectionManagerImpl &connectionManager, const config::SocketOptions &socketOptions) : socketSet(connectionManager.getLogger()), connectionManager(connectionManager), - logger(connectionManager.getLogger()) { + logger(connectionManager.getLogger()), socketOptions(socketOptions) { t.tv_sec = 5; t.tv_usec = 0; } @@ -83,7 +83,7 @@ namespace hazelcast { else localAddress = "::1"; - wakeUpSocket.reset(new internal::socket::TcpSocket(Address(localAddress, p))); + wakeUpSocket.reset(new internal::socket::TcpSocket(Address(localAddress, p), NULL)); int error = wakeUpSocket->connect(5000); if (error == 0) { sleepingSocket.reset(serverSocket.accept()); diff --git a/hazelcast/src/hazelcast/client/connection/InSelector.cpp b/hazelcast/src/hazelcast/client/connection/InSelector.cpp index b5ed915ae8..ab39cbbab8 100644 --- a/hazelcast/src/hazelcast/client/connection/InSelector.cpp +++ b/hazelcast/src/hazelcast/client/connection/InSelector.cpp @@ -33,8 +33,8 @@ namespace hazelcast { namespace client { namespace connection { - InSelector::InSelector(ClientConnectionManagerImpl& connectionManager) - : IOSelector(connectionManager) { + InSelector::InSelector(ClientConnectionManagerImpl& connectionManager, const config::SocketOptions &socketOptions) + : IOSelector(connectionManager, socketOptions) { } bool InSelector::start() { diff --git a/hazelcast/src/hazelcast/client/connection/OutSelector.cpp b/hazelcast/src/hazelcast/client/connection/OutSelector.cpp index 8297309437..170c95493d 100644 --- a/hazelcast/src/hazelcast/client/connection/OutSelector.cpp +++ b/hazelcast/src/hazelcast/client/connection/OutSelector.cpp @@ -33,9 +33,8 @@ namespace hazelcast { namespace client { namespace connection { - OutSelector::OutSelector(ClientConnectionManagerImpl &connectionManager) - :IOSelector(connectionManager), wakeUpSocketSet(connectionManager.getLogger()) { - + OutSelector::OutSelector(ClientConnectionManagerImpl &connectionManager, const config::SocketOptions &socketOptions) + :IOSelector(connectionManager, socketOptions), wakeUpSocketSet(connectionManager.getLogger()) { } bool OutSelector::start() { diff --git a/hazelcast/src/hazelcast/client/internal/socket/SSLSocket.cpp b/hazelcast/src/hazelcast/client/internal/socket/SSLSocket.cpp index 856c73cda8..da19b1ede1 100644 --- a/hazelcast/src/hazelcast/client/internal/socket/SSLSocket.cpp +++ b/hazelcast/src/hazelcast/client/internal/socket/SSLSocket.cpp @@ -38,9 +38,9 @@ namespace hazelcast { namespace client { namespace internal { namespace socket { - SSLSocket::SSLSocket(const client::Address &address, asio::ssl::context &context) - : remoteEndpoint(address), sslContext(context), - deadline(ioService), socketId(-1) { + SSLSocket::SSLSocket(const client::Address &address, asio::ssl::context &context, + client::config::SocketOptions &socketOptions) : remoteEndpoint(address), + sslContext(context), deadline(ioService), socketId(-1), socketOptions(socketOptions) { socket = std::auto_ptr >( new asio::ssl::stream(ioService, sslContext)); } @@ -136,6 +136,8 @@ namespace hazelcast { socket->handshake(asio::ssl::stream::client); + setSocketOptions(); + setBlocking(false); socketId = socket->lowest_layer().native_handle(); } catch (asio::system_error &e) { @@ -236,7 +238,7 @@ namespace hazelcast { return (int) numBytes; } - SocketInterface &SSLSocket::setSocketOptions(const client::config::SocketOptions &socketOptions) { + void SSLSocket::setSocketOptions() { asio::basic_socket > &lowestLayer = socket->lowest_layer(); @@ -251,13 +253,14 @@ namespace hazelcast { lowestLayer.set_option(asio::socket_base::linger(true, lingerSeconds)); } - lowestLayer.set_option(asio::socket_base::receive_buffer_size(socketOptions.getBufferSize())); - lowestLayer.set_option(asio::socket_base::send_buffer_size(socketOptions.getBufferSize())); + int bufferSize = socketOptions.getBufferSize(); + if (bufferSize > 0) { + lowestLayer.set_option(asio::socket_base::receive_buffer_size(bufferSize)); + lowestLayer.set_option(asio::socket_base::send_buffer_size(bufferSize)); + } // SO_NOSIGPIPE seems to be internally handled by asio on connect and accept. no such option // is defined at the api, hence not setting this option - - return *this; } SSLSocket::ReadHandler::ReadHandler(size_t &numRead, asio::error_code &ec) : numRead(numRead), diff --git a/hazelcast/src/hazelcast/client/internal/socket/SocketFactory.cpp b/hazelcast/src/hazelcast/client/internal/socket/SocketFactory.cpp index cc70e9d2f5..4b996c2197 100644 --- a/hazelcast/src/hazelcast/client/internal/socket/SocketFactory.cpp +++ b/hazelcast/src/hazelcast/client/internal/socket/SocketFactory.cpp @@ -85,23 +85,20 @@ namespace hazelcast { #else (void) clientContext; #endif - + return true; } std::auto_ptr SocketFactory::create(const Address &address) const { - std::auto_ptr socket; #ifdef HZ_BUILD_WITH_SSL if (sslContext.get()) { - socket.reset(new internal::socket::SSLSocket(address, *sslContext)); - } else { - socket.reset(new internal::socket::TcpSocket(address)); + return std::auto_ptr(new internal::socket::SSLSocket(address, *sslContext, + clientContext.getClientConfig().getNetworkConfig().getSocketOptions())); } #endif - socket->setSocketOptions(clientContext.getClientConfig().getNetworkConfig().getSocketOptions()); - - return std::auto_ptr(socket); + return std::auto_ptr(new internal::socket::TcpSocket(address, + &clientContext.getClientConfig().getNetworkConfig().getSocketOptions())); } } } diff --git a/hazelcast/src/hazelcast/client/internal/socket/TcpSocket.cpp b/hazelcast/src/hazelcast/client/internal/socket/TcpSocket.cpp index f8d23fe817..e5b3f170a3 100644 --- a/hazelcast/src/hazelcast/client/internal/socket/TcpSocket.cpp +++ b/hazelcast/src/hazelcast/client/internal/socket/TcpSocket.cpp @@ -32,7 +32,8 @@ namespace hazelcast { namespace client { namespace internal { namespace socket { - TcpSocket::TcpSocket(const client::Address &address) : configAddress(address) { + TcpSocket::TcpSocket(const client::Address &address, const client::config::SocketOptions *socketOptions) + : configAddress(address) { #if defined(WIN32) || defined(_WIN32) || defined(WIN64) || defined(_WIN64) int n = WSAStartup(MAKEWORD(2, 0), &wsa_data); if(n == -1) throw exception::IOException("TcpSocket::TcpSocket ", "WSAStartup error"); @@ -57,6 +58,11 @@ namespace hazelcast { if (-1 == socketId) { throwIOException("TcpSocket", "[TcpSocket::TcpSocket] Failed to obtain socket."); } + + if (socketOptions) { + setSocketOptions(*socketOptions); + } + isOpen = true; } @@ -284,7 +290,7 @@ namespace hazelcast { } } - SocketInterface &TcpSocket::setSocketOptions(const client::config::SocketOptions &socketOptions) { + void TcpSocket::setSocketOptions(const client::config::SocketOptions &socketOptions) { int optionValue = socketOptions.getBufferSize(); if (::setsockopt(socketId, SOL_SOCKET, SO_RCVBUF, (char *) &optionValue, sizeof(optionValue))) { throwIOException("setSocketOptions", "Failed to set socket receive buffer size."); @@ -294,17 +300,17 @@ namespace hazelcast { } optionValue = socketOptions.isTcpNoDelay(); - if (::setsockopt(socketId, IPPROTO_TCP, TCP_NODELAY, (void *) &optionValue, sizeof(optionValue))) { + if (::setsockopt(socketId, IPPROTO_TCP, TCP_NODELAY, (char *) &optionValue, sizeof(optionValue))) { throwIOException("setSocketOptions", "Failed to set TCP_NODELAY option on the socket."); } optionValue = socketOptions.isKeepAlive(); - if (::setsockopt(socketId, SOL_SOCKET, SO_KEEPALIVE, &optionValue, sizeof(optionValue))) { + if (::setsockopt(socketId, SOL_SOCKET, SO_KEEPALIVE, (char *) &optionValue, sizeof(optionValue))) { throwIOException("setSocketOptions", "Failed to set SO_KEEPALIVE option on the socket."); } optionValue = socketOptions.isReuseAddress(); - if (::setsockopt(socketId, SOL_SOCKET, SO_REUSEADDR, &optionValue, sizeof(optionValue))) { + if (::setsockopt(socketId, SOL_SOCKET, SO_REUSEADDR, (char *) &optionValue, sizeof(optionValue))) { throwIOException("setSocketOptions", "Failed to set SO_REUSEADDR option on the socket."); } @@ -314,19 +320,18 @@ namespace hazelcast { so_linger.l_onoff = 1; so_linger.l_linger = optionValue; - if (::setsockopt(socketId, SOL_SOCKET, SO_LINGER, &so_linger, sizeof(so_linger))) { + if (::setsockopt(socketId, SOL_SOCKET, SO_LINGER, (char *) &so_linger, sizeof(so_linger))) { throwIOException("setSocketOptions", "Failed to set SO_LINGER option on the socket."); } } #if defined(SO_NOSIGPIPE) optionValue = 1; - if (setsockopt(socketId, SOL_SOCKET, SO_NOSIGPIPE, &optionValue, sizeof(optionValue))) { + if (setsockopt(socketId, SOL_SOCKET, SO_NOSIGPIPE, (char *) &optionValue, sizeof(optionValue))) { throwIOException("TcpSocket", "Failed to set socket option SO_NOSIGPIPE."); } #endif - return *this; } } } From eae45462f5127f9b4a7cd6ebdb8028c6e798d5d3 Mon Sep 17 00:00:00 2001 From: ihsandemir Date: Tue, 20 Nov 2018 14:25:18 +0300 Subject: [PATCH 4/7] Windows export dll fix. --- .../hazelcast/client/internal/socket/SSLSocket.h | 12 +++++++++++- .../hazelcast/client/internal/socket/TcpSocket.h | 11 ++++++++++- 2 files changed, 21 insertions(+), 2 deletions(-) diff --git a/hazelcast/include/hazelcast/client/internal/socket/SSLSocket.h b/hazelcast/include/hazelcast/client/internal/socket/SSLSocket.h index 04b6592fb8..1aa722f87e 100644 --- a/hazelcast/include/hazelcast/client/internal/socket/SSLSocket.h +++ b/hazelcast/include/hazelcast/client/internal/socket/SSLSocket.h @@ -30,6 +30,12 @@ # define MSG_NOSIGNAL 0 #endif +#if defined(WIN32) || defined(_WIN32) || defined(WIN64) || defined(_WIN64) +#pragma warning(push) +#pragma warning(disable: 4251) //for dll export +#pragma warning(disable: 4003) //for not enough actual parameters for macro 'min' in asio wait_traits +#endif + namespace hazelcast { namespace client { namespace internal { @@ -37,7 +43,7 @@ namespace hazelcast { /** * SSL Socket using asio library */ - class SSLSocket : public Socket { + class HAZELCAST_API SSLSocket : public Socket { public: struct CipherInfo { std::string name; @@ -153,6 +159,10 @@ namespace hazelcast { } } +#if defined(WIN32) || defined(_WIN32) || defined(WIN64) || defined(_WIN64) +#pragma warning(pop) +#endif + #endif /* HZ_BUILD_WITH_SSL */ #endif /* HAZELCAST_CLIENT_INTERNAL_SOCKET_SSLSOCKET_H_ */ diff --git a/hazelcast/include/hazelcast/client/internal/socket/TcpSocket.h b/hazelcast/include/hazelcast/client/internal/socket/TcpSocket.h index cfc1a59ad5..256b42e059 100644 --- a/hazelcast/include/hazelcast/client/internal/socket/TcpSocket.h +++ b/hazelcast/include/hazelcast/client/internal/socket/TcpSocket.h @@ -47,6 +47,11 @@ typedef int socklen_t; #include "hazelcast/client/Address.h" #include "hazelcast/util/AtomicBoolean.h" +#if defined(WIN32) || defined(_WIN32) || defined(WIN64) || defined(_WIN64) +#pragma warning(push) +#pragma warning(disable: 4251) //for dll export +#endif + #if !defined(MSG_NOSIGNAL) # define MSG_NOSIGNAL 0 #endif @@ -58,7 +63,7 @@ namespace hazelcast { /** * c Sockets wrapper class. */ - class TcpSocket : public Socket { + class HAZELCAST_API TcpSocket : public Socket { public: /** * Constructor @@ -143,4 +148,8 @@ namespace hazelcast { } } +#if defined(WIN32) || defined(_WIN32) || defined(WIN64) || defined(_WIN64) +#pragma warning(pop) +#endif + #endif /* HAZELCAST_CLIENT_INTERNAL_SOCKET_TCPSOCKET_H_ */ From a1fe056c5b40e270bc133c5a6b57181de5848000 Mon Sep 17 00:00:00 2001 From: ihsandemir Date: Tue, 20 Nov 2018 15:28:29 +0300 Subject: [PATCH 5/7] Review comment fixes. (from @mdumandag) --- hazelcast/include/hazelcast/client/config/SocketOptions.h | 4 ++-- hazelcast/src/hazelcast/client/config/SocketOptions.cpp | 4 ++-- hazelcast/src/hazelcast/client/internal/socket/SSLSocket.cpp | 2 +- hazelcast/src/hazelcast/client/internal/socket/TcpSocket.cpp | 2 +- hazelcast/test/src/cluster/SocketOptionsTest.cpp | 3 ++- 5 files changed, 8 insertions(+), 7 deletions(-) diff --git a/hazelcast/include/hazelcast/client/config/SocketOptions.h b/hazelcast/include/hazelcast/client/config/SocketOptions.h index 24581d4b16..14fa317d6c 100644 --- a/hazelcast/include/hazelcast/client/config/SocketOptions.h +++ b/hazelcast/include/hazelcast/client/config/SocketOptions.h @@ -113,7 +113,7 @@ namespace hazelcast { * Gets the SO_SNDBUF and SO_RCVBUF options value in bytes * @return bufferSize Number of bytes */ - int getBufferSize() const; + int getBufferSizeInBytes() const; /** * If set to 0 or less, then it is not set on the socket. @@ -125,7 +125,7 @@ namespace hazelcast { * @param bufferSize Number of bytes * @return SocketOptions configured */ - SocketOptions &setBufferSize(int bufferSize); + SocketOptions &setBufferSizeInBytes(int bufferSize); private: // socket options diff --git a/hazelcast/src/hazelcast/client/config/SocketOptions.cpp b/hazelcast/src/hazelcast/client/config/SocketOptions.cpp index 0d1d635906..1d78b4f857 100644 --- a/hazelcast/src/hazelcast/client/config/SocketOptions.cpp +++ b/hazelcast/src/hazelcast/client/config/SocketOptions.cpp @@ -57,11 +57,11 @@ namespace hazelcast { return *this; } - int SocketOptions::getBufferSize() const { + int SocketOptions::getBufferSizeInBytes() const { return bufferSize; } - SocketOptions &SocketOptions::setBufferSize(int bufferSize) { + SocketOptions &SocketOptions::setBufferSizeInBytes(int bufferSize) { SocketOptions::bufferSize = bufferSize; return *this; } diff --git a/hazelcast/src/hazelcast/client/internal/socket/SSLSocket.cpp b/hazelcast/src/hazelcast/client/internal/socket/SSLSocket.cpp index da19b1ede1..509dd21aa4 100644 --- a/hazelcast/src/hazelcast/client/internal/socket/SSLSocket.cpp +++ b/hazelcast/src/hazelcast/client/internal/socket/SSLSocket.cpp @@ -253,7 +253,7 @@ namespace hazelcast { lowestLayer.set_option(asio::socket_base::linger(true, lingerSeconds)); } - int bufferSize = socketOptions.getBufferSize(); + int bufferSize = socketOptions.getBufferSizeInBytes(); if (bufferSize > 0) { lowestLayer.set_option(asio::socket_base::receive_buffer_size(bufferSize)); lowestLayer.set_option(asio::socket_base::send_buffer_size(bufferSize)); diff --git a/hazelcast/src/hazelcast/client/internal/socket/TcpSocket.cpp b/hazelcast/src/hazelcast/client/internal/socket/TcpSocket.cpp index e5b3f170a3..cc0ca685bd 100644 --- a/hazelcast/src/hazelcast/client/internal/socket/TcpSocket.cpp +++ b/hazelcast/src/hazelcast/client/internal/socket/TcpSocket.cpp @@ -291,7 +291,7 @@ namespace hazelcast { } void TcpSocket::setSocketOptions(const client::config::SocketOptions &socketOptions) { - int optionValue = socketOptions.getBufferSize(); + int optionValue = socketOptions.getBufferSizeInBytes(); if (::setsockopt(socketId, SOL_SOCKET, SO_RCVBUF, (char *) &optionValue, sizeof(optionValue))) { throwIOException("setSocketOptions", "Failed to set socket receive buffer size."); } diff --git a/hazelcast/test/src/cluster/SocketOptionsTest.cpp b/hazelcast/test/src/cluster/SocketOptionsTest.cpp index 040ee72ae4..b04112fdbd 100644 --- a/hazelcast/test/src/cluster/SocketOptionsTest.cpp +++ b/hazelcast/test/src/cluster/SocketOptionsTest.cpp @@ -33,7 +33,8 @@ namespace hazelcast { HazelcastServer instance(*g_srvFactory); ClientConfig clientConfig; - clientConfig.getNetworkConfig().getSocketOptions().setKeepAlive(false).setReuseAddress(true).setTcpNoDelay(false).setLingerSeconds(5).setBufferSize(2 * 1024); + clientConfig.getNetworkConfig().getSocketOptions().setKeepAlive(false).setReuseAddress( + true).setTcpNoDelay(false).setLingerSeconds(5).setBufferSizeInBytes(2 * 1024); HazelcastClient client(clientConfig); } From 7e08b761a16eb9b9553f3998d386c8d480ef787b Mon Sep 17 00:00:00 2001 From: ihsandemir Date: Tue, 20 Nov 2018 15:33:52 +0300 Subject: [PATCH 6/7] Minor addition to the test. --- hazelcast/test/src/cluster/SocketOptionsTest.cpp | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/hazelcast/test/src/cluster/SocketOptionsTest.cpp b/hazelcast/test/src/cluster/SocketOptionsTest.cpp index b04112fdbd..e5a598e389 100644 --- a/hazelcast/test/src/cluster/SocketOptionsTest.cpp +++ b/hazelcast/test/src/cluster/SocketOptionsTest.cpp @@ -32,11 +32,18 @@ namespace hazelcast { TEST_F(SocketOptionsTest, testConfiguration) { HazelcastServer instance(*g_srvFactory); + const int bufferSize = 2 * 1024; ClientConfig clientConfig; clientConfig.getNetworkConfig().getSocketOptions().setKeepAlive(false).setReuseAddress( - true).setTcpNoDelay(false).setLingerSeconds(5).setBufferSizeInBytes(2 * 1024); + true).setTcpNoDelay(false).setLingerSeconds(5).setBufferSizeInBytes(bufferSize); HazelcastClient client(clientConfig); + + config::SocketOptions &socketOptions = client.getClientConfig().getNetworkConfig().getSocketOptions(); + ASSERT_FALSE(socketOptions.isKeepAlive()); + ASSERT_TRUE(socketOptions.isTcpNoDelay()); + ASSERT_EQ(5, socketOptions.getLingerSeconds()); + ASSERT_EQ(bufferSize, socketOptions.getBufferSizeInBytes()); } } } From aacf35feb8a7254ffea4c4cdfdf1c34aaccadf9f Mon Sep 17 00:00:00 2001 From: ihsandemir Date: Fri, 23 Nov 2018 16:45:59 +0300 Subject: [PATCH 7/7] Fix to the test. --- hazelcast/test/src/cluster/SocketOptionsTest.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/hazelcast/test/src/cluster/SocketOptionsTest.cpp b/hazelcast/test/src/cluster/SocketOptionsTest.cpp index e5a598e389..f602002983 100644 --- a/hazelcast/test/src/cluster/SocketOptionsTest.cpp +++ b/hazelcast/test/src/cluster/SocketOptionsTest.cpp @@ -41,7 +41,7 @@ namespace hazelcast { config::SocketOptions &socketOptions = client.getClientConfig().getNetworkConfig().getSocketOptions(); ASSERT_FALSE(socketOptions.isKeepAlive()); - ASSERT_TRUE(socketOptions.isTcpNoDelay()); + ASSERT_FALSE(socketOptions.isTcpNoDelay()); ASSERT_EQ(5, socketOptions.getLingerSeconds()); ASSERT_EQ(bufferSize, socketOptions.getBufferSizeInBytes()); }