You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@trafficserver.apache.org by cm...@apache.org on 2024/07/21 22:36:22 UTC

(trafficserver) branch 10.0.x updated (f029bf1bb7 -> aa4ec84190)

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

cmcfarlen pushed a change to branch 10.0.x
in repository https://gitbox.apache.org/repos/asf/trafficserver.git


    from f029bf1bb7 Send EOS event when QUIC connection becomes draining state (#11317)
     new 62355fb177 Add HTTP/2 Empty CONTINUATION & DATA frame counter (#11345)
     new 58bc651e8f Update quiche to 0.22.0. (#11493)
     new cb65f9d026 Try TCP_FASTOPEN socket option with mptcp (#11517)
     new 8ffa5f61a9 Deprecate the support for URL param segment (#11519)
     new d2582a6764 H3 Tools: Disable libunwind build tests for boringssl. (#11540)
     new 670bd9ead4 Fixes the assertion in TSRemapDLHandleGet (#11544)
     new c7b7183ef7 Check incoming protocol list length first (#11545)
     new f63c1a23cc setup_server_read_response_header: remove assertion (#11548)
     new 0e540a7b73 Fix for OpenSSL 3.2+. (#11501)
     new 0a407a1c9c Fix server names for post-early-return (#11563)
     new e254d16666 Removes the Matrix parameters from Cripts (#11569)
     new 30dc1ee8a7 Removes matrix parameters from HRW (#11570)
     new 7c15990e68 Removes matrix parameters from regex_remap plugin (#11571)
     new 3e84c36718 Dispatch WRITE_COMPLETE when TLS handshake completes (#11574)
     new c9771d7840 Comment out an unused parameter in URLImpl::set_params (#11578)
     new aa4ec84190 Set `TS_HAVE_TLS_EARLY_DATA` correctly (#11577)

The 16 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails.  The revisions
listed as "add" were already present in the repository and have only
been added to this reference.


Summary of changes:
 CMakeLists.txt                                  |  19 ++--
 doc/admin-guide/files/records.yaml.en.rst       |  23 +++-
 doc/admin-guide/files/sni.yaml.en.rst           |   4 +
 doc/admin-guide/plugins/regex_remap.en.rst      |   6 --
 doc/developer-guide/cripts/cripts-urls.en.rst   |   1 -
 include/cripts/Urls.hpp                         |  31 +-----
 include/iocore/net/TLSSNISupport.h              |  10 +-
 include/iocore/net/quic/QUICStream.h            |   2 +
 include/proxy/http2/HTTP2.h                     |  16 +--
 include/proxy/http2/Http2ConnectionState.h      |  14 ++-
 include/ts/ts.h                                 |   6 ++
 include/tscore/ink_config.h.cmake.in            |   3 +
 plugins/header_rewrite/conditions.cc            |   5 -
 plugins/header_rewrite/statement.cc             |   2 -
 plugins/header_rewrite/statement.h              |   1 -
 plugins/regex_remap/regex_remap.cc              |  62 ++++-------
 src/api/InkAPI.cc                               |   2 +-
 src/cripts/Urls.cc                              |  27 -----
 src/iocore/net/ALPNSupport.cc                   |   2 +-
 src/iocore/net/BIO_fastopen.cc                  | 133 +++++++++++++++++++++---
 src/iocore/net/BIO_fastopen.h                   |   7 +-
 src/iocore/net/Connection.cc                    |  11 +-
 src/iocore/net/SSLNetVConnection.cc             |   5 +-
 src/iocore/net/UnixNetVConnection.cc            |   6 ++
 src/iocore/net/quic/QUICStream.cc               |  18 ++--
 src/proxy/hdrs/URL.cc                           |  78 +++++---------
 src/proxy/hdrs/unit_tests/test_URL.cc           |  82 +++++++++++++++
 src/proxy/http/HttpSM.cc                        |   4 +-
 src/proxy/http2/HTTP2.cc                        |  32 +++---
 src/proxy/http2/Http2ConnectionState.cc         |  66 +++++++++---
 src/records/RecordsConfig.cc                    |  14 +--
 src/traffic_cache_tool/CacheScan.cc             |   8 +-
 tests/gold_tests/post/post-early-return.test.py |  10 +-
 tools/build_boringssl_h3_tools.sh               |  13 ++-
 tools/build_openssl_h3_tools.sh                 |   4 +-
 35 files changed, 443 insertions(+), 284 deletions(-)


(trafficserver) 15/16: Comment out an unused parameter in URLImpl::set_params (#11578)

Posted by cm...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

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

commit c9771d7840f7026f6d023bb7a7a89b4cbb95e65b
Author: Masakazu Kitajo <ma...@apache.org>
AuthorDate: Thu Jul 18 15:22:02 2024 -0600

    Comment out an unused parameter in URLImpl::set_params (#11578)
    
    (cherry picked from commit f42d68f46e7988f90b086154ba780e07580ef8e9)
---
 src/proxy/hdrs/URL.cc | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/src/proxy/hdrs/URL.cc b/src/proxy/hdrs/URL.cc
index e56ab796c2..29af18d602 100644
--- a/src/proxy/hdrs/URL.cc
+++ b/src/proxy/hdrs/URL.cc
@@ -549,7 +549,7 @@ URLImpl::set_path(HdrHeap *heap, const char *value, int length, bool copy_string
 // url_{params|query|fragment}_set()
 
 void
-URLImpl::set_params(HdrHeap *heap, const char *value, int length, bool copy_string)
+URLImpl::set_params(HdrHeap *heap, const char *value, int length, bool /* copy_string ATS_UNUSED */)
 {
   int path_len = this->m_len_path;
 


(trafficserver) 06/16: Fixes the assertion in TSRemapDLHandleGet (#11544)

Posted by cm...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

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

commit 670bd9ead4db7a0a9fe130a040f0cbb1de58a1df
Author: Leif Hedstrom <zw...@apache.org>
AuthorDate: Sat Jul 13 09:59:22 2024 -0600

    Fixes the assertion in TSRemapDLHandleGet (#11544)
    
    (cherry picked from commit 008eb499951fe098d2e0a66941b6f6d406ef0c76)
---
 src/api/InkAPI.cc | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/src/api/InkAPI.cc b/src/api/InkAPI.cc
index 45202fd74e..8ccb7c4aef 100644
--- a/src/api/InkAPI.cc
+++ b/src/api/InkAPI.cc
@@ -8642,7 +8642,7 @@ TSRemapToUrlGet(TSHttpTxn txnp, TSMLoc *urlLocp)
 void *
 TSRemapDLHandleGet(TSRemapPluginInfo plugin_info)
 {
-  sdk_assert(sdk_sanity_check_null_ptr(plugin_info));
+  sdk_assert(sdk_sanity_check_null_ptr(plugin_info) == TS_SUCCESS);
   RemapPluginInfo *info = reinterpret_cast<RemapPluginInfo *>(plugin_info);
 
   return info->dlh();


(trafficserver) 09/16: Fix for OpenSSL 3.2+. (#11501)

Posted by cm...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

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

commit 0e540a7b73886c9d527fa77b0a81f9b60925bea6
Author: Walt Karas <wk...@yahooinc.com>
AuthorDate: Tue Jul 16 14:32:37 2024 -0400

    Fix for OpenSSL 3.2+. (#11501)
    
    It seems BIO user data is no longer set to nullptr.
    
    (cherry picked from commit 6bf342ba362a42786b9efcb0d4d554f725643a8d)
---
 CMakeLists.txt                       |   3 +
 include/tscore/ink_config.h.cmake.in |   3 +
 src/iocore/net/BIO_fastopen.cc       | 133 +++++++++++++++++++++++++++++++----
 src/iocore/net/BIO_fastopen.h        |   7 +-
 src/iocore/net/SSLNetVConnection.cc  |   5 +-
 5 files changed, 128 insertions(+), 23 deletions(-)

diff --git a/CMakeLists.txt b/CMakeLists.txt
index 5b0a9ba594..0069e1b68f 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -450,6 +450,9 @@ check_symbol_exists(BIO_meth_new "openssl/bio.h" HAVE_BIO_METH_NEW)
 check_symbol_exists(BIO_set_data "openssl/bio.h" HAVE_BIO_SET_DATA)
 check_symbol_exists(BIO_get_data "openssl/bio.h" HAVE_BIO_GET_DATA)
 check_symbol_exists(BIO_get_shutdown "openssl/bio.h" HAVE_BIO_GET_SHUTDOWN)
+check_symbol_exists(BIO_get_ex_new_index "openssl/bio.h" HAVE_BIO_GET_EX_NEW_INDEX)
+check_symbol_exists(BIO_get_ex_data "openssl/bio.h" HAVE_BIO_GET_EX_DATA)
+check_symbol_exists(BIO_set_ex_data "openssl/bio.h" HAVE_BIO_SET_EX_DATA)
 check_symbol_exists(BIO_meth_get_ctrl "openssl/bio.h" HAVE_BIO_METH_GET_CTRL)
 check_symbol_exists(BIO_meth_get_create "openssl/bio.h" HAVE_BIO_METH_GET_CREATE)
 check_symbol_exists(BIO_meth_get_destroy "openssl/bio.h" HAVE_BIO_METH_GET_DESTROY)
diff --git a/include/tscore/ink_config.h.cmake.in b/include/tscore/ink_config.h.cmake.in
index b8f036457f..50e14e4019 100644
--- a/include/tscore/ink_config.h.cmake.in
+++ b/include/tscore/ink_config.h.cmake.in
@@ -80,6 +80,9 @@
 #cmakedefine HAVE_BIO_SET_DATA 1
 #cmakedefine HAVE_BIO_GET_DATA 1
 #cmakedefine HAVE_BIO_GET_SHUTDOWN 1
+#cmakedefine HAVE_BIO_GET_EX_NEW_INDEX 1
+#cmakedefine HAVE_BIO_GET_EX_DATA 1
+#cmakedefine HAVE_BIO_SET_EX_DATA 1
 #cmakedefine HAVE_BIO_METH_GET_CTRL 1
 #cmakedefine HAVE_BIO_METH_GET_CREATE 1
 #cmakedefine HAVE_BIO_METH_GET_DESTROY 1
diff --git a/src/iocore/net/BIO_fastopen.cc b/src/iocore/net/BIO_fastopen.cc
index ac2a9e38b7..fd9ea9dd9c 100644
--- a/src/iocore/net/BIO_fastopen.cc
+++ b/src/iocore/net/BIO_fastopen.cc
@@ -21,12 +21,116 @@
  *  limitations under the License.
  */
 
+#include <openssl/opensslv.h>
+
 #include "P_Net.h"
 #include "iocore/eventsystem/SocketManager.h"
 #include "tscore/ink_assert.h"
+#include "tscore/ink_config.h"
 
 #include "BIO_fastopen.h"
 
+#if defined(BORINGLIKE)
+#error
+#elif defined(OPENSSL_IS_BORINGSSL) || defined(OPENSSL_IS_AWSLC)
+#define BORINGLIKE 1
+#else
+#define BORINGLIKE 0
+#endif
+
+namespace
+{
+
+#if defined(HAVE_BIO_GET_EX_NEW_INDEX) && defined(HAVE_BIO_GET_EX_DATA) && defined(HAVE_BIO_SET_EX_DATA)
+
+class ExData
+{
+public:
+  // Pseudo-namespace
+  ExData() = delete;
+
+  static int
+  idx()
+  {
+    static int idx_ = []() -> int {
+      int i = BIO_get_ex_new_index(0, nullptr, _new, _dup, _free);
+      ink_release_assert(i >= 0);
+      return i;
+    }();
+    return idx_;
+  }
+
+private:
+#if BORINGLIKE
+  static constexpr CRYPTO_EX_unused *_new{nullptr};
+#else
+  static void
+  _new(void * /* parent */, void * /* ptr */, CRYPTO_EX_DATA *ad, int idx_, long /* argl */, void * /* argp */)
+  {
+    ink_release_assert(CRYPTO_set_ex_data(ad, idx_, nullptr) == 1);
+  }
+#endif
+
+#if BORINGLIKE
+  static void
+  _free(void * /* parent */, void * /* ptr */, CRYPTO_EX_DATA * /* ad */, int /* idx_ */, long /* argl */, void * /* argp */)
+  {
+  }
+#else
+  static void
+  _free(void * /* parent */, void * /* ptr */, CRYPTO_EX_DATA *ad, int idx_, long /* argl */, void * /* argp */)
+  {
+    ink_release_assert(CRYPTO_set_ex_data(ad, idx_, nullptr) == 1);
+  }
+#endif
+
+#if BORINGLIKE || (OPENSSL_VERSION_MAJOR >= 3)
+  using _Type_from_d = void **;
+#else
+  using _Type_from_d = void *;
+#endif
+
+  static int
+  _dup(CRYPTO_EX_DATA * /* to */, const CRYPTO_EX_DATA * /* from */, _Type_from_d /* from_d */, int /* idx */, long /* argl */,
+       void * /* argp */)
+  {
+    ink_assert(false);
+    return 0;
+  }
+};
+
+inline void
+set_dest_addr_for_bio(BIO *b, void *dest_addr)
+{
+  ink_assert(BIO_set_ex_data(b, ExData::idx(), dest_addr) == 1);
+}
+
+inline void *
+get_dest_addr_for_bio(BIO *b)
+{
+  return BIO_get_ex_data(b, ExData::idx());
+}
+
+#else // no BIO ex data in SSL library
+
+// Fall back on the krufty way this was done using older SSL libraries.
+
+inline void
+set_dest_addr_for_bio(BIO *b, void *dest_addr)
+{
+  BIO_set_data(b, dest_addr);
+}
+
+inline void *
+get_dest_addr_for_bio(BIO *b)
+{
+  return BIO_get_data(b);
+}
+
+#endif
+
+} // end anonymous namespace
+
 // For BoringSSL, which for some reason doesn't have this function.
 // (In BoringSSL, sock_read() and sock_write() use the internal
 // bio_fd_non_fatal_error() instead.) #1437
@@ -113,20 +217,20 @@ fastopen_bwrite(BIO *bio, const char *in, int insz)
   int fd = BIO_get_fd(bio, nullptr);
   ink_assert(fd != NO_FD);
 
-  if (BIO_get_data(bio)) {
+  void *dst_void = get_dest_addr_for_bio(bio);
+  if (dst_void) {
+    auto dst = static_cast<sockaddr *>(dst_void);
     // On the first write only, make a TFO request if TFO is enabled.
     // The best documentation on the behavior of the Linux API is in
     // RFC 7413. If we get EINPROGRESS it means that the SYN has been
     // sent without data and we should retry.
-    const sockaddr *dst = reinterpret_cast<const sockaddr *>(BIO_get_data(bio));
-
     Metrics::Counter::increment(net_rsb.fastopen_attempts);
     err = SocketManager::sendto(fd, (void *)in, insz, MSG_FASTOPEN, dst, ats_ip_size(dst));
     if (err >= 0) {
       Metrics::Counter::increment(net_rsb.fastopen_successes);
     }
 
-    BIO_set_data(bio, nullptr);
+    set_dest_addr_for_bio(bio, nullptr);
   } else {
     err = SocketManager::write(fd, (void *)in, insz);
   }
@@ -164,21 +268,14 @@ fastopen_bread(BIO *bio, char *out, int outsz)
   return err < 0 ? -1 : err;
 }
 
+#ifndef HAVE_BIO_METH_NEW
+
 static long
 fastopen_ctrl(BIO *bio, int cmd, long larg, void *ptr)
 {
-  switch (cmd) {
-  case BIO_C_SET_CONNECT:
-    // We only support BIO_set_conn_address(), which sets a sockaddr.
-    ink_assert(larg == 2);
-    BIO_set_data(bio, ptr);
-    return 0;
-  }
-
   return BIO_meth_get_ctrl(const_cast<BIO_METHOD *>(BIO_s_socket()))(bio, cmd, larg, ptr);
 }
 
-#ifndef HAVE_BIO_METH_NEW
 static const BIO_METHOD fastopen_methods[] = {
   {
    .type          = BIO_TYPE_SOCKET,
@@ -193,12 +290,12 @@ static const BIO_METHOD fastopen_methods[] = {
    .callback_ctrl = nullptr,
    }
 };
-#else
+#else // defined(HAVE_BIO_METH_NEW)
 static const BIO_METHOD *fastopen_methods = [] {
   BIO_METHOD *methods = BIO_meth_new(BIO_TYPE_SOCKET, "fastopen");
   BIO_meth_set_write(methods, fastopen_bwrite);
   BIO_meth_set_read(methods, fastopen_bread);
-  BIO_meth_set_ctrl(methods, fastopen_ctrl);
+  BIO_meth_set_ctrl(methods, BIO_meth_get_ctrl(const_cast<BIO_METHOD *>(BIO_s_socket())));
   BIO_meth_set_create(methods, fastopen_create);
   BIO_meth_set_destroy(methods, fastopen_destroy);
   return methods;
@@ -210,3 +307,9 @@ BIO_s_fastopen()
 {
   return fastopen_methods;
 }
+
+void
+BIO_fastopen_set_dest_addr(BIO *bio, const sockaddr *dest_addr)
+{
+  set_dest_addr_for_bio(bio, const_cast<sockaddr *>(dest_addr));
+}
diff --git a/src/iocore/net/BIO_fastopen.h b/src/iocore/net/BIO_fastopen.h
index ce42e3be42..b949953daa 100644
--- a/src/iocore/net/BIO_fastopen.h
+++ b/src/iocore/net/BIO_fastopen.h
@@ -29,8 +29,5 @@
 // Return a BIO_METHOD for a socket BIO that implements TCP Fast Open.
 const BIO_METHOD *BIO_s_fastopen();
 
-// OpenSSL 1.0.2h has BIO_set_conn_ip(), but master has BIO_set_conn_address(). Use
-// the API from master since it makes more sense.
-#if !defined(BIO_set_conn_address)
-#define BIO_set_conn_address(b, addr) BIO_ctrl(b, BIO_C_SET_CONNECT, 2, (char *)addr)
-#endif
+// Set destination address for a BIO for a fastopen TCP socket where the local host is the client.
+void BIO_fastopen_set_dest_addr(BIO *bio, const sockaddr *dest_addr);
diff --git a/src/iocore/net/SSLNetVConnection.cc b/src/iocore/net/SSLNetVConnection.cc
index ca89894be0..5ebb705f0e 100644
--- a/src/iocore/net/SSLNetVConnection.cc
+++ b/src/iocore/net/SSLNetVConnection.cc
@@ -212,9 +212,8 @@ SSLNetVConnection::_make_ssl_connection(SSL_CTX *ctx)
       BIO *bio = BIO_new(const_cast<BIO_METHOD *>(BIO_s_fastopen()));
       BIO_set_fd(bio, this->get_socket(), BIO_NOCLOSE);
 
-      if (this->options.f_tcp_fastopen) {
-        BIO_set_conn_address(bio, this->get_remote_addr());
-      }
+      BIO_fastopen_set_dest_addr(bio,
+                                 this->options.f_tcp_fastopen ? this->get_remote_addr() : static_cast<const sockaddr *>(nullptr));
 
       SSL_set_bio(ssl, bio, bio);
     } else {


(trafficserver) 10/16: Fix server names for post-early-return (#11563)

Posted by cm...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

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

commit 0a407a1c9c831d9d583fb46c82c871bb85ae26af
Author: Brian Neradt <br...@gmail.com>
AuthorDate: Thu Jul 18 12:38:47 2024 -0500

    Fix server names for post-early-return (#11563)
    
    The post-early-return.test.py server* names are all copy and pasted as
    "server1" which means they are not configured correctly. This patch
    updates those names so they are distinct.
    
    (cherry picked from commit 5f29d55f3cff865f2178d597199d72eb747ac80b)
---
 tests/gold_tests/post/post-early-return.test.py | 10 +++++-----
 1 file changed, 5 insertions(+), 5 deletions(-)

diff --git a/tests/gold_tests/post/post-early-return.test.py b/tests/gold_tests/post/post-early-return.test.py
index e81100c112..ac699f47b2 100644
--- a/tests/gold_tests/post/post-early-return.test.py
+++ b/tests/gold_tests/post/post-early-return.test.py
@@ -63,15 +63,15 @@ ts.Disk.records_config.update(
 server1 = Test.Processes.Process(
     "server1", "bash -c '" + Test.TestDirectory + "/server1.sh {} outserver1'".format(Test.Variables.upstream_port1))
 server2 = Test.Processes.Process(
-    "server1", "bash -c '" + Test.TestDirectory + "/server1.sh {} outserver1'".format(Test.Variables.upstream_port2))
+    "server2", "bash -c '" + Test.TestDirectory + "/server1.sh {} outserver1'".format(Test.Variables.upstream_port2))
 server3 = Test.Processes.Process(
-    "server1", "bash -c '" + Test.TestDirectory + "/server1.sh {} outserver1'".format(Test.Variables.upstream_port3))
+    "server3", "bash -c '" + Test.TestDirectory + "/server1.sh {} outserver1'".format(Test.Variables.upstream_port3))
 server4 = Test.Processes.Process(
-    "server1", "bash -c '" + Test.TestDirectory + "/server1.sh {} outserver1'".format(Test.Variables.upstream_port4))
+    "server4", "bash -c '" + Test.TestDirectory + "/server1.sh {} outserver1'".format(Test.Variables.upstream_port4))
 server5 = Test.Processes.Process(
-    "server1", "bash -c '" + Test.TestDirectory + "/server1.sh {} outserver1'".format(Test.Variables.upstream_port5))
+    "server5", "bash -c '" + Test.TestDirectory + "/server1.sh {} outserver1'".format(Test.Variables.upstream_port5))
 server6 = Test.Processes.Process(
-    "server1", "bash -c '" + Test.TestDirectory + "/server1.sh {} outserver1'".format(Test.Variables.upstream_port6))
+    "server6", "bash -c '" + Test.TestDirectory + "/server1.sh {} outserver1'".format(Test.Variables.upstream_port6))
 
 big_post_body = "0123456789" * 231070
 big_post_body_file = open(os.path.join(Test.RunDirectory, "big_post_body"), "w")


(trafficserver) 03/16: Try TCP_FASTOPEN socket option with mptcp (#11517)

Posted by cm...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

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

commit cb65f9d02602766a5da1c0d87aa130a5b913a236
Author: Serris Lew <se...@gmail.com>
AuthorDate: Mon Jul 15 13:24:44 2024 -0700

    Try TCP_FASTOPEN socket option with mptcp (#11517)
    
    * Try TCP_FASTOPEN socket option with mptcp
    
    * Add comment for EOPNOTSUPP
    
    ---------
    
    Co-authored-by: Serris Lew <ls...@apple.com>
    (cherry picked from commit 90ab13277f4afb198494ce48799c5bb1be910beb)
---
 doc/admin-guide/files/records.yaml.en.rst |  4 ++--
 src/iocore/net/Connection.cc              | 11 +++++++----
 2 files changed, 9 insertions(+), 6 deletions(-)

diff --git a/doc/admin-guide/files/records.yaml.en.rst b/doc/admin-guide/files/records.yaml.en.rst
index 19d6dbd144..944a255b43 100644
--- a/doc/admin-guide/files/records.yaml.en.rst
+++ b/doc/admin-guide/files/records.yaml.en.rst
@@ -5088,8 +5088,8 @@ Sockets
         TCP_NOTSENT_LOWAT (64)
         INCOMING_CPU (128)
 
-   Note: If MPTCP is enabled, TCP_NODELAY is only supported on Linux kernels 5.17+. TCP_FASTOPEN
-   and TCP_NOTSENT_LOWAT socket options are currently not supported.
+   Note: If MPTCP is enabled, TCP_NODELAY is only supported on Linux kernels 5.17+ and TCP_FASTOPEN is
+   only supported on Linux kernels 6.2+. TCP_NOTSENT_LOWAT socket option is currently not supported.
 
 .. note::
 
diff --git a/src/iocore/net/Connection.cc b/src/iocore/net/Connection.cc
index d13e1a7254..80276efdd9 100644
--- a/src/iocore/net/Connection.cc
+++ b/src/iocore/net/Connection.cc
@@ -272,10 +272,13 @@ Server::setup_fd_for_listen(bool non_blocking, const NetProcessor::AcceptOptions
 
 #ifdef TCP_FASTOPEN
   if (opt.sockopt_flags & NetVCOptions::SOCK_OPT_TCP_FAST_OPEN) {
-    if (opt.f_mptcp) {
-      Warning("[Server::listen] TCP_FASTOPEN socket option not valid on MPTCP socket level");
-    } else if (safe_setsockopt(fd, IPPROTO_TCP, TCP_FASTOPEN, (char *)&opt.tfo_queue_length, sizeof(int))) {
-      goto Lerror;
+    if (safe_setsockopt(fd, IPPROTO_TCP, TCP_FASTOPEN, (char *)&opt.tfo_queue_length, sizeof(int))) {
+      // EOPNOTSUPP also checked for general safeguarding of unsupported operations of socket functions
+      if (opt.f_mptcp && (errno == ENOPROTOOPT || errno == EOPNOTSUPP)) {
+        Warning("[Server::listen] TCP_FASTOPEN socket option not valid on MPTCP socket level");
+      } else {
+        goto Lerror;
+      }
     }
   }
 #endif


(trafficserver) 13/16: Removes matrix parameters from regex_remap plugin (#11571)

Posted by cm...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

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

commit 7c15990e6844478e071248addc98f68c21cff796
Author: Leif Hedstrom <zw...@apache.org>
AuthorDate: Thu Jul 18 21:40:49 2024 -0600

    Removes matrix parameters from regex_remap plugin (#11571)
    
    (cherry picked from commit 3289fb0b73af1b84aaf434b67123bd1fe7fb0d10)
---
 doc/admin-guide/plugins/regex_remap.en.rst |  6 ---
 plugins/regex_remap/regex_remap.cc         | 62 +++++++++---------------------
 2 files changed, 19 insertions(+), 49 deletions(-)

diff --git a/doc/admin-guide/plugins/regex_remap.en.rst b/doc/admin-guide/plugins/regex_remap.en.rst
index d5744ebe33..547309faca 100644
--- a/doc/admin-guide/plugins/regex_remap.en.rst
+++ b/doc/admin-guide/plugins/regex_remap.en.rst
@@ -70,7 +70,6 @@ be used to modify the plugin instance behavior ::
 
     @pparam=[no-]method              [default: off]
     @pparam=[no-]query-string        [default: on]
-    @pparam=[no-]matrix-parameters   [default: off]
     @pparam=[no-]host                [default: off]
 
 If you wish to match on the HTTP method used (e.g. "``GET``\ "),
@@ -92,11 +91,6 @@ again, to turn this off use the option 'no-query-string', e.g. ::
 
     ... @pparam=maps.reg @pparam=no-query-string
 
-You can also include the matrix parameters in the string, using
-the option 'matrix-parameters', e.g. ::
-
-    ... @pparam=maps.reg @pparam=matrix-parameters
-
 Finally, to match on the host as well, use the option 'host', e.g. ::
 
     ... @pparam=maps.reg @pparam=host
diff --git a/plugins/regex_remap/regex_remap.cc b/plugins/regex_remap/regex_remap.cc
index 350557bc2d..ca838c23ef 100644
--- a/plugins/regex_remap/regex_remap.cc
+++ b/plugins/regex_remap/regex_remap.cc
@@ -59,14 +59,14 @@ static const int MAX_SUBS  = 32; // No more than 32 substitution variables in th
 
 // Substitutions other than regex matches
 enum ExtraSubstitutions {
-  SUB_HOST       = 11,
-  SUB_FROM_HOST  = 12,
-  SUB_TO_HOST    = 13,
-  SUB_PORT       = 14,
-  SUB_SCHEME     = 15,
-  SUB_PATH       = 16,
-  SUB_QUERY      = 17,
-  SUB_MATRIX     = 18,
+  SUB_HOST      = 11,
+  SUB_FROM_HOST = 12,
+  SUB_TO_HOST   = 13,
+  SUB_PORT      = 14,
+  SUB_SCHEME    = 15,
+  SUB_PATH      = 16,
+  SUB_QUERY     = 17,
+  // 18 is unused, used to be matrix parameters
   SUB_CLIENT_IP  = 19,
   SUB_LOWER_PATH = 20,
 };
@@ -87,24 +87,21 @@ struct UrlComponents {
     host   = TSUrlHostGet(bufp, url, &host_len);
     path   = TSUrlPathGet(bufp, url, &path_len);
     query  = TSUrlHttpQueryGet(bufp, url, &query_len);
-    matrix = TSUrlHttpParamsGet(bufp, url, &matrix_len);
     port   = TSUrlPortGet(bufp, url);
 
-    url_len = scheme_len + host_len + path_len + query_len + matrix_len + 32;
+    url_len = scheme_len + host_len + path_len + query_len + 32;
   }
 
   const char *scheme = nullptr;
   const char *host   = nullptr;
   const char *path   = nullptr;
   const char *query  = nullptr;
-  const char *matrix = nullptr;
   int         port   = 0;
 
   int scheme_len = 0;
   int host_len   = 0;
   int path_len   = 0;
   int query_len  = 0;
-  int matrix_len = 0;
 
   int url_len = 0; // Full length, of all components
 };
@@ -442,9 +439,6 @@ RemapRegex::compile(const char *&error, int &erroffset)
         case 'q':
           ix = SUB_QUERY;
           break;
-        case 'm':
-          ix = SUB_MATRIX;
-          break;
         case 'i':
           ix = SUB_CLIENT_IP;
           break;
@@ -515,9 +509,6 @@ RemapRegex::get_lengths(const int ovector[], int lengths[], TSRemapRequestInfo *
       case SUB_QUERY:
         len += req_url->query_len;
         break;
-      case SUB_MATRIX:
-        len += req_url->matrix_len;
-        break;
       case SUB_CLIENT_IP:
         len += INET6_ADDRSTRLEN;
         break;
@@ -583,10 +574,6 @@ RemapRegex::substitute(char dest[], const char *src, const int ovector[], const
           str = req_url->query;
           len = req_url->query_len;
           break;
-        case SUB_MATRIX:
-          str = req_url->matrix;
-          len = req_url->matrix_len;
-          break;
         case SUB_CLIENT_IP:
           str = ats_ip_ntop(TSHttpTxnClientAddrGet(txnp), buff, INET6_ADDRSTRLEN);
           len = strlen(str);
@@ -627,17 +614,16 @@ RemapRegex::substitute(char dest[], const char *src, const int ovector[], const
 struct RemapInstance {
   RemapInstance() : filename("unknown") {}
 
-  RemapRegex *first         = nullptr;
-  RemapRegex *last          = nullptr;
-  bool        pristine_url  = false;
-  bool        profile       = false;
-  bool        method        = false;
-  bool        query_string  = true;
-  bool        matrix_params = false;
-  bool        host          = false;
-  int         hits          = 0;
-  int         misses        = 0;
-  int         failures      = 0;
+  RemapRegex *first        = nullptr;
+  RemapRegex *last         = nullptr;
+  bool        pristine_url = false;
+  bool        profile      = false;
+  bool        method       = false;
+  bool        query_string = true;
+  bool        host         = false;
+  int         hits         = 0;
+  int         misses       = 0;
+  int         failures     = 0;
   std::string filename;
 };
 
@@ -689,10 +675,6 @@ TSRemapNewInstance(int argc, char *argv[], void **ih, char * /* errbuf ATS_UNUSE
       ri->query_string = true;
     } else if (strncmp(argv[i], "no-query-string", 15) == 0) {
       ri->query_string = false;
-    } else if (strncmp(argv[i], "matrix-parameters", 17) == 0) {
-      ri->matrix_params = true;
-    } else if (strncmp(argv[i], "no-matrix-parameters", 20) == 0) {
-      ri->matrix_params = false;
     } else if (strncmp(argv[i], "host", 4) == 0) {
       ri->host = true;
     } else if (strncmp(argv[i], "no-host", 7) == 0) {
@@ -957,12 +939,6 @@ TSRemapDoRemap(void *ih, TSHttpTxn txnp, TSRemapRequestInfo *rri)
     match_len += (req_url.path_len);
   }
 
-  if (ri->matrix_params && req_url.matrix && req_url.matrix_len > 0) {
-    *(match_buf + match_len) = ';';
-    memcpy(match_buf + match_len + 1, req_url.matrix, req_url.matrix_len);
-    match_len += (req_url.matrix_len + 1);
-  }
-
   if (ri->query_string && req_url.query && req_url.query_len > 0) {
     *(match_buf + match_len) = '?';
     memcpy(match_buf + match_len + 1, req_url.query, req_url.query_len);


(trafficserver) 05/16: H3 Tools: Disable libunwind build tests for boringssl. (#11540)

Posted by cm...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

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

commit d2582a676453a7c5be9186246cd200ac883b8538
Author: Damian Meden <dm...@apache.org>
AuthorDate: Sat Jul 13 02:23:26 2024 +0200

    H3 Tools: Disable libunwind build tests for boringssl. (#11540)
    
    (cherry picked from commit 998f07979be49584874d67a5c7909c71e691c9e9)
---
 tools/build_boringssl_h3_tools.sh | 9 ++++++---
 1 file changed, 6 insertions(+), 3 deletions(-)

diff --git a/tools/build_boringssl_h3_tools.sh b/tools/build_boringssl_h3_tools.sh
index f5261f9e80..8c5979619f 100755
--- a/tools/build_boringssl_h3_tools.sh
+++ b/tools/build_boringssl_h3_tools.sh
@@ -137,13 +137,16 @@ fi
 set -e
 
 # Note: -Wdangling-pointer=0
-# We may have some issues with latest GCC compilers, so disabling -Wdangling-pointer=
+#   We may have some issues with latest GCC compilers, so disabling -Wdangling-pointer=
+# Note: -UBORINGSSL_HAVE_LIBUNWIND
+#   Disable related libunwind test builds, there are some version number issues
+#   with this pkg in Ubuntu 20.04, so disable this to make sure it builds.
 cmake \
   -B build-shared \
   -DGO_EXECUTABLE=${GO_BINARY_PATH} \
   -DCMAKE_INSTALL_PREFIX=${BASE}/boringssl \
   -DCMAKE_BUILD_TYPE=Release \
-  -DCMAKE_CXX_FLAGS='-Wno-error=ignored-attributes' \
+  -DCMAKE_CXX_FLAGS='-Wno-error=ignored-attributes -UBORINGSSL_HAVE_LIBUNWIND' \
   -DCMAKE_C_FLAGS=${BSSL_C_FLAGS} \
   -DBUILD_SHARED_LIBS=1
 cmake \
@@ -151,7 +154,7 @@ cmake \
   -DGO_EXECUTABLE=${GO_BINARY_PATH} \
   -DCMAKE_INSTALL_PREFIX=${BASE}/boringssl \
   -DCMAKE_BUILD_TYPE=Release \
-  -DCMAKE_CXX_FLAGS='-Wno-error=ignored-attributes' \
+  -DCMAKE_CXX_FLAGS='-Wno-error=ignored-attributes -UBORINGSSL_HAVE_LIBUNWIND' \
   -DCMAKE_C_FLAGS=${BSSL_C_FLAGS} \
   -DBUILD_SHARED_LIBS=0
 cmake --build build-shared -j ${num_threads}


(trafficserver) 14/16: Dispatch WRITE_COMPLETE when TLS handshake completes (#11574)

Posted by cm...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

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

commit 3e84c36718dbe2710a7fe1d9b6be3fcf5cbfa258
Author: Brian Neradt <br...@gmail.com>
AuthorDate: Fri Jul 19 09:51:18 2024 -0500

    Dispatch WRITE_COMPLETE when TLS handshake completes (#11574)
    
    The SSLNetVConnection.cc logic already does this, so this is a port over
    of that event dispatch functionality when ntodo is 0 for
    UnixNetVConnection.cc. @josiahwi and I investigated a periodic failure
    in proxy_protocol.test.py and we noticed that the issue was due to the
    handshake completing within a single call of sslStartHandshake. In those
    cases, the ConnectingEntry handler wasn't called back and the connection
    would hang without progressing with the rest of the request after the
    handshake completed. This ensures that the ConnectingEntry handler is
    called in these circumstances.
    
    (cherry picked from commit de2c354514d0cb7b58df28692316f227f0d718cc)
---
 src/iocore/net/UnixNetVConnection.cc | 6 ++++++
 1 file changed, 6 insertions(+)

diff --git a/src/iocore/net/UnixNetVConnection.cc b/src/iocore/net/UnixNetVConnection.cc
index 9d6d7c60f0..4790016546 100644
--- a/src/iocore/net/UnixNetVConnection.cc
+++ b/src/iocore/net/UnixNetVConnection.cc
@@ -418,6 +418,12 @@ write_to_net_io(NetHandler *nh, UnixNetVConnection *vc, EThread *thread)
       if (vc->write.enabled) {
         nh->write_ready_list.in_or_enqueue(vc);
       }
+      // If this was driven by a zero length read, signal complete when
+      // the handshake is complete. Otherwise set up for continuing read
+      // operations.
+      if (s->vio.ntodo() <= 0) {
+        vc->readSignalDone(VC_EVENT_WRITE_COMPLETE, nh);
+      }
     } else {
       write_reschedule(nh, vc);
     }


(trafficserver) 12/16: Removes matrix parameters from HRW (#11570)

Posted by cm...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

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

commit 30dc1ee8a77ec5dba8c70cefd3ed0be6fdf70ece
Author: Leif Hedstrom <zw...@apache.org>
AuthorDate: Thu Jul 18 21:41:07 2024 -0600

    Removes matrix parameters from HRW (#11570)
    
    (cherry picked from commit 3d8f8b4fc813188caadc8c07f1d3f2c37528a628)
---
 plugins/header_rewrite/conditions.cc | 5 -----
 plugins/header_rewrite/statement.cc  | 2 --
 plugins/header_rewrite/statement.h   | 1 -
 3 files changed, 8 deletions(-)

diff --git a/plugins/header_rewrite/conditions.cc b/plugins/header_rewrite/conditions.cc
index 9682d5c8a8..67ed1f7567 100644
--- a/plugins/header_rewrite/conditions.cc
+++ b/plugins/header_rewrite/conditions.cc
@@ -339,11 +339,6 @@ ConditionUrl::append_value(std::string &s, const Resources &res)
     s.append(q_str, i);
     Dbg(pi_dbg_ctl, "   Query parameters to match is: %.*s", i, q_str);
     break;
-  case URL_QUAL_MATRIX:
-    q_str = TSUrlHttpParamsGet(bufp, url, &i);
-    s.append(q_str, i);
-    Dbg(pi_dbg_ctl, "   Matrix parameters to match is: %.*s", i, q_str);
-    break;
   case URL_QUAL_SCHEME:
     q_str = TSUrlSchemeGet(bufp, url, &i);
     s.append(q_str, i);
diff --git a/plugins/header_rewrite/statement.cc b/plugins/header_rewrite/statement.cc
index 17a1f31736..69bacda1fe 100644
--- a/plugins/header_rewrite/statement.cc
+++ b/plugins/header_rewrite/statement.cc
@@ -104,8 +104,6 @@ Statement::parse_url_qualifier(const std::string &q) const
     qual = URL_QUAL_PATH;
   } else if (q == "QUERY") {
     qual = URL_QUAL_QUERY;
-  } else if (q == "MATRIX") {
-    qual = URL_QUAL_MATRIX;
   } else if (q == "SCHEME") {
     qual = URL_QUAL_SCHEME;
   } else if (q == "URL") {
diff --git a/plugins/header_rewrite/statement.h b/plugins/header_rewrite/statement.h
index dfb376908f..1b5798bff3 100644
--- a/plugins/header_rewrite/statement.h
+++ b/plugins/header_rewrite/statement.h
@@ -39,7 +39,6 @@ enum UrlQualifiers {
   URL_QUAL_PORT,
   URL_QUAL_PATH,
   URL_QUAL_QUERY,
-  URL_QUAL_MATRIX,
   URL_QUAL_SCHEME,
   URL_QUAL_URL,
 };


(trafficserver) 01/16: Add HTTP/2 Empty CONTINUATION & DATA frame counter (#11345)

Posted by cm...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

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

commit 62355fb177d18ea566c5a30df775b41d9e4c14b5
Author: Masakazu Kitajo <ma...@apache.org>
AuthorDate: Wed Jul 17 14:04:34 2024 -0600

    Add HTTP/2 Empty CONTINUATION & DATA frame counter (#11345)
    
    * HTTP/2 Empty CONTINUATION & DATA frame counter
    
    * Allow using 0 as a valid limit value and use negative numbers as unlimited
    
    * Don't return early if CONTINUATION frame is empty
    
    * Fix typos
    
    * Add documentation about proxy.config.http2.max_empty_frames_per_minute
    
    * Add documentation about http2_max_empty_frames_per_minute in sni.yaml
    
    * Fix errors from rebasing
    
    * Documentation
    
    * Improve wording
    
    ---------
    
    Co-authored-by: Masaori Koshiba <ma...@apache.org>
    (cherry picked from commit 21581ecbf1cc441cfb6fab4f935b326107963ced)
---
 doc/admin-guide/files/records.yaml.en.rst  | 19 +++++++++
 doc/admin-guide/files/sni.yaml.en.rst      |  4 ++
 include/iocore/net/TLSSNISupport.h         | 10 ++---
 include/proxy/http2/HTTP2.h                | 16 ++++----
 include/proxy/http2/Http2ConnectionState.h | 14 ++++---
 src/proxy/http2/HTTP2.cc                   | 32 ++++++++-------
 src/proxy/http2/Http2ConnectionState.cc    | 66 +++++++++++++++++++++++-------
 src/records/RecordsConfig.cc               | 14 ++++---
 8 files changed, 124 insertions(+), 51 deletions(-)

diff --git a/doc/admin-guide/files/records.yaml.en.rst b/doc/admin-guide/files/records.yaml.en.rst
index 198b014e4f..19d6dbd144 100644
--- a/doc/admin-guide/files/records.yaml.en.rst
+++ b/doc/admin-guide/files/records.yaml.en.rst
@@ -4546,6 +4546,7 @@ HTTP/2 Configuration
    Specifies how many settings in an HTTP/2 SETTINGS frame |TS| accepts.
    Clients exceeded this limit will be immediately disconnected with an error
    code of ENHANCE_YOUR_CALM.
+   Any negative value configures no limit to the number of settings received.
 
 .. ts:cv:: CONFIG proxy.config.http2.max_settings_per_minute INT 14
    :reloadable:
@@ -4553,6 +4554,7 @@ HTTP/2 Configuration
    Specifies how many settings in HTTP/2 SETTINGS frames |TS| accept for a minute.
    Clients exceeded this limit will be immediately disconnected with an error
    code of ENHANCE_YOUR_CALM.
+   Any negative value configures no limit to the number of settings received.
 
 .. ts:cv:: CONFIG proxy.config.http2.max_settings_frames_per_minute INT 14
    :reloadable:
@@ -4560,6 +4562,7 @@ HTTP/2 Configuration
    Specifies how many SETTINGS frames |TS| receives for a minute at maximum.
    Clients exceeded this limit will be immediately disconnected with an error
    code of ENHANCE_YOUR_CALM.
+   Any negative value configures no limit to the number of SETTINGS frames received.
 
 .. ts:cv:: CONFIG proxy.config.http2.max_ping_frames_per_minute INT 60
    :reloadable:
@@ -4567,6 +4570,7 @@ HTTP/2 Configuration
    Specifies how many number of PING frames |TS| receives for a minute at maximum.
    Clients exceeded this limit will be immediately disconnected with an error
    code of ENHANCE_YOUR_CALM.
+   Any negative value configures no limit to the number of PING frames received.
 
 .. ts:cv:: CONFIG proxy.config.http2.max_priority_frames_per_minute INT 120
    :reloadable:
@@ -4576,6 +4580,7 @@ HTTP/2 Configuration
    code of ENHANCE_YOUR_CALM. If this is set to 0, the limit logic is disabled.
    This limit only will be enforced if :ts:cv:`proxy.config.http2.stream_priority_enabled`
    is set to 1.
+   Any negative value configures no limit to the number of PRIORITY frames received.
 
 .. ts:cv:: CONFIG proxy.config.http2.max_rst_stream_frames_per_minute INT 200
    :reloadable:
@@ -4583,6 +4588,7 @@ HTTP/2 Configuration
    Specifies how many RST_STREAM frames |TS| receives per minute at maximum.
    Clients exceeding this limit will be immediately disconnected with an error
    code of ENHANCE_YOUR_CALM.
+   Any negative value configures no limit to the number of RST_STREAM frames received.
 
 .. ts:cv:: CONFIG proxy.config.http2.max_continuation_frames_per_minute INT 120
    :reloadable:
@@ -4590,6 +4596,19 @@ HTTP/2 Configuration
    Specifies how many CONTINUATION frames |TS| receives per minute at maximum.
    Clients exceeding this limit will be immediately disconnected with an error
    code of ENHANCE_YOUR_CALM.
+   Any negative value configures no limit to the number of CONTINUATION frames received.
+
+.. ts:cv:: CONFIG proxy.config.http2.max_empty_frames_per_minute INT 0
+   :reloadable:
+
+   Specifies the maximum number of empty frames |TS| will receive per minute before it will start closing connections.
+   In this context, an "empty frame" means either a DATA frame that does not carry a payload
+   nor an END_STREAM flag, or a CONTINUATION frame that does not carry payload
+   nor an END_HEADERS flag.
+   Clients exceeding this limit will be immediately disconnected with an error
+   code of ENHANCE_YOUR_CALM.
+   Any negative value configures no limit to the number of empty frames received.
+   ``0`` is the default configuration, meaning that no empty frames are allowed.
 
 .. ts:cv:: CONFIG proxy.config.http2.min_avg_window_update FLOAT 2560.0
    :reloadable:
diff --git a/doc/admin-guide/files/sni.yaml.en.rst b/doc/admin-guide/files/sni.yaml.en.rst
index 7be40de811..191fefb010 100644
--- a/doc/admin-guide/files/sni.yaml.en.rst
+++ b/doc/admin-guide/files/sni.yaml.en.rst
@@ -228,6 +228,10 @@ http2_max_continuation_frames_per_minute Inbound   Specifies how many CONTINUATI
                                                    By default this is :ts:cv:`proxy.config.http2.max_continuation_frames_per_minute`.
                                                    NOTE: Connection coalescing may prevent this from taking effect.
 
+http2_max_empty_frames_per_minute        Inbound   Specifies how many empty frames |TS| receives per minute at maximum.
+                                                   By default this is :ts:cv:`proxy.config.http2.max_empty_frames_per_minute`.
+                                                   NOTE: Connection coalescing may prevent this from taking effect.
+
 quic                                     Inbound   Indicates whether QUIC connections should be accepted. The valid values are :code:`on` or
                                                    :code:`off`. Note that this is a more specific setting to configure QUIC availability per server
                                                    name. More broadly, you will also need to configure :ts:cv:`proxy.config.http.server_ports` to
diff --git a/include/iocore/net/TLSSNISupport.h b/include/iocore/net/TLSSNISupport.h
index 060b60c826..1e6685276f 100644
--- a/include/iocore/net/TLSSNISupport.h
+++ b/include/iocore/net/TLSSNISupport.h
@@ -61,11 +61,11 @@ public:
     std::optional<uint32_t>         http2_buffer_water_mark;
     std::optional<uint32_t>         server_max_early_data;
     std::optional<uint32_t>         http2_initial_window_size_in;
-    std::optional<uint32_t>         http2_max_settings_frames_per_minute;
-    std::optional<uint32_t>         http2_max_ping_frames_per_minute;
-    std::optional<uint32_t>         http2_max_priority_frames_per_minute;
-    std::optional<uint32_t>         http2_max_rst_stream_frames_per_minute;
-    std::optional<uint32_t>         http2_max_continuation_frames_per_minute;
+    std::optional<int32_t>          http2_max_settings_frames_per_minute;
+    std::optional<int32_t>          http2_max_ping_frames_per_minute;
+    std::optional<int32_t>          http2_max_priority_frames_per_minute;
+    std::optional<int32_t>          http2_max_rst_stream_frames_per_minute;
+    std::optional<int32_t>          http2_max_continuation_frames_per_minute;
     std::optional<std::string_view> outbound_sni_policy;
   } hints_from_sni;
 
diff --git a/include/proxy/http2/HTTP2.h b/include/proxy/http2/HTTP2.h
index 11c60ec35f..9f3c62b97e 100644
--- a/include/proxy/http2/HTTP2.h
+++ b/include/proxy/http2/HTTP2.h
@@ -104,6 +104,7 @@ struct Http2StatsBlock {
   Metrics::Counter::AtomicType *max_priority_frames_per_minute_exceeded;
   Metrics::Counter::AtomicType *max_rst_stream_frames_per_minute_exceeded;
   Metrics::Counter::AtomicType *max_continuation_frames_per_minute_exceeded;
+  Metrics::Counter::AtomicType *max_empty_frames_per_minute_exceeded;
   Metrics::Counter::AtomicType *insufficient_avg_window_update;
   Metrics::Counter::AtomicType *max_concurrent_streams_exceeded_in;
   Metrics::Counter::AtomicType *max_concurrent_streams_exceeded_out;
@@ -423,13 +424,14 @@ public:
 
   static float    stream_error_rate_threshold;
   static uint32_t stream_error_sampling_threshold;
-  static uint32_t max_settings_per_frame;
-  static uint32_t max_settings_per_minute;
-  static uint32_t max_settings_frames_per_minute;
-  static uint32_t max_ping_frames_per_minute;
-  static uint32_t max_priority_frames_per_minute;
-  static uint32_t max_rst_stream_frames_per_minute;
-  static uint32_t max_continuation_frames_per_minute;
+  static int32_t  max_settings_per_frame;
+  static int32_t  max_settings_per_minute;
+  static int32_t  max_settings_frames_per_minute;
+  static int32_t  max_ping_frames_per_minute;
+  static int32_t  max_priority_frames_per_minute;
+  static int32_t  max_rst_stream_frames_per_minute;
+  static int32_t  max_continuation_frames_per_minute;
+  static int32_t  max_empty_frames_per_minute;
   static float    min_avg_window_update;
   static uint32_t con_slow_log_threshold;
   static uint32_t stream_slow_log_threshold;
diff --git a/include/proxy/http2/Http2ConnectionState.h b/include/proxy/http2/Http2ConnectionState.h
index 0681fddeed..289918754c 100644
--- a/include/proxy/http2/Http2ConnectionState.h
+++ b/include/proxy/http2/Http2ConnectionState.h
@@ -201,6 +201,8 @@ public:
   uint32_t get_received_rst_stream_frame_count();
   void     increment_received_continuation_frame_count();
   uint32_t get_received_continuation_frame_count();
+  void     increment_received_empty_frame_count();
+  uint32_t get_received_empty_frame_count();
 
   ssize_t        get_peer_rwnd() const;
   Http2ErrorCode increment_peer_rwnd(size_t amount);
@@ -336,6 +338,7 @@ private:
   FrequencyCounter _received_priority_frame_counter;
   FrequencyCounter _received_rst_stream_frame_counter;
   FrequencyCounter _received_continuation_frame_counter;
+  FrequencyCounter _received_empty_frame_counter;
 
   /** Records the various settings for each SETTINGS frame that we've sent.
    *
@@ -405,11 +408,12 @@ private:
   Event             *_data_event         = nullptr;
   Event             *retransmit_event    = nullptr;
 
-  uint32_t configured_max_settings_frames_per_minute     = 0;
-  uint32_t configured_max_ping_frames_per_minute         = 0;
-  uint32_t configured_max_priority_frames_per_minute     = 0;
-  uint32_t configured_max_rst_stream_frames_per_minute   = 0;
-  uint32_t configured_max_continuation_frames_per_minute = 0;
+  int32_t configured_max_settings_frames_per_minute     = 0;
+  int32_t configured_max_ping_frames_per_minute         = 0;
+  int32_t configured_max_priority_frames_per_minute     = 0;
+  int32_t configured_max_rst_stream_frames_per_minute   = 0;
+  int32_t configured_max_continuation_frames_per_minute = 0;
+  int32_t configured_max_empty_frames_per_minute        = 0;
 };
 
 ///////////////////////////////////////////////
diff --git a/src/proxy/http2/HTTP2.cc b/src/proxy/http2/HTTP2.cc
index a28284588d..8323b05352 100644
--- a/src/proxy/http2/HTTP2.cc
+++ b/src/proxy/http2/HTTP2.cc
@@ -486,13 +486,14 @@ uint32_t               Http2::no_activity_timeout_out    = 120;
 
 float    Http2::stream_error_rate_threshold        = 0.1;
 uint32_t Http2::stream_error_sampling_threshold    = 10;
-uint32_t Http2::max_settings_per_frame             = 7;
-uint32_t Http2::max_settings_per_minute            = 14;
-uint32_t Http2::max_settings_frames_per_minute     = 14;
-uint32_t Http2::max_ping_frames_per_minute         = 60;
-uint32_t Http2::max_priority_frames_per_minute     = 120;
-uint32_t Http2::max_rst_stream_frames_per_minute   = 200;
-uint32_t Http2::max_continuation_frames_per_minute = 120;
+int32_t  Http2::max_settings_per_frame             = 7;
+int32_t  Http2::max_settings_per_minute            = 14;
+int32_t  Http2::max_settings_frames_per_minute     = 14;
+int32_t  Http2::max_ping_frames_per_minute         = 60;
+int32_t  Http2::max_priority_frames_per_minute     = 120;
+int32_t  Http2::max_rst_stream_frames_per_minute   = 200;
+int32_t  Http2::max_continuation_frames_per_minute = 120;
+int32_t  Http2::max_empty_frames_per_minute        = 0;
 float    Http2::min_avg_window_update              = 2560.0;
 uint32_t Http2::con_slow_log_threshold             = 0;
 uint32_t Http2::stream_slow_log_threshold          = 0;
@@ -544,13 +545,14 @@ Http2::init()
   REC_EstablishStaticConfigInt32U(zombie_timeout_in, "proxy.config.http2.zombie_debug_timeout_in");
   REC_EstablishStaticConfigFloat(stream_error_rate_threshold, "proxy.config.http2.stream_error_rate_threshold");
   REC_EstablishStaticConfigInt32U(stream_error_sampling_threshold, "proxy.config.http2.stream_error_sampling_threshold");
-  REC_EstablishStaticConfigInt32U(max_settings_per_frame, "proxy.config.http2.max_settings_per_frame");
-  REC_EstablishStaticConfigInt32U(max_settings_per_minute, "proxy.config.http2.max_settings_per_minute");
-  REC_EstablishStaticConfigInt32U(max_settings_frames_per_minute, "proxy.config.http2.max_settings_frames_per_minute");
-  REC_EstablishStaticConfigInt32U(max_ping_frames_per_minute, "proxy.config.http2.max_ping_frames_per_minute");
-  REC_EstablishStaticConfigInt32U(max_priority_frames_per_minute, "proxy.config.http2.max_priority_frames_per_minute");
-  REC_EstablishStaticConfigInt32U(max_rst_stream_frames_per_minute, "proxy.config.http2.max_rst_stream_frames_per_minute");
-  REC_EstablishStaticConfigInt32U(max_continuation_frames_per_minute, "proxy.config.http2.max_continuation_frames_per_minute");
+  REC_EstablishStaticConfigInt32(max_settings_per_frame, "proxy.config.http2.max_settings_per_frame");
+  REC_EstablishStaticConfigInt32(max_settings_per_minute, "proxy.config.http2.max_settings_per_minute");
+  REC_EstablishStaticConfigInt32(max_settings_frames_per_minute, "proxy.config.http2.max_settings_frames_per_minute");
+  REC_EstablishStaticConfigInt32(max_ping_frames_per_minute, "proxy.config.http2.max_ping_frames_per_minute");
+  REC_EstablishStaticConfigInt32(max_priority_frames_per_minute, "proxy.config.http2.max_priority_frames_per_minute");
+  REC_EstablishStaticConfigInt32(max_rst_stream_frames_per_minute, "proxy.config.http2.max_rst_stream_frames_per_minute");
+  REC_EstablishStaticConfigInt32(max_continuation_frames_per_minute, "proxy.config.http2.max_continuation_frames_per_minute");
+  REC_EstablishStaticConfigInt32(max_empty_frames_per_minute, "proxy.config.http2.max_empty_frames_per_minute");
   REC_EstablishStaticConfigFloat(min_avg_window_update, "proxy.config.http2.min_avg_window_update");
   REC_EstablishStaticConfigInt32U(con_slow_log_threshold, "proxy.config.http2.connection.slow.log.threshold");
   REC_EstablishStaticConfigInt32U(stream_slow_log_threshold, "proxy.config.http2.stream.slow.log.threshold");
@@ -607,6 +609,8 @@ Http2::init()
     Metrics::Counter::createPtr("proxy.process.http2.max_rst_stream_frames_per_minute_exceeded");
   http2_rsb.max_continuation_frames_per_minute_exceeded =
     Metrics::Counter::createPtr("proxy.process.http2.max_continuation_frames_per_minute_exceeded");
+  http2_rsb.max_empty_frames_per_minute_exceeded =
+    Metrics::Counter::createPtr("proxy.process.http2.max_empty_frames_per_minute_exceeded");
   http2_rsb.insufficient_avg_window_update = Metrics::Counter::createPtr("proxy.process.http2.insufficient_avg_window_update");
   http2_rsb.max_concurrent_streams_exceeded_in =
     Metrics::Counter::createPtr("proxy.process.http2.max_concurrent_streams_exceeded_in");
diff --git a/src/proxy/http2/Http2ConnectionState.cc b/src/proxy/http2/Http2ConnectionState.cc
index d4e1ac6f2d..affbf0b813 100644
--- a/src/proxy/http2/Http2ConnectionState.cc
+++ b/src/proxy/http2/Http2ConnectionState.cc
@@ -184,8 +184,19 @@ Http2ConnectionState::rcv_data_frame(const Http2Frame &frame)
     stream->set_trailing_header_is_possible();
   }
 
-  // If payload length is 0 without END_STREAM flag, do nothing
-  if (payload_length == 0 && !stream->receive_end_stream) {
+  // If payload length is 0 without END_STREAM flag, just count it
+  const uint32_t unpadded_length = payload_length - pad_length;
+  if (unpadded_length == 0 && !stream->receive_end_stream) {
+    this->increment_received_empty_frame_count();
+    if (configured_max_empty_frames_per_minute >= 0 &&
+        this->get_received_empty_frame_count() > static_cast<uint32_t>(configured_max_empty_frames_per_minute)) {
+      Metrics::Counter::increment(http2_rsb.max_empty_frames_per_minute_exceeded);
+      Http2StreamDebug(this->session, id, "Observed too many empty DATA frames: %u within the last minute",
+                       this->get_received_empty_frame_count());
+      return Http2Error(Http2ErrorClass::HTTP2_ERROR_CLASS_CONNECTION, Http2ErrorCode::HTTP2_ERROR_ENHANCE_YOUR_CALM,
+                        "recv data too frequent empty frame");
+    }
+
     return Http2Error(Http2ErrorClass::HTTP2_ERROR_CLASS_NONE);
   }
 
@@ -211,8 +222,7 @@ Http2ConnectionState::rcv_data_frame(const Http2Frame &frame)
                      this->get_local_rwnd(), session_window, stream->get_local_rwnd(), stream_window);
   }
 
-  const uint32_t unpadded_length = payload_length - pad_length;
-  MIOBuffer     *writer          = stream->read_vio_writer();
+  MIOBuffer *writer = stream->read_vio_writer();
   if (writer == nullptr) {
     return Http2Error(Http2ErrorClass::HTTP2_ERROR_CLASS_STREAM, Http2ErrorCode::HTTP2_ERROR_INTERNAL_ERROR, "no writer");
   }
@@ -573,8 +583,8 @@ Http2ConnectionState::rcv_priority_frame(const Http2Frame &frame)
   // Update PRIORITY frame count per minute
   this->increment_received_priority_frame_count();
   // Close this connection if its priority frame count received exceeds a limit
-  if (configured_max_priority_frames_per_minute != 0 &&
-      this->get_received_priority_frame_count() > configured_max_priority_frames_per_minute) {
+  if (configured_max_priority_frames_per_minute >= 0 &&
+      this->get_received_priority_frame_count() > static_cast<uint32_t>(configured_max_priority_frames_per_minute)) {
     Metrics::Counter::increment(http2_rsb.max_priority_frames_per_minute_exceeded);
     Http2StreamDebug(this->session, stream_id, "Observed too frequent priority changes: %u priority changes within a last minute",
                      this->get_received_priority_frame_count());
@@ -648,8 +658,8 @@ Http2ConnectionState::rcv_rst_stream_frame(const Http2Frame &frame)
   // Update RST_STREAM frame count per minute
   this->increment_received_rst_stream_frame_count();
   // Close this connection if its RST_STREAM frame count exceeds a limit
-  if (configured_max_rst_stream_frames_per_minute != 0 &&
-      this->get_received_rst_stream_frame_count() > configured_max_rst_stream_frames_per_minute) {
+  if (configured_max_rst_stream_frames_per_minute >= 0 &&
+      this->get_received_rst_stream_frame_count() > static_cast<uint32_t>(configured_max_rst_stream_frames_per_minute)) {
     Metrics::Counter::increment(http2_rsb.max_rst_stream_frames_per_minute_exceeded);
     Http2StreamDebug(this->session, stream_id, "Observed too frequent RST_STREAM frames: %u frames within a last minute",
                      this->get_received_rst_stream_frame_count());
@@ -697,8 +707,8 @@ Http2ConnectionState::rcv_settings_frame(const Http2Frame &frame)
   // Update SETTINGS frame count per minute
   this->increment_received_settings_frame_count();
   // Close this connection if its SETTINGS frame count exceeds a limit
-  if (configured_max_settings_frames_per_minute != 0 &&
-      this->get_received_settings_frame_count() > configured_max_settings_frames_per_minute) {
+  if (configured_max_settings_frames_per_minute >= 0 &&
+      this->get_received_settings_frame_count() > static_cast<uint32_t>(configured_max_settings_frames_per_minute)) {
     Metrics::Counter::increment(http2_rsb.max_settings_frames_per_minute_exceeded);
     Http2StreamDebug(this->session, stream_id, "Observed too frequent SETTINGS frames: %u frames within a last minute",
                      this->get_received_settings_frame_count());
@@ -738,7 +748,7 @@ Http2ConnectionState::rcv_settings_frame(const Http2Frame &frame)
 
   uint32_t n_settings = 0;
   while (nbytes < frame.header().length) {
-    if (n_settings >= Http2::max_settings_per_frame) {
+    if (Http2::max_settings_per_frame >= 0 && n_settings >= static_cast<uint32_t>(Http2::max_settings_per_frame)) {
       Metrics::Counter::increment(http2_rsb.max_settings_per_frame_exceeded);
       Http2StreamDebug(this->session, stream_id, "Observed too many settings in a frame");
       return Http2Error(Http2ErrorClass::HTTP2_ERROR_CLASS_CONNECTION, Http2ErrorCode::HTTP2_ERROR_ENHANCE_YOUR_CALM,
@@ -779,7 +789,8 @@ Http2ConnectionState::rcv_settings_frame(const Http2Frame &frame)
   // Update settings count per minute
   this->increment_received_settings_count(n_settings);
   // Close this connection if its settings count received exceeds a limit
-  if (this->get_received_settings_count() > Http2::max_settings_per_minute) {
+  if (Http2::max_settings_per_frame >= 0 &&
+      this->get_received_settings_count() > static_cast<uint32_t>(Http2::max_settings_per_minute)) {
     Metrics::Counter::increment(http2_rsb.max_settings_per_minute_exceeded);
     Http2StreamDebug(this->session, stream_id, "Observed too frequent setting changes: %u settings within a last minute",
                      this->get_received_settings_count());
@@ -833,7 +844,8 @@ Http2ConnectionState::rcv_ping_frame(const Http2Frame &frame)
   // Update PING frame count per minute
   this->increment_received_ping_frame_count();
   // Close this connection if its ping count received exceeds a limit
-  if (configured_max_ping_frames_per_minute != 0 && this->get_received_ping_frame_count() > configured_max_ping_frames_per_minute) {
+  if (configured_max_ping_frames_per_minute >= 0 &&
+      this->get_received_ping_frame_count() > static_cast<uint32_t>(configured_max_ping_frames_per_minute)) {
     Metrics::Counter::increment(http2_rsb.max_ping_frames_per_minute_exceeded);
     Http2StreamDebug(this->session, stream_id, "Observed too frequent PING frames: %u PING frames within a last minute",
                      this->get_received_ping_frame_count());
@@ -1002,6 +1014,18 @@ Http2ConnectionState::rcv_continuation_frame(const Http2Frame &frame)
                       "continuation bad client id");
   }
 
+  if (payload_length == 0 && (frame.header().flags & HTTP2_FLAGS_HEADERS_END_HEADERS) == 0x0) {
+    this->increment_received_empty_frame_count();
+    if (configured_max_empty_frames_per_minute >= 0 &&
+        this->get_received_empty_frame_count() > static_cast<uint32_t>(configured_max_empty_frames_per_minute)) {
+      Metrics::Counter::increment(http2_rsb.max_empty_frames_per_minute_exceeded);
+      Http2StreamDebug(this->session, stream_id, "Observed too many empty CONTINUATION frames: %u within the last minute",
+                       this->get_received_empty_frame_count());
+      return Http2Error(Http2ErrorClass::HTTP2_ERROR_CLASS_CONNECTION, Http2ErrorCode::HTTP2_ERROR_ENHANCE_YOUR_CALM,
+                        "recv continuation too frequent empty frame");
+    }
+  }
+
   // Find opened stream
   // CONTINUATION frames MUST be associated with a stream.  If a
   // CONTINUATION frame is received whose stream identifier field is 0x0,
@@ -1033,7 +1057,7 @@ Http2ConnectionState::rcv_continuation_frame(const Http2Frame &frame)
   this->increment_received_continuation_frame_count();
   // Close this connection if its CONTINUATION frame count exceeds a limit.
   if (configured_max_continuation_frames_per_minute != 0 &&
-      this->get_received_continuation_frame_count() > configured_max_continuation_frames_per_minute) {
+      this->get_received_continuation_frame_count() > static_cast<uint32_t>(configured_max_continuation_frames_per_minute)) {
     Metrics::Counter::increment(http2_rsb.max_continuation_frames_per_minute_exceeded);
     Http2StreamDebug(this->session, stream_id, "Observed too frequent CONTINUATION frames: %u frames within a last minute",
                      this->get_received_continuation_frame_count());
@@ -1287,6 +1311,8 @@ Http2ConnectionState::init(Http2CommonSession *ssn)
   configured_max_priority_frames_per_minute     = Http2::max_priority_frames_per_minute;
   configured_max_rst_stream_frames_per_minute   = Http2::max_rst_stream_frames_per_minute;
   configured_max_continuation_frames_per_minute = Http2::max_continuation_frames_per_minute;
+  configured_max_empty_frames_per_minute        = Http2::max_empty_frames_per_minute;
+
   if (auto snis = session->get_netvc()->get_service<TLSSNISupport>(); snis) {
     if (snis->hints_from_sni.http2_max_settings_frames_per_minute.has_value()) {
       configured_max_settings_frames_per_minute = snis->hints_from_sni.http2_max_settings_frames_per_minute.value();
@@ -2798,6 +2824,18 @@ Http2ConnectionState::get_received_continuation_frame_count()
   return this->_received_continuation_frame_counter.get_count();
 }
 
+void
+Http2ConnectionState::increment_received_empty_frame_count()
+{
+  this->_received_empty_frame_counter.increment();
+}
+
+uint32_t
+Http2ConnectionState::get_received_empty_frame_count()
+{
+  return this->_received_empty_frame_counter.get_count();
+}
+
 // Return min_concurrent_streams_in when current client streams number is larger than max_active_streams_in.
 // Main purpose of this is preventing DDoS Attacks.
 unsigned
diff --git a/src/records/RecordsConfig.cc b/src/records/RecordsConfig.cc
index 4955ee7de3..899a6d3c76 100644
--- a/src/records/RecordsConfig.cc
+++ b/src/records/RecordsConfig.cc
@@ -1304,17 +1304,19 @@ static const RecordElement RecordsConfig[] =
   ,
   {RECT_CONFIG, "proxy.config.http2.stream_error_sampling_threshold", RECD_INT, "10", RECU_DYNAMIC, RR_NULL, RECC_STR, "^[0-9]+$", RECA_NULL}
   ,
-  {RECT_CONFIG, "proxy.config.http2.max_settings_per_frame", RECD_INT, "7", RECU_DYNAMIC, RR_NULL, RECC_STR, "^[0-9]+$", RECA_NULL}
+  {RECT_CONFIG, "proxy.config.http2.max_settings_per_frame", RECD_INT, "7", RECU_DYNAMIC, RR_NULL, RECC_STR, "^-?[0-9]+$", RECA_NULL}
   ,
-  {RECT_CONFIG, "proxy.config.http2.max_settings_per_minute", RECD_INT, "14", RECU_DYNAMIC, RR_NULL, RECC_STR, "^[0-9]+$", RECA_NULL}
+  {RECT_CONFIG, "proxy.config.http2.max_settings_per_minute", RECD_INT, "14", RECU_DYNAMIC, RR_NULL, RECC_STR, "^-?[0-9]+$", RECA_NULL}
   ,
-  {RECT_CONFIG, "proxy.config.http2.max_settings_frames_per_minute", RECD_INT, "14", RECU_DYNAMIC, RR_NULL, RECC_STR, "^[0-9]+$", RECA_NULL}
+  {RECT_CONFIG, "proxy.config.http2.max_settings_frames_per_minute", RECD_INT, "14", RECU_DYNAMIC, RR_NULL, RECC_STR, "^-?[0-9]+$", RECA_NULL}
   ,
-  {RECT_CONFIG, "proxy.config.http2.max_ping_frames_per_minute", RECD_INT, "60", RECU_DYNAMIC, RR_NULL, RECC_STR, "^[0-9]+$", RECA_NULL}
+  {RECT_CONFIG, "proxy.config.http2.max_ping_frames_per_minute", RECD_INT, "60", RECU_DYNAMIC, RR_NULL, RECC_STR, "^-?[0-9]+$", RECA_NULL}
   ,
-  {RECT_CONFIG, "proxy.config.http2.max_priority_frames_per_minute", RECD_INT, "120", RECU_DYNAMIC, RR_NULL, RECC_STR, "^[0-9]+$", RECA_NULL}
+  {RECT_CONFIG, "proxy.config.http2.max_priority_frames_per_minute", RECD_INT, "120", RECU_DYNAMIC, RR_NULL, RECC_STR, "^-?[0-9]+$", RECA_NULL}
   ,
-  {RECT_CONFIG, "proxy.config.http2.max_rst_stream_frames_per_minute", RECD_INT, "200", RECU_DYNAMIC, RR_NULL, RECC_STR, "^[0-9]+$", RECA_NULL}
+  {RECT_CONFIG, "proxy.config.http2.max_rst_stream_frames_per_minute", RECD_INT, "200", RECU_DYNAMIC, RR_NULL, RECC_STR, "^-?[0-9]+$", RECA_NULL}
+  ,
+  {RECT_CONFIG, "proxy.config.http2.max_empty_frames_per_minute", RECD_INT, "0", RECU_DYNAMIC, RR_NULL, RECC_STR, "^-?[0-9]+$", RECA_NULL}
   ,
   {RECT_CONFIG, "proxy.config.http2.max_continuation_frames_per_minute", RECD_INT, "120", RECU_DYNAMIC, RR_NULL, RECC_STR, "^[0-9]+$", RECA_NULL}
   ,


(trafficserver) 07/16: Check incoming protocol list length first (#11545)

Posted by cm...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

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

commit c7b7183ef7f3c17476f35ec5a4cb7e12c24f8d8a
Author: Masakazu Kitajo <ma...@apache.org>
AuthorDate: Mon Jul 15 16:24:17 2024 -0600

    Check incoming protocol list length first (#11545)
    
    If the length is 0, there's no need to do check the other list
    
    (cherry picked from commit 34819d12e1a3c838bce60b8911897767150de50e)
---
 src/iocore/net/ALPNSupport.cc | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/src/iocore/net/ALPNSupport.cc b/src/iocore/net/ALPNSupport.cc
index 20bcd18b42..dbe9eb74c7 100644
--- a/src/iocore/net/ALPNSupport.cc
+++ b/src/iocore/net/ALPNSupport.cc
@@ -104,7 +104,7 @@ ALPNSupport::select_next_protocol(const unsigned char **out, unsigned char *outl
   unsigned int         npnsize = 0;
   int                  retval  = SSL_TLSEXT_ERR_ALERT_FATAL;
 
-  if (this->getNPN(&npnptr, &npnsize) && npnsize > 0) {
+  if (inlen > 0 && this->getNPN(&npnptr, &npnsize) && npnsize > 0) {
     // SSL_select_next_proto chooses the first server-offered protocol that appears in the clients protocol set, ie. the
     // server selects the protocol. This is a n^2 search, so it's preferable to keep the protocol set short.
     if (SSL_select_next_proto(const_cast<unsigned char **>(out), outlen, npnptr, npnsize, in, inlen) == OPENSSL_NPN_NEGOTIATED) {


(trafficserver) 04/16: Deprecate the support for URL param segment (#11519)

Posted by cm...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

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

commit 8ffa5f61a98e9727867e47231d8161f31d9556cd
Author: Masakazu Kitajo <ma...@apache.org>
AuthorDate: Thu Jul 18 14:22:40 2024 -0600

    Deprecate the support for URL param segment (#11519)
    
    * Make TSUrlHttpParamsGet include params segment
    
    * Add some unit tests
    
    * Update docs
    
    * Fix
    
    (cherry picked from commit 5eb87bc8f264f638763fff93015652417a31ae3d)
---
 include/ts/ts.h                       |  6 +++
 src/proxy/hdrs/URL.cc                 | 76 ++++++++++----------------------
 src/proxy/hdrs/unit_tests/test_URL.cc | 82 +++++++++++++++++++++++++++++++++++
 src/proxy/http/HttpSM.cc              |  3 +-
 src/traffic_cache_tool/CacheScan.cc   |  8 ++--
 5 files changed, 115 insertions(+), 60 deletions(-)

diff --git a/include/ts/ts.h b/include/ts/ts.h
index 075fea93ee..95be90f3a6 100644
--- a/include/ts/ts.h
+++ b/include/ts/ts.h
@@ -666,6 +666,9 @@ TSReturnCode TSUrlFtpTypeSet(TSMBuffer bufp, TSMLoc offset, int type);
     argument. Note: the returned string is not guaranteed to be
     null-terminated.
 
+    This function is deprecated and returns empty string.
+    Plugins that need "params" can call TSUrlPathGet to get a whole path string to parse it.
+
     @param bufp marshal buffer containing the URL.
     @param offset location of the URL.
     @param length of the returned string.
@@ -682,6 +685,9 @@ const char *TSUrlHttpParamsGet(TSMBuffer bufp, TSMLoc offset, int *length);
     copies the string to within bufp, so you can modify or delete
     value after calling TSUrlHttpParamsSet().
 
+    This function is deprecated. The value passed will be internally appended to the path portion.
+    Thus, TSUrlHttpParamsGet will not return the value set by this function.
+
     @param bufp marshal buffer containing the URL.
     @param offset location of the URL.
     @param value HTTP params string to set in the URL.
diff --git a/src/proxy/hdrs/URL.cc b/src/proxy/hdrs/URL.cc
index 191e644876..e56ab796c2 100644
--- a/src/proxy/hdrs/URL.cc
+++ b/src/proxy/hdrs/URL.cc
@@ -551,8 +551,22 @@ URLImpl::set_path(HdrHeap *heap, const char *value, int length, bool copy_string
 void
 URLImpl::set_params(HdrHeap *heap, const char *value, int length, bool copy_string)
 {
-  url_called_set(this);
-  mime_str_u16_set(heap, value, length, &(this->m_ptr_params), &(this->m_len_params), copy_string);
+  int path_len = this->m_len_path;
+
+  // Truncate the current param segment if it exists
+  if (auto p = strchr(this->m_ptr_path, ';'); p != nullptr) {
+    auto params_len  = path_len - (p - this->m_ptr_path);
+    path_len        -= params_len;
+  }
+
+  int   total_length    = path_len + 1 + length;
+  char *path_and_params = static_cast<char *>(alloca(total_length));
+
+  memcpy(path_and_params, this->m_ptr_path, path_len);
+  memcpy(path_and_params + path_len, ";", 1);
+  memcpy(path_and_params + path_len + 1, value, length);
+
+  this->set_path(heap, path_and_params, total_length, true);
 }
 
 /*-------------------------------------------------------------------------
@@ -887,10 +901,6 @@ url_length_get(URLImpl *url, unsigned normalization_flags)
     length += 1; // +1 for "/"
   }
 
-  if (url->m_ptr_params && url->m_len_params > 0) {
-    length += url->m_len_params + 1; // +1 for ";"
-  }
-
   if (url->m_ptr_query && url->m_len_query > 0) {
     length += url->m_len_query + 1; // +1 for "?"
   }
@@ -962,12 +972,6 @@ url_to_string(URLImpl *url, Arena *arena, int *length)
   memcpy(&str[idx], url->m_ptr_path, url->m_len_path);
   idx += url->m_len_path;
 
-  if (url->m_ptr_params && url->m_len_params > 0) {
-    str[idx++] = ';';
-    memcpy(&str[idx], url->m_ptr_params, url->m_len_params);
-    idx += url->m_len_params;
-  }
-
   if (url->m_ptr_query && url->m_len_query > 0) {
     str[idx++] = '?';
     memcpy(&str[idx], url->m_ptr_query, url->m_len_query);
@@ -1433,8 +1437,6 @@ url_parse_http(HdrHeap *heap, URLImpl *url, const char **start, const char *end,
   const char *cur;
   const char *path_start     = nullptr;
   const char *path_end       = nullptr;
-  const char *params_start   = nullptr;
-  const char *params_end     = nullptr;
   const char *query_start    = nullptr;
   const char *query_end      = nullptr;
   const char *fragment_start = nullptr;
@@ -1456,13 +1458,9 @@ url_parse_http(HdrHeap *heap, URLImpl *url, const char **start, const char *end,
   if (*cur == '/') {
     path_start = cur;
   }
-  mask = ';' & '?' & '#';
+  mask = '?' & '#';
 parse_path2:
   if ((*cur & mask) == mask) {
-    if (*cur == ';') {
-      path_end = cur;
-      goto parse_params1;
-    }
     if (*cur == '?') {
       path_end = cur;
       goto parse_query1;
@@ -1472,26 +1470,11 @@ parse_path2:
       goto parse_fragment1;
     }
   } else {
-    ink_assert((*cur != ';') && (*cur != '?') && (*cur != '#'));
+    ink_assert((*cur != '?') && (*cur != '#'));
   }
   GETNEXT(done);
   goto parse_path2;
 
-parse_params1:
-  params_start = cur + 1;
-  GETNEXT(done);
-parse_params2:
-  if (*cur == '?') {
-    params_end = cur;
-    goto parse_query1;
-  }
-  if (*cur == '#') {
-    params_end = cur;
-    goto parse_fragment1;
-  }
-  GETNEXT(done);
-  goto parse_params2;
-
 parse_query1:
   query_start = cur + 1;
   GETNEXT(done);
@@ -1552,12 +1535,6 @@ done:
     // nothing_after_host check.
     url->m_path_is_empty = true;
   }
-  if (params_start) {
-    if (!params_end) {
-      params_end = cur;
-    }
-    url->set_params(heap, params_start, params_end - params_start, copy_strings);
-  }
   if (query_start) {
     // There was a query string marked by '?'.
     if (!query_end) {
@@ -1715,11 +1692,6 @@ url_print(URLImpl *url, char *buf_start, int buf_length, int *buf_index_inout, i
     TRY(mime_mem_print(url->m_ptr_path, url->m_len_path, buf_start, buf_length, buf_index_inout, buf_chars_to_skip_inout));
   }
 
-  if (url->m_ptr_params && url->m_len_params > 0) {
-    TRY(mime_mem_print(";", 1, buf_start, buf_length, buf_index_inout, buf_chars_to_skip_inout));
-    TRY(mime_mem_print(url->m_ptr_params, url->m_len_params, buf_start, buf_length, buf_index_inout, buf_chars_to_skip_inout));
-  }
-
   if (url->m_ptr_query && url->m_len_query > 0) {
     TRY(mime_mem_print("?", 1, buf_start, buf_length, buf_index_inout, buf_chars_to_skip_inout));
     TRY(mime_mem_print(url->m_ptr_query, url->m_len_query, buf_start, buf_length, buf_index_inout, buf_chars_to_skip_inout));
@@ -1753,8 +1725,6 @@ url_describe(HdrHeapObjImpl *raw, bool /* recurse ATS_UNUSED */)
       obj->m_len_port, obj->m_port);
   Dbg(dbg_ctl_http, "\tPATH: \"%.*s\", PATH_LEN: %d,", obj->m_len_path, (obj->m_ptr_path ? obj->m_ptr_path : "NULL"),
       obj->m_len_path);
-  Dbg(dbg_ctl_http, "\tPARAMS: \"%.*s\", PARAMS_LEN: %d,", obj->m_len_params, (obj->m_ptr_params ? obj->m_ptr_params : "NULL"),
-      obj->m_len_params);
   Dbg(dbg_ctl_http, "\tQUERY: \"%.*s\", QUERY_LEN: %d,", obj->m_len_query, (obj->m_ptr_query ? obj->m_ptr_query : "NULL"),
       obj->m_len_query);
   Dbg(dbg_ctl_http, "\tFRAGMENT: \"%.*s\", FRAGMENT_LEN: %d]", obj->m_len_fragment,
@@ -1855,8 +1825,8 @@ url_CryptoHash_get_general(const URLImpl *url, CryptoContext &ctx, CryptoHash &h
   ends[7] = strs[7] + 1;
   ends[8] = strs[8] + url->m_len_path;
 
-  strs[9]  = ";";
-  strs[10] = url->m_ptr_params;
+  strs[9]  = "";
+  strs[10] = nullptr;
   strs[11] = "?";
 
   // Special case for the query paramters, allowing us to ignore them if requested
@@ -1868,8 +1838,8 @@ url_CryptoHash_get_general(const URLImpl *url, CryptoContext &ctx, CryptoHash &h
     ends[12] = nullptr;
   }
 
-  ends[9]  = strs[9] + 1;
-  ends[10] = strs[10] + url->m_len_params;
+  ends[9]  = strs[9] + 0;
+  ends[10] = strs[10] + 0;
   ends[11] = strs[11] + 1;
 
   p = buffer;
@@ -1927,7 +1897,7 @@ url_CryptoHash_get(const URLImpl *url, CryptoHash *hash, bool ignore_query, cach
 {
   URLHashContext ctx;
   if ((url_hash_method != 0) && (url->m_url_type == URL_TYPE_HTTP) &&
-      ((url->m_len_user + url->m_len_password + url->m_len_params + (ignore_query ? 0 : url->m_len_query)) == 0) &&
+      ((url->m_len_user + url->m_len_password + (ignore_query ? 0 : url->m_len_query)) == 0) &&
       (3 + 1 + 1 + 1 + 1 + 1 + 2 + url->m_len_scheme + url->m_len_host + url->m_len_path < BUFSIZE) &&
       (memchr(url->m_ptr_host, '%', url->m_len_host) == nullptr) && (memchr(url->m_ptr_path, '%', url->m_len_path) == nullptr)) {
     url_CryptoHash_get_fast(url, ctx, hash, generation);
diff --git a/src/proxy/hdrs/unit_tests/test_URL.cc b/src/proxy/hdrs/unit_tests/test_URL.cc
index 5c7cdf4f40..9c5b3c6413 100644
--- a/src/proxy/hdrs/unit_tests/test_URL.cc
+++ b/src/proxy/hdrs/unit_tests/test_URL.cc
@@ -697,3 +697,85 @@ TEST_CASE("UrlHashGet", "[url][hash_get]")
     }
   }
 }
+
+struct get_path_test_case {
+  const std::string description;
+  const std::string uri;
+  const std::string path;
+};
+
+// clang-format off
+std::vector<get_path_test_case> get_path_test_cases = {
+  {
+    "Semicolon in paths 1",
+    "http://foo.test/abc/xyz;p1=1,p2=2",
+    "abc/xyz;p1=1,p2=2",
+  },
+  {
+    "Semicolon in paths 2",
+    "http://foo.test/abc;p1=1,p2=2/xyz",
+    "abc;p1=1,p2=2/xyz",
+  },
+  {
+    "Semicolon in paths 3",
+    "http://foo.test/abc/xyz;p1=1,p2=2?q1=1",
+    "abc/xyz;p1=1,p2=2",
+  },
+  {
+    "Semicolon in paths 4",
+    "http://foo.test/abc;p1=1,p2=2/xyz?q1=1",
+    "abc;p1=1,p2=2/xyz",
+  },
+};
+
+/** Return the hash related to a URI.
+  *
+  * @param[in] uri The URI to hash.
+  * @return The hash of the URI.
+ */
+TEST_CASE("UrlPathGet", "[url][path_get]")
+{
+  for (auto const &test_case : get_path_test_cases) {
+    std::string description = test_case.description + ": " + test_case.uri + " -> " + test_case.path;
+    SECTION(description) {
+      URL url;
+      HdrHeap *heap = new_HdrHeap();
+      url.create(heap);
+      url.parse(test_case.uri);
+      const char *path;
+      int path_len;
+      path = url.path_get(&path_len);
+      CHECK(std::string_view(path, path_len) == test_case.path);
+      heap->destroy();
+    }
+  }
+}
+
+
+/**
+ * Tests for deprecated params_get/set
+ */
+TEST_CASE("UrlParamsGet", "[url][params_get]")
+{
+  // Expected behavior
+  // - ParamsGet always return empty string
+  // - ParamsSet appends the value to path
+  // - PathGet returns params appended by ParamsSet
+
+  const char *value;
+  int value_len;
+
+  URL url;
+  HdrHeap *heap = new_HdrHeap();
+  url.create(heap);
+  url.parse("https://foo.test/path;p=1");
+  value = url.path_get(&value_len);
+  CHECK(std::string_view(value, value_len) == "path;p=1");
+  url.params_set("param=1", 7);
+  value = url.params_get(&value_len);
+  CHECK(value == nullptr);
+  CHECK(value_len == 0);
+  value = url.path_get(&value_len);
+  CHECK(std::string_view(value, value_len) == "path;param=1");
+  heap->destroy();
+}
diff --git a/src/proxy/http/HttpSM.cc b/src/proxy/http/HttpSM.cc
index 2b2119ae76..a3cd0eb644 100644
--- a/src/proxy/http/HttpSM.cc
+++ b/src/proxy/http/HttpSM.cc
@@ -709,8 +709,7 @@ HttpSM::state_read_client_request_header(int event, void *data)
         call_transact_and_set_next_state(HttpTransact::TooEarly);
         return 0;
       } else if (!SSLConfigParams::server_allow_early_data_params &&
-                 (t_state.hdr_info.client_request.m_http->u.req.m_url_impl->m_len_params > 0 ||
-                  t_state.hdr_info.client_request.m_http->u.req.m_url_impl->m_len_query > 0)) {
+                 t_state.hdr_info.client_request.m_http->u.req.m_url_impl->m_len_query > 0) {
         SMDbg(dbg_ctl_http, "client request was from early data but HAS parameters");
         call_transact_and_set_next_state(HttpTransact::TooEarly);
         return 0;
diff --git a/src/traffic_cache_tool/CacheScan.cc b/src/traffic_cache_tool/CacheScan.cc
index bac9ea3f75..26e92894ef 100644
--- a/src/traffic_cache_tool/CacheScan.cc
+++ b/src/traffic_cache_tool/CacheScan.cc
@@ -388,19 +388,17 @@ CacheScan::get_alternates(const char *buf, int length, bool search)
         std::string str;
 
         if (search) {
-          swoc::bwprint(str, "{}://{}:{}/{};{}?{}", std::string_view(url->m_ptr_scheme, url->m_len_scheme),
+          swoc::bwprint(str, "{}://{}:{}/{}?{}", std::string_view(url->m_ptr_scheme, url->m_len_scheme),
                         std::string_view(url->m_ptr_host, url->m_len_host), std::string_view(url->m_ptr_port, url->m_len_port),
-                        std::string_view(url->m_ptr_path, url->m_len_path), std::string_view(url->m_ptr_params, url->m_len_params),
-                        std::string_view(url->m_ptr_query, url->m_len_query));
+                        std::string_view(url->m_ptr_path, url->m_len_path), std::string_view(url->m_ptr_query, url->m_len_query));
           if (u_matcher->match(str.data())) {
             str = this->stripe->hashText + " " + str;
             std::cout << "match found " << str << std::endl;
           }
         } else {
-          swoc::bwprint(str, "stripe: {} : {}://{}:{}/{};{}?{}", std::string_view(this->stripe->hashText),
+          swoc::bwprint(str, "stripe: {} : {}://{}:{}/{}?{}", std::string_view(this->stripe->hashText),
                         std::string_view(url->m_ptr_scheme, url->m_len_scheme), std::string_view(url->m_ptr_host, url->m_len_host),
                         std::string_view(url->m_ptr_port, url->m_len_port), std::string_view(url->m_ptr_path, url->m_len_path),
-                        std::string_view(url->m_ptr_params, url->m_len_params),
                         std::string_view(url->m_ptr_query, url->m_len_query));
           std::cout << str << std::endl;
         }


(trafficserver) 11/16: Removes the Matrix parameters from Cripts (#11569)

Posted by cm...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

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

commit e254d166662295b7e17d4c8d326d700cf44a18e4
Author: Leif Hedstrom <zw...@apache.org>
AuthorDate: Thu Jul 18 21:40:18 2024 -0600

    Removes the Matrix parameters from Cripts (#11569)
    
    (cherry picked from commit f22d35fba0686212705dfaf01899b0cbedda3cb8)
---
 doc/developer-guide/cripts/cripts-urls.en.rst |  1 -
 include/cripts/Urls.hpp                       | 31 +--------------------------
 src/cripts/Urls.cc                            | 27 -----------------------
 3 files changed, 1 insertion(+), 58 deletions(-)

diff --git a/doc/developer-guide/cripts/cripts-urls.en.rst b/doc/developer-guide/cripts/cripts-urls.en.rst
index 5666e2c3db..07a0678290 100644
--- a/doc/developer-guide/cripts/cripts-urls.en.rst
+++ b/doc/developer-guide/cripts/cripts-urls.en.rst
@@ -75,7 +75,6 @@ Component         Description
 ``port``          The port number, this is an integer value.
 ``path``          The path.
 ``query``         The query parameters.
-``matrix``        The matrix parameters: Note: This is currently treated as a single string.
 ===============   =================================================================================
 
 .. note::
diff --git a/include/cripts/Urls.hpp b/include/cripts/Urls.hpp
index cd034bb2e2..d4a41dad21 100644
--- a/include/cripts/Urls.hpp
+++ b/include/cripts/Urls.hpp
@@ -522,21 +522,8 @@ public:
 
   }; // End class Url::Query
 
-  class Matrix : public Component
-  {
-    using super_type = Component;
-    using self_type  = Matrix;
-
-  public:
-    using Component::Component;
-
-    Cript::string_view GetSV() override;
-    self_type          operator=(Cript::string_view matrix);
-
-  }; // End class Url::Matrix
-
 public:
-  Url() : scheme(this), host(this), port(this), path(this), query(this), matrix(this) {}
+  Url() : scheme(this), host(this), port(this), path(this), query(this) {}
 
   // Clear anything "cached" in the Url, this is rather draconian, but it's safe...
   virtual void
@@ -585,7 +572,6 @@ public:
   Port   port;
   Path   path;
   Query  query;
-  Matrix matrix;
 
 protected:
   void
@@ -895,19 +881,4 @@ template <> struct formatter<Cript::Url::Query> {
   }
 };
 
-template <> struct formatter<Cript::Url::Matrix> {
-  constexpr auto
-  parse(format_parse_context &ctx) -> decltype(ctx.begin())
-  {
-    return ctx.begin();
-  }
-
-  template <typename FormatContext>
-  auto
-  format(Cript::Url::Matrix &matrix, FormatContext &ctx) -> decltype(ctx.out())
-  {
-    return fmt::format_to(ctx.out(), "{}", matrix.GetSV());
-  }
-};
-
 } // namespace fmt
diff --git a/src/cripts/Urls.cc b/src/cripts/Urls.cc
index 14d79e2d00..034376cea8 100644
--- a/src/cripts/Urls.cc
+++ b/src/cripts/Urls.cc
@@ -402,33 +402,6 @@ Cript::Url::Query::_parser()
   }
 }
 
-Cript::string_view
-Cript::Url::Matrix::GetSV()
-{
-  if (_owner && _data.empty()) {
-    const char *value = nullptr;
-    int         len   = 0;
-
-    value   = TSUrlHttpParamsGet(_owner->_bufp, _owner->_urlp, &len);
-    _data   = Cript::string_view(value, len);
-    _loaded = true;
-  }
-
-  return _data;
-}
-
-Cript::Url::Matrix
-Cript::Url::Matrix::operator=(Cript::string_view matrix)
-{
-  CAssert(!_owner->ReadOnly()); // This can not be a read-only URL
-  TSUrlHttpParamsSet(_owner->_bufp, _owner->_urlp, matrix.data(), matrix.size());
-  _owner->_modified = true;
-  Reset();
-  _loaded = false;
-
-  return *this;
-}
-
 Cript::string
 Cript::Url::String() const
 {


(trafficserver) 02/16: Update quiche to 0.22.0. (#11493)

Posted by cm...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

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

commit 58bc651e8fb6801cb7df34fbafbf67c89d4ce4ef
Author: Damian Meden <dm...@apache.org>
AuthorDate: Tue Jul 16 01:16:51 2024 +0200

    Update quiche to 0.22.0. (#11493)
    
    This bumps the quiche version from the build deps scripts and
    update the code to use the changed API from quic:
    - quiche_conn_stream_recv
    - quiche_conn_stream_send
    
    which now takes an extra param to get the detected error(if any).
    
    (cherry picked from commit e6a8ac335e819f2849fa5581774861e4cbc346d3)
---
 include/iocore/net/quic/QUICStream.h |  2 ++
 src/iocore/net/quic/QUICStream.cc    | 18 +++++++++++-------
 tools/build_boringssl_h3_tools.sh    |  4 +++-
 tools/build_openssl_h3_tools.sh      |  4 +++-
 4 files changed, 19 insertions(+), 9 deletions(-)

diff --git a/include/iocore/net/quic/QUICStream.h b/include/iocore/net/quic/QUICStream.h
index 4caa16d731..689d399654 100644
--- a/include/iocore/net/quic/QUICStream.h
+++ b/include/iocore/net/quic/QUICStream.h
@@ -43,6 +43,8 @@ class QUICStreamStateListener;
 class QUICStream
 {
 public:
+  using ErrorCode = uint64_t; //!<  recv/send stream application error codes.
+
   QUICStream() {}
   QUICStream(QUICConnectionInfoProvider *cinfo, QUICStreamId sid);
   ~QUICStream();
diff --git a/src/iocore/net/quic/QUICStream.cc b/src/iocore/net/quic/QUICStream.cc
index b01e4d1280..fcdfc7e88e 100644
--- a/src/iocore/net/quic/QUICStream.cc
+++ b/src/iocore/net/quic/QUICStream.cc
@@ -96,11 +96,13 @@ QUICStream::on_eos()
 void
 QUICStream::receive_data(quiche_conn *quiche_con)
 {
-  uint8_t buf[4096];
-  bool    fin;
-  ssize_t read_len = 0;
+  uint8_t                    buf[4096];
+  bool                       fin;
+  ssize_t                    read_len = 0;
+  [[maybe_unused]] ErrorCode error_code{0}; // Only set if QUICHE_ERR_STREAM_STOPPED(-15) or QUICHE_ERR_STREAM_RESET(-16) are
+                                            // returned by quiche_conn_stream_recv.
 
-  while ((read_len = quiche_conn_stream_recv(quiche_con, this->_id, buf, sizeof(buf), &fin)) > 0) {
+  while ((read_len = quiche_conn_stream_recv(quiche_con, this->_id, buf, sizeof(buf), &fin, &error_code)) > 0) {
     this->_adapter->write(this->_received_bytes, buf, read_len, fin);
     this->_received_bytes += read_len;
   }
@@ -112,8 +114,10 @@ QUICStream::receive_data(quiche_conn *quiche_con)
 void
 QUICStream::send_data(quiche_conn *quiche_con)
 {
-  bool    fin = false;
-  ssize_t len = 0;
+  bool                       fin = false;
+  ssize_t                    len = 0;
+  [[maybe_unused]] ErrorCode error_code{0}; // Only set if QUICHE_ERR_STREAM_STOPPED(-15) or QUICHE_ERR_STREAM_RESET(-16) are
+                                            // returned by quiche_conn_stream_send.
 
   len = quiche_conn_stream_capacity(quiche_con, this->_id);
   if (len <= 0) {
@@ -125,7 +129,7 @@ QUICStream::send_data(quiche_conn *quiche_con)
   }
   if (block->size() > 0 || fin) {
     ssize_t written_len =
-      quiche_conn_stream_send(quiche_con, this->_id, reinterpret_cast<uint8_t *>(block->start()), block->size(), fin);
+      quiche_conn_stream_send(quiche_con, this->_id, reinterpret_cast<uint8_t *>(block->start()), block->size(), fin, &error_code);
     if (written_len >= 0) {
       this->_sent_bytes += written_len;
     }
diff --git a/tools/build_boringssl_h3_tools.sh b/tools/build_boringssl_h3_tools.sh
index b4dced9657..f5261f9e80 100755
--- a/tools/build_boringssl_h3_tools.sh
+++ b/tools/build_boringssl_h3_tools.sh
@@ -168,12 +168,14 @@ echo "Building quiche"
 QUICHE_BASE="${BASE:-/opt}/quiche"
 [ ! -d quiche ] && git clone  https://github.com/cloudflare/quiche.git
 cd quiche
-git checkout 0.21.0
+git checkout 0.22.0
 QUICHE_BSSL_PATH=${BORINGSSL_LIB_PATH} QUICHE_BSSL_LINK_KIND=dylib cargo build -j4 --package quiche --release --features ffi,pkg-config-meta,qlog
 sudo mkdir -p ${QUICHE_BASE}/lib/pkgconfig
 sudo mkdir -p ${QUICHE_BASE}/include
 sudo cp target/release/libquiche.a ${QUICHE_BASE}/lib/
 [ -f target/release/libquiche.so ] && sudo cp target/release/libquiche.so ${QUICHE_BASE}/lib/
+# Why a link? https://github.com/cloudflare/quiche/issues/1808#issuecomment-2196233378
+sudo ln -s ${QUICHE_BASE}/lib/libquiche.so ${QUICHE_BASE}/lib/libquiche.so.0
 sudo cp quiche/include/quiche.h ${QUICHE_BASE}/include/
 sudo cp target/release/quiche.pc ${QUICHE_BASE}/lib/pkgconfig
 sudo chmod -R a+rX ${BASE}
diff --git a/tools/build_openssl_h3_tools.sh b/tools/build_openssl_h3_tools.sh
index cc4d358b75..0f4c5c4f26 100755
--- a/tools/build_openssl_h3_tools.sh
+++ b/tools/build_openssl_h3_tools.sh
@@ -120,7 +120,7 @@ echo "Building quiche"
 QUICHE_BASE="${BASE:-/opt}/quiche"
 [ ! -d quiche ] && git clone https://github.com/cloudflare/quiche.git
 cd quiche
-git checkout 0.21.0
+git checkout 0.22.0
 
 PKG_CONFIG_PATH="$OPENSSL_LIB"/pkgconfig LD_LIBRARY_PATH="$OPENSSL_LIB" \
   cargo build -j4 --package quiche --release --features ffi,pkg-config-meta,qlog,openssl
@@ -129,6 +129,8 @@ sudo mkdir -p ${QUICHE_BASE}/lib/pkgconfig
 sudo mkdir -p ${QUICHE_BASE}/include
 sudo cp target/release/libquiche.a ${QUICHE_BASE}/lib/
 [ -f target/release/libquiche.so ] && sudo cp target/release/libquiche.so ${QUICHE_BASE}/lib/
+# Why a link? https://github.com/cloudflare/quiche/issues/1808#issuecomment-2196233378
+sudo ln -s ${QUICHE_BASE}/lib/libquiche.so ${QUICHE_BASE}/lib/libquiche.so.0
 sudo cp quiche/include/quiche.h ${QUICHE_BASE}/include/
 sudo cp target/release/quiche.pc ${QUICHE_BASE}/lib/pkgconfig
 sudo chmod -R a+rX ${BASE}


(trafficserver) 08/16: setup_server_read_response_header: remove assertion (#11548)

Posted by cm...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

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

commit f63c1a23cc804a89992127d279ccd67dcac30195
Author: Brian Neradt <br...@gmail.com>
AuthorDate: Mon Jul 15 13:50:58 2024 -0500

    setup_server_read_response_header: remove assertion (#11548)
    
    This addresses an intermittent assertion failure associated with Expect:
    100-Continue via the h2origin.test.py autest introduced via #11536.
    Since the 100 Continue is followed immediately by 200 OK, it is possible
    that both are processed at once if the Expect: 100-Continue request has
    no body. In these cases, the assertion will fail because
    state_read_server_response_header will have processed the entire
    response. Since that is now possible, we might as well just remove the
    assertion. In theory, it can be kept for the case when there is no
    response bytes available to read, but in those situations the assertion
    isn't really doing anything because there will be no complicated logic
    from state_read_server_response_header and we set the server_entry->vc
    earlier in the function.
    
    (cherry picked from commit 05a58d10df279182b8ce5fc22129e31fa62d80bb)
---
 src/proxy/http/HttpSM.cc | 1 -
 1 file changed, 1 deletion(-)

diff --git a/src/proxy/http/HttpSM.cc b/src/proxy/http/HttpSM.cc
index a3cd0eb644..5fd1e7fd72 100644
--- a/src/proxy/http/HttpSM.cc
+++ b/src/proxy/http/HttpSM.cc
@@ -6668,7 +6668,6 @@ HttpSM::setup_server_read_response_header()
   if (server_txn->get_remote_reader()->read_avail() > 0) {
     state_read_server_response_header((server_entry->eos) ? VC_EVENT_EOS : VC_EVENT_READ_READY, server_entry->read_vio);
   }
-  ink_assert(server_entry->vc != nullptr);
 }
 
 HttpTunnelProducer *


(trafficserver) 16/16: Set `TS_HAVE_TLS_EARLY_DATA` correctly (#11577)

Posted by cm...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

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

commit aa4ec84190a52171a4ae1ea3fa0f2faa9a14f8dd
Author: JosiahWI <41...@users.noreply.github.com>
AuthorDate: Thu Jul 18 17:01:09 2024 -0500

    Set `TS_HAVE_TLS_EARLY_DATA` correctly (#11577)
    
    I chose a conditional over a generator expression because the community is
    likely more familiar with the conditional, and the generator expressions can
    look kind of messy.
    
    Fixes #11575.
    
    (cherry picked from commit 59404ee1cffda817cb11e4ee81eb0e5344b939a2)
---
 CMakeLists.txt | 16 ++++++++--------
 1 file changed, 8 insertions(+), 8 deletions(-)

diff --git a/CMakeLists.txt b/CMakeLists.txt
index 0069e1b68f..8155afe9d0 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -485,15 +485,15 @@ endif()
 
 unset(CMAKE_REQUIRED_FLAGS)
 
-set(TS_HAS_TLS_EARLY_DATA
-    ${HAVE_SSL_SET_MAX_EARLY_DATA}
-    |
-    ${HAVE_SSL_READ_EARLY_DATA}
-    |
-    ${HAVE_SSL_WRITE_EARLY_DATA}
-    |
-    ${HAVE_SSL_IN_EARLY_DATA}
+if(HAVE_SSL_SET_MAX_EARLY_DATA
+   OR HAVE_SSL_READ_EARL_DATA
+   OR HAVE_SSL_WRITE_EARLY_DATA
+   OR HAVE_SSL_IN_EARLY_DATA
 )
+  set(TS_HAS_TLS_EARLY_DATA TRUE)
+else()
+  set(TS_HAS_TLS_EARLY_DATA FALSE)
+endif()
 
 set(CMAKE_REQUIRED_INCLUDES netinet/in.h netinet/tcp.h)
 check_type_size("struct tcp_info" STRUCT_TCP_INFO)