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);

Reply via email to