You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@geode.apache.org by bb...@apache.org on 2020/08/13 18:57:01 UTC
[geode-native] 04/08: SNI proxy plumbing works from API layer down
to TcpSslConn ctor - now just need to make proxy connection work properly
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 <bb...@pivotal.io>
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);