This is an automated email from the ASF dual-hosted git repository. bbender pushed a commit to branch feature/asio in repository https://gitbox.apache.org/repos/asf/geode-native.git
commit 8226ffd37b225c4f1d53895204ec9eeb73197985 Author: Blake Bender <[email protected]> AuthorDate: Thu Jul 23 14:54:47 2020 -0700 SNI proxy plumbing works from API layer down to TcpSslConn ctor - now just need to make proxy connection work properly --- cppcache/include/geode/PoolFactory.hpp | 5 +++ cppcache/integration/test/SNITest.cpp | 5 +-- cppcache/src/PoolAttributes.cpp | 59 ++++++++++++++++---------------- cppcache/src/PoolAttributes.hpp | 11 ++++++ cppcache/src/PoolFactory.cpp | 11 ++++-- cppcache/src/TcpSslConn.cpp | 57 ++++++++++++++++++++++++------ cppcache/src/TcpSslConn.hpp | 30 ++++++++++++---- cppcache/src/ThinClientLocatorHelper.cpp | 35 +++++++++++++++---- cppcache/src/ThinClientLocatorHelper.hpp | 5 +++ cppcache/src/ThinClientPoolDM.cpp | 4 ++- 10 files changed, 165 insertions(+), 57 deletions(-) diff --git a/cppcache/include/geode/PoolFactory.hpp b/cppcache/include/geode/PoolFactory.hpp index 195e28d..d554482 100644 --- a/cppcache/include/geode/PoolFactory.hpp +++ b/cppcache/include/geode/PoolFactory.hpp @@ -427,6 +427,11 @@ class APACHE_GEODE_EXPORT PoolFactory { PoolFactory& addServer(const std::string& host, int port); /** + * Set proxy info for SNI connection. Used for connecting via SNI proxy. + */ + PoolFactory& setSniProxy(const std::string& hostname, const int port); + + /** * If set to <code>true</code> then the created pool will have * server-to-client * subscriptions enabled. diff --git a/cppcache/integration/test/SNITest.cpp b/cppcache/integration/test/SNITest.cpp index 41afabd..4d50e08 100644 --- a/cppcache/integration/test/SNITest.cpp +++ b/cppcache/integration/test/SNITest.cpp @@ -128,7 +128,8 @@ TEST_F(SNITest, connectViaProxyTest) { cache.getPoolManager() .createFactory() - .addLocator("localhost", portNumber) + .addLocator("locator-maeve", 10334) + .setSniProxy("localhost", portNumber) .create("pool"); auto region = cache.createRegionFactory(RegionShortcut::PROXY) @@ -153,7 +154,7 @@ TEST_F(SNITest, connectionFailsTest) { cache.getPoolManager() .createFactory() - .addLocator("localhost", 10334) + .addLocator("locator-maeve", 10334) .create("pool"); auto region = cache.createRegionFactory(RegionShortcut::PROXY) diff --git a/cppcache/src/PoolAttributes.cpp b/cppcache/src/PoolAttributes.cpp index 2b4230d..16cd063 100644 --- a/cppcache/src/PoolAttributes.cpp +++ b/cppcache/src/PoolAttributes.cpp @@ -44,44 +44,45 @@ PoolAttributes::PoolAttributes() m_subsEnabled(PoolFactory::DEFAULT_SUBSCRIPTION_ENABLED), m_multiuserSecurityMode(PoolFactory::DEFAULT_MULTIUSER_SECURE_MODE), m_isPRSingleHopEnabled(PoolFactory::DEFAULT_PR_SINGLE_HOP_ENABLED), - m_serverGrp(PoolFactory::DEFAULT_SERVER_GROUP) {} + m_serverGrp(PoolFactory::DEFAULT_SERVER_GROUP), + m_sniProxyPort(0) {} std::shared_ptr<PoolAttributes> PoolAttributes::clone() { return std::make_shared<PoolAttributes>(*this); } /** Return true if all the attributes are equal to those of other. */ bool PoolAttributes::operator==(const PoolAttributes& other) const { - if (m_isThreadLocalConn != other.m_isThreadLocalConn) return false; - if (m_freeConnTimeout != other.m_freeConnTimeout) return false; - if (m_loadCondInterval != other.m_loadCondInterval) return false; - if (m_sockBufferSize != other.m_sockBufferSize) return false; - if (m_readTimeout != other.m_readTimeout) return false; - if (m_minConns != other.m_minConns) return false; - if (m_maxConns != other.m_maxConns) return false; - if (m_retryAttempts != other.m_retryAttempts) return false; - if (m_statsInterval != other.m_statsInterval) return false; - if (m_redundancy != other.m_redundancy) return false; - if (m_msgTrackTimeout != other.m_msgTrackTimeout) return false; - if (m_subsAckInterval != other.m_subsAckInterval) return false; - if (m_idleTimeout != other.m_idleTimeout) return false; - if (m_pingInterval != other.m_pingInterval) return false; - if (m_updateLocatorListInterval != other.m_updateLocatorListInterval) { - return false; - } - if (m_subsEnabled != other.m_subsEnabled) return false; - if (m_multiuserSecurityMode != other.m_multiuserSecurityMode) return false; - if (m_isPRSingleHopEnabled != other.m_isPRSingleHopEnabled) return false; - if (m_serverGrp != other.m_serverGrp) return false; - - if (m_initLocList.size() != other.m_initLocList.size()) return false; - if (m_initServList.size() != other.m_initServList.size()) return false; + bool result = false; - if (!compareVectorOfStrings(m_initLocList, other.m_initLocList)) return false; - if (!compareVectorOfStrings(m_initServList, other.m_initServList)) { - return false; + if ((m_isThreadLocalConn == other.m_isThreadLocalConn) + && (m_freeConnTimeout == other.m_freeConnTimeout) + && (m_loadCondInterval == other.m_loadCondInterval) + && (m_sockBufferSize == other.m_sockBufferSize) + && (m_readTimeout == other.m_readTimeout) + && (m_minConns == other.m_minConns) + && (m_maxConns == other.m_maxConns) + && (m_retryAttempts == other.m_retryAttempts) + && (m_statsInterval == other.m_statsInterval) + && (m_redundancy == other.m_redundancy) + && (m_msgTrackTimeout == other.m_msgTrackTimeout) + && (m_subsAckInterval == other.m_subsAckInterval) + && (m_idleTimeout == other.m_idleTimeout) + && (m_pingInterval == other.m_pingInterval) + && (m_updateLocatorListInterval == other.m_updateLocatorListInterval) + && (m_subsEnabled == other.m_subsEnabled) + && (m_multiuserSecurityMode == other.m_multiuserSecurityMode) + && (m_isPRSingleHopEnabled == other.m_isPRSingleHopEnabled) + && (m_serverGrp == other.m_serverGrp) + && (m_initLocList.size() == other.m_initLocList.size()) + && (m_initServList.size() == other.m_initServList.size()) + && (compareVectorOfStrings(m_initLocList, other.m_initLocList)) + && (compareVectorOfStrings(m_initServList, other.m_initServList)) + && (m_sniProxyHost == other.m_sniProxyHost) + && (m_sniProxyPort == other.m_sniProxyPort)) { + result = true; } - return true; + return result; } bool PoolAttributes::compareVectorOfStrings( diff --git a/cppcache/src/PoolAttributes.hpp b/cppcache/src/PoolAttributes.hpp index 3fee900..d205066 100644 --- a/cppcache/src/PoolAttributes.hpp +++ b/cppcache/src/PoolAttributes.hpp @@ -121,6 +121,14 @@ class PoolAttributes { m_statsInterval = statisticInterval; } + const std::string& getSniProxyHost() const { return m_sniProxyHost; } + + void setSniProxyHost(const std::string& host) { m_sniProxyHost = host; } + + int getSniProxyPort() const { return m_sniProxyPort; } + + void setSniProxyPort(const int port) { m_sniProxyPort = port; } + const std::string& getServerGroup() const { return m_serverGrp; } void setServerGroup(std::string group) { m_serverGrp = group; } @@ -197,6 +205,9 @@ class PoolAttributes { std::vector<std::string> m_initLocList; std::vector<std::string> m_initServList; + std::string m_sniProxyHost; + int m_sniProxyPort; + static bool compareVectorOfStrings( const std::vector<std::string>& thisVector, const std::vector<std::string>& otherVector); diff --git a/cppcache/src/PoolFactory.cpp b/cppcache/src/PoolFactory.cpp index 0ee2518..b8eced9 100644 --- a/cppcache/src/PoolFactory.cpp +++ b/cppcache/src/PoolFactory.cpp @@ -172,19 +172,26 @@ PoolFactory& PoolFactory::setServerGroup(std::string group) { } PoolFactory& PoolFactory::addLocator(const std::string& host, int port) { - addCheck(host, port); +// addCheck(host, port); m_attrs->addLocator(host, port); m_addedServerOrLocator = true; return *this; } PoolFactory& PoolFactory::addServer(const std::string& host, int port) { - addCheck(host, port); +// addCheck(host, port); m_attrs->addServer(host, port); m_addedServerOrLocator = true; return *this; } +PoolFactory& PoolFactory::setSniProxy(const std::string& hostname, + const int port) { + m_attrs->setSniProxyHost(hostname); + m_attrs->setSniProxyPort(port); + return *this; +} + PoolFactory& PoolFactory::setSubscriptionEnabled(bool enabled) { m_attrs->setSubscriptionEnabled(enabled); return *this; diff --git a/cppcache/src/TcpSslConn.cpp b/cppcache/src/TcpSslConn.cpp index 5158487..6513514 100644 --- a/cppcache/src/TcpSslConn.cpp +++ b/cppcache/src/TcpSslConn.cpp @@ -31,27 +31,64 @@ namespace apache { namespace geode { namespace client { -TcpSslConn::TcpSslConn(const std::string ipaddr, +TcpSslConn::TcpSslConn(const std::string& ipaddr, std::chrono::microseconds connect_timeout, - int32_t maxBuffSizePool, const std::string pubkeyfile, - const std::string privkeyfile, - const std::string pemPassword) + const std::string& sniProxy, int32_t maxBuffSizePool, + const std::string& pubkeyfile, + const std::string& privkeyfile, + const std::string& pemPassword) : TcpSslConn{ ipaddr.substr(0, ipaddr.find(':')), static_cast<uint16_t>(std::stoi(ipaddr.substr(ipaddr.find(':') + 1))), + sniProxy.substr(0, sniProxy.find(':')), + static_cast<uint16_t>( + std::stoi(sniProxy.substr(sniProxy.find(':') + 1))), connect_timeout, maxBuffSizePool, pubkeyfile, privkeyfile, pemPassword} {} -TcpSslConn::TcpSslConn(const std::string hostname, uint16_t port, +TcpSslConn::TcpSslConn(const std::string& ipaddr, std::chrono::microseconds connect_timeout, - int32_t maxBuffSizePool, const std::string pubkeyfile, - const std::string privkeyfile, - const std::string pemPassword) + int32_t maxBuffSizePool, const std::string& pubkeyfile, + const std::string& privkeyfile, + const std::string& pemPassword) + : TcpSslConn{ + ipaddr.substr(0, ipaddr.find(':')), + static_cast<uint16_t>(std::stoi(ipaddr.substr(ipaddr.find(':') + 1))), + connect_timeout, + maxBuffSizePool, + pubkeyfile, + privkeyfile, + pemPassword} {} + +TcpSslConn::TcpSslConn(const std::string& hostname, uint16_t port, + std::chrono::microseconds connect_timeout, + int32_t maxBuffSizePool, const std::string& pubkeyfile, + const std::string& privkeyfile, + const std::string& pemPassword) : TcpConn{hostname, port, connect_timeout, maxBuffSizePool}, ssl_context_{boost::asio::ssl::context::sslv23_client} { + init(pubkeyfile, privkeyfile, pemPassword); +} + +TcpSslConn::TcpSslConn(const std::string& hostname, uint16_t, + const std::string& sniProxyHostname, + uint16_t sniProxyPort, + std::chrono::microseconds connect_timeout, + int32_t maxBuffSizePool, const std::string& pubkeyfile, + const std::string& privkeyfile, + const std::string& pemPassword) + : TcpConn{sniProxyHostname, sniProxyPort, connect_timeout, maxBuffSizePool}, + ssl_context_{boost::asio::ssl::context::sslv23_client} { + init(pubkeyfile, privkeyfile, pemPassword, hostname); +} + +void TcpSslConn::init(const std::string& pubkeyfile, + const std::string& privkeyfile, + const std::string& pemPassword, + const std::string& sniHostname) { // Most of the SSL configuration provided *through* Asio is on the context. // This configuration is copied into each SSL instance upon construction. // That means you need to get your configuration in order before you @@ -74,7 +111,7 @@ TcpSslConn::TcpSslConn(const std::string hostname, uint16_t port, auto stream = std::unique_ptr<ssl_stream_type>( new ssl_stream_type{socket_, ssl_context_}); - SSL_set_tlsext_host_name(stream->native_handle(), "localhost"); + SSL_set_tlsext_host_name(stream->native_handle(), sniHostname.c_str()); stream->handshake(ssl_stream_type::client); @@ -98,7 +135,7 @@ size_t TcpSslConn::receive(char *buff, const size_t len, auto start = std::chrono::system_clock::now(); return boost::asio::read(*socket_stream_, boost::asio::buffer(buff, len), - [len, start](boost::system::error_code &ec, + [len, start](boost::system::error_code& ec, const std::size_t n) -> std::size_t { if (ec && ec != boost::asio::error::eof) { // Quit if we encounter an error. diff --git a/cppcache/src/TcpSslConn.hpp b/cppcache/src/TcpSslConn.hpp index e2ddf0b..cf5e45b 100644 --- a/cppcache/src/TcpSslConn.hpp +++ b/cppcache/src/TcpSslConn.hpp @@ -39,16 +39,34 @@ class TcpSslConn : public TcpConn { std::unique_ptr<ssl_stream_type> socket_stream_; public: - TcpSslConn(const std::string hostname, uint16_t port, + TcpSslConn(const std::string& hostname, uint16_t port, + const std::string& sniProxyHostname, uint16_t sniProxyPort, std::chrono::microseconds connect_timeout, int32_t maxBuffSizePool, - const std::string pubkeyfile, const std::string privkeyfile, - const std::string pemPassword); + const std::string& pubkeyfile, const std::string& privkeyfile, + const std::string& pemPassword); - TcpSslConn(const std::string ipaddr, std::chrono::microseconds wait, - int32_t maxBuffSizePool, const std::string pubkeyfile, - const std::string privkeyfile, const std::string pemPassword); + TcpSslConn(const std::string& hostname, uint16_t port, + std::chrono::microseconds connect_timeout, int32_t maxBuffSizePool, + const std::string& pubkeyfile, const std::string& privkeyfile, + const std::string& pemPassword); + + TcpSslConn(const std::string& ipaddr, + std::chrono::microseconds connect_timeout, int32_t maxBuffSizePool, + const std::string& pubkeyfile, const std::string& privkeyfile, + const std::string& pemPassword); + + TcpSslConn(const std::string& ipaddr, + std::chrono::microseconds connect_timeout, + const std::string& sniProxy, int32_t maxBuffSizePool, + const std::string& pubkeyfile, const std::string& privkeyfile, + const std::string& pemPassword); ~TcpSslConn() override; + + private: + void init(const std::string& pubkeyfile, const std::string& privkeyfile, + const std::string& pemPassword, + const std::string& sniHostname = ""); }; } // namespace client } // namespace geode diff --git a/cppcache/src/ThinClientLocatorHelper.cpp b/cppcache/src/ThinClientLocatorHelper.cpp index 611ff98..2a45d7e 100644 --- a/cppcache/src/ThinClientLocatorHelper.cpp +++ b/cppcache/src/ThinClientLocatorHelper.cpp @@ -45,7 +45,19 @@ const int BUFF_SIZE = 3000; ThinClientLocatorHelper::ThinClientLocatorHelper( const std::vector<std::string>& locatorAddresses, const ThinClientPoolDM* poolDM) - : m_poolDM(poolDM) { + : m_poolDM(poolDM), m_sniProxyHost(""), m_sniProxyPort(0) { + for (auto&& locatorAddress : locatorAddresses) { + m_locHostPort.emplace_back(locatorAddress); + } +} + +ThinClientLocatorHelper::ThinClientLocatorHelper( + const std::vector<std::string>& locatorAddresses, + const std::string& sniProxyHost, int sniProxyPort, + const ThinClientPoolDM* poolDM) + : m_poolDM(poolDM), + m_sniProxyHost(sniProxyHost), + m_sniProxyPort(sniProxyPort) { for (auto&& locatorAddress : locatorAddresses) { m_locHostPort.emplace_back(locatorAddress); } @@ -60,13 +72,22 @@ std::unique_ptr<Connector> ThinClientLocatorHelper::createConnection( ->getDistributedSystem() .getSystemProperties(); if (systemProperties.sslEnabled()) { - return std::unique_ptr<Connector>{new TcpSslConn{ - hostname, static_cast<uint16_t>(port), wait, maxBuffSizePool, - systemProperties.sslTrustStore(), systemProperties.sslKeyStore(), - systemProperties.sslKeystorePassword()}}; + if (m_sniProxyHost.empty()) { + return std::unique_ptr<Connector>(new TcpSslConn( + hostname, static_cast<uint16_t>(port), wait, maxBuffSizePool, + systemProperties.sslTrustStore(), systemProperties.sslKeyStore(), + systemProperties.sslKeystorePassword())); + } + else { + return std::unique_ptr<Connector>(new TcpSslConn( + hostname, static_cast<uint16_t>(port), m_sniProxyHost, m_sniProxyPort, + wait, maxBuffSizePool, systemProperties.sslTrustStore(), + systemProperties.sslKeyStore(), + systemProperties.sslKeystorePassword())); + } } else { - return std::unique_ptr<Connector>{new TcpConn{ - hostname, static_cast<uint16_t>(port), wait, maxBuffSizePool}}; + return std::unique_ptr<Connector>(new TcpConn( + hostname, static_cast<uint16_t>(port), wait, maxBuffSizePool)); } } diff --git a/cppcache/src/ThinClientLocatorHelper.hpp b/cppcache/src/ThinClientLocatorHelper.hpp index 0034b86..9e8e19c 100644 --- a/cppcache/src/ThinClientLocatorHelper.hpp +++ b/cppcache/src/ThinClientLocatorHelper.hpp @@ -45,6 +45,9 @@ class ThinClientLocatorHelper { public: ThinClientLocatorHelper(const std::vector<std::string>& locatorAddresses, const ThinClientPoolDM* poolDM); + ThinClientLocatorHelper(const std::vector<std::string>& locatorAddresses, + const std::string& sniProxyHost, int sniProxyPort, + const ThinClientPoolDM* poolDM); GfErrType getEndpointForNewFwdConn( ServerLocation& outEndpoint, std::string& additionalLoc, const std::set<ServerLocation>& exclEndPts, @@ -72,6 +75,8 @@ class ThinClientLocatorHelper { const ThinClientPoolDM* m_poolDM; ThinClientLocatorHelper(const ThinClientLocatorHelper&); ThinClientLocatorHelper& operator=(const ThinClientLocatorHelper&); + std::string m_sniProxyHost; + int m_sniProxyPort; }; } // namespace client } // namespace geode diff --git a/cppcache/src/ThinClientPoolDM.cpp b/cppcache/src/ThinClientPoolDM.cpp index c4909ec..75cf663 100644 --- a/cppcache/src/ThinClientPoolDM.cpp +++ b/cppcache/src/ThinClientPoolDM.cpp @@ -194,7 +194,9 @@ ThinClientPoolDM::ThinClientPoolDM(const char* name, throw IllegalStateException(msg); } reset(); - m_locHelper = new ThinClientLocatorHelper(m_attrs->m_initLocList, this); + m_locHelper = new ThinClientLocatorHelper(m_attrs->m_initLocList, + m_attrs->m_sniProxyHost, + m_attrs->m_sniProxyPort, this); m_stats = new PoolStats( cacheImpl->getStatisticsManager().getStatisticsFactory(), m_poolName);
