This is an automated email from the ASF dual-hosted git repository.

bcall pushed a commit to branch 9.1.x
in repository https://gitbox.apache.org/repos/asf/trafficserver.git


The following commit(s) were added to refs/heads/9.1.x by this push:
     new 281416ad9 SNIConfig (tunnel_route): Change the way we extract matched 
subgroups from the server name. (#8589)
281416ad9 is described below

commit 281416ad90b95f4adf752df3f323ce8c04789387
Author: Damian Meden <[email protected]>
AuthorDate: Wed Jan 19 15:12:25 2022 +0000

    SNIConfig (tunnel_route): Change the way we extract matched subgroups from 
the server name. (#8589)
    
    This now uses the provided offsets from pcre_exec to read each matched 
group, this avoids
    allocating memory for the subgroups. There was a memory leak here as well 
which is now eliminated.
    This also changes the ActionItem::Context vector of strings to a vector of 
views to keep each matched group.
    
    (cherry picked from commit 4f0c4f21ce9e507331f4d92e63e56a0642cd08d5)
    
     Conflicts:
            iocore/net/SSLSNIConfig.cc
---
 iocore/net/P_SNIActionPerformer.h |  9 ++++++---
 iocore/net/P_SSLSNI.h             |  3 ++-
 iocore/net/SSLSNIConfig.cc        | 28 ++++++++++++----------------
 iocore/net/TLSSNISupport.cc       |  7 ++++++-
 4 files changed, 26 insertions(+), 21 deletions(-)

diff --git a/iocore/net/P_SNIActionPerformer.h 
b/iocore/net/P_SNIActionPerformer.h
index 9876b1db3..65958cf52 100644
--- a/iocore/net/P_SNIActionPerformer.h
+++ b/iocore/net/P_SNIActionPerformer.h
@@ -45,11 +45,14 @@ public:
    * Context should contain extra data needed to be passed to the actual 
SNIAction.
    */
   struct Context {
+    using CapturedGroupViewVec = std::vector<std::string_view>;
     /**
      * if any, fqdn_wildcard_captured_groups will hold the captured groups 
from the `fqdn`
-     * match which will be used to construct the tunnel destination.
+     * match which will be used to construct the tunnel destination. This 
vector contains only
+     * partial views of the original server name, group views are valid as 
long as the original
+     * string from where the groups were obtained lives.
      */
-    std::optional<std::vector<std::string>> _fqdn_wildcard_captured_groups;
+    std::optional<CapturedGroupViewVec> _fqdn_wildcard_captured_groups;
   };
 
   virtual int SNIAction(TLSSNISupport *snis, const Context &ctx) const = 0;
@@ -144,7 +147,7 @@ private:
    * groups could be at any order.
    */
   std::string
-  replace_match_groups(const std::string &dst, const std::vector<std::string> 
&groups) const
+  replace_match_groups(const std::string &dst, const 
ActionItem::Context::CapturedGroupViewVec &groups) const
   {
     if (dst.empty() || groups.empty()) {
       return dst;
diff --git a/iocore/net/P_SSLSNI.h b/iocore/net/P_SSLSNI.h
index a8be9fda5..04e2fd7cf 100644
--- a/iocore/net/P_SSLSNI.h
+++ b/iocore/net/P_SSLSNI.h
@@ -31,6 +31,7 @@
 #pragma once
 
 #include <vector>
+#include <string_view>
 #include <strings.h>
 #include <memory>
 
@@ -125,7 +126,7 @@ struct SNIConfigParams : public ConfigInfo {
   void cleanup();
   int Initialize();
   void loadSNIConfig();
-  std::pair<const actionVector *, ActionItem::Context> get(const std::string 
&servername) const;
+  std::pair<const actionVector *, ActionItem::Context> get(std::string_view 
servername) const;
 };
 
 struct SNIConfig {
diff --git a/iocore/net/SSLSNIConfig.cc b/iocore/net/SSLSNIConfig.cc
index f3481da5b..816f297c5 100644
--- a/iocore/net/SSLSNIConfig.cc
+++ b/iocore/net/SSLSNIConfig.cc
@@ -109,22 +109,21 @@ int SNIConfig::configid = 0;
 SNIConfigParams::SNIConfigParams() {}
 
 std::pair<const actionVector *, ActionItem::Context>
-SNIConfigParams::get(const std::string &servername) const
+SNIConfigParams::get(std::string_view servername) const
 {
   int ovector[OVECSIZE];
-  ActionItem::Context context;
 
   for (const auto &retval : sni_action_list) {
     int length = servername.length();
     if (retval.match == nullptr && length == 0) {
-      return {&retval.actions, context};
-    } else if (auto offset = pcre_exec(retval.match.get(), nullptr, 
servername.c_str(), length, 0, 0, ovector, OVECSIZE);
+      return {&retval.actions, {}};
+    } else if (auto offset = pcre_exec(retval.match.get(), nullptr, 
servername.data(), length, 0, 0, ovector, OVECSIZE);
                offset >= 0) {
       if (offset == 1) {
         // first pair identify the portion of the subject string matched by 
the entire pattern
         if (ovector[0] == 0 && ovector[1] == length) {
           // full match
-          return {&retval.actions, context};
+          return {&retval.actions, {}};
         } else {
           continue;
         }
@@ -135,21 +134,18 @@ SNIConfigParams::get(const std::string &servername) const
         offset = OVECSIZE / 3;
       }
 
-      const char *psubStrMatchStr = nullptr;
-      std::vector<std::string> groups;
+      ActionItem::Context::CapturedGroupViewVec groups;
+      groups.reserve(offset);
       for (int strnum = 1; strnum < offset; strnum++) {
-        pcre_get_substring(servername.c_str(), ovector, offset, strnum, 
&(psubStrMatchStr));
-        groups.emplace_back(psubStrMatchStr);
-      }
-      context._fqdn_wildcard_captured_groups = std::move(groups);
-      if (psubStrMatchStr) {
-        pcre_free_substring(psubStrMatchStr);
-      }
+        const std::size_t start  = ovector[2 * strnum];
+        const std::size_t length = ovector[2 * strnum + 1] - start;
 
-      return {&retval.actions, context};
+        groups.emplace_back(servername.data() + start, length);
+      }
+      return {&retval.actions, {std::move(groups)}};
     }
   }
-  return {nullptr, context};
+  return {nullptr, {}};
 }
 
 int
diff --git a/iocore/net/TLSSNISupport.cc b/iocore/net/TLSSNISupport.cc
index 52cd47205..20672f7ec 100644
--- a/iocore/net/TLSSNISupport.cc
+++ b/iocore/net/TLSSNISupport.cc
@@ -58,8 +58,13 @@ int
 TLSSNISupport::perform_sni_action()
 {
   const char *servername = this->_get_sni_server_name();
+  if (!servername) {
+    Debug("ssl_sni", "No servername provided");
+    return SSL_TLSEXT_ERR_OK;
+  }
+
   SNIConfig::scoped_config params;
-  if (const auto &actions = params->get(servername); !actions.first) {
+  if (const auto &actions = params->get({servername, 
std::strlen(servername)}); !actions.first) {
     Debug("ssl_sni", "%s not available in the map", servername);
   } else {
     for (auto &&item : *actions.first) {

Reply via email to