diff -u -r -N squid-5.6/ChangeLog squid-5.7/ChangeLog
--- squid-5.6/ChangeLog	2022-06-06 10:11:52.000000000 +1200
+++ squid-5.7/ChangeLog	2022-09-05 16:06:48.000000000 +1200
@@ -1,3 +1,14 @@
+Changes in squid-5.7 (05 Sep 2022):
+
+	- Regression Fix: Typo in manager ACL
+	- Bug 5186: noteDestinationsEnd check failed: transportWait
+	- Bug 5160: Test suite fails with -flto=auto
+	- Bug 3193 pt2: NTLM decoder truncating strings
+	- Bug 5133: OpenSSL 3.0 support
+	- ext_session_acl: fix TDB key lookup
+	- forward_max_tries: Do not count discarded connections
+	- ... and many compile and debugging fixes
+
 Changes in squid-5.6 (06 Jun 2022):
 
 	- Bug 5208: Part 1: Restart kids killed by SIGKILL
diff -u -r -N squid-5.6/compat/GnuRegex.c squid-5.7/compat/GnuRegex.c
--- squid-5.6/compat/GnuRegex.c	2022-06-06 10:11:52.000000000 +1200
+++ squid-5.7/compat/GnuRegex.c	2022-09-05 16:06:48.000000000 +1200
@@ -40,6 +40,13 @@
 
 #if USE_GNUREGEX /* only if squid needs it. Usually not */
 
+/* Starting with v12.1, GCC warns of various problems with this ancient code. */
+/* GCC versions prior to v12.1 do not support these pragmas. */
+#if (__GNUC__ == 12 && __GNUC_MINOR__ >= 1) || (__GNUC__ > 12)
+#pragma GCC diagnostic ignored "-Warray-bounds"
+#pragma GCC diagnostic ignored "-Wuse-after-free"
+#endif
+
 #if !HAVE_ALLOCA
 #define REGEX_MALLOC 1
 #endif
diff -u -r -N squid-5.6/compat/os/mswindows.h squid-5.7/compat/os/mswindows.h
--- squid-5.6/compat/os/mswindows.h	2022-06-06 10:11:52.000000000 +1200
+++ squid-5.7/compat/os/mswindows.h	2022-09-05 16:06:48.000000000 +1200
@@ -618,27 +618,31 @@
 }
 #define getsockopt(s,l,o,v,n) Squid::getsockopt(s,l,o,v,n)
 
+#if HAVE_DECL_INETNTOPA || HAVE_DECL_INET_NTOP
 inline char *
 inet_ntop(int af, const void *src, char *dst, size_t size)
 {
 #if HAVE_DECL_INETNTOPA
     return (char*)InetNtopA(af, const_cast<void*>(src), dst, size);
-#else
+#else // HAVE_DECL_INET_NTOP
     return ::inet_ntop(af, src, dst, size);
 #endif
 }
 #define inet_ntop(a,s,d,l) Squid::inet_ntop(a,s,d,l)
+#endif // let compat/inet_ntop.h deal with it
 
+#if HAVE_DECL_INETPTONA || HAVE_DECL_INET_PTON
 inline char *
 inet_pton(int af, const void *src, char *dst)
 {
 #if HAVE_DECL_INETPTONA
     return (char*)InetPtonA(af, const_cast<void*>(src), dst);
-#else
+#else // HAVE_DECL_INET_PTON
     return ::inet_pton(af, src, dst);
 #endif
 }
 #define inet_pton(a,s,d) Squid::inet_pton(a,s,d)
+#endif // let compat/inet_pton.h deal with it
 
 /* Simple ioctl() emulation */
 inline int
diff -u -r -N squid-5.6/configure squid-5.7/configure
--- squid-5.6/configure	2022-06-06 10:42:04.000000000 +1200
+++ squid-5.7/configure	2022-09-06 03:35:26.000000000 +1200
@@ -1,7 +1,7 @@
 #! /bin/sh
 # From configure.ac Revision.
 # Guess values for system-dependent variables and create Makefiles.
-# Generated by GNU Autoconf 2.71 for Squid Web Proxy 5.6.
+# Generated by GNU Autoconf 2.71 for Squid Web Proxy 5.7.
 #
 # Report bugs to <http://bugs.squid-cache.org/>.
 #
@@ -626,8 +626,8 @@
 # Identity of this package.
 PACKAGE_NAME='Squid Web Proxy'
 PACKAGE_TARNAME='squid'
-PACKAGE_VERSION='5.6'
-PACKAGE_STRING='Squid Web Proxy 5.6'
+PACKAGE_VERSION='5.7'
+PACKAGE_STRING='Squid Web Proxy 5.7'
 PACKAGE_BUGREPORT='http://bugs.squid-cache.org/'
 PACKAGE_URL=''
 
@@ -1691,7 +1691,7 @@
   # Omit some internal or obsolete options to make the list less imposing.
   # This message is too long to be a string in the A/UX 3.1 sh.
   cat <<_ACEOF
-\`configure' configures Squid Web Proxy 5.6 to adapt to many kinds of systems.
+\`configure' configures Squid Web Proxy 5.7 to adapt to many kinds of systems.
 
 Usage: $0 [OPTION]... [VAR=VALUE]...
 
@@ -1762,7 +1762,7 @@
 
 if test -n "$ac_init_help"; then
   case $ac_init_help in
-     short | recursive ) echo "Configuration of Squid Web Proxy 5.6:";;
+     short | recursive ) echo "Configuration of Squid Web Proxy 5.7:";;
    esac
   cat <<\_ACEOF
 
@@ -2196,7 +2196,7 @@
 test -n "$ac_init_help" && exit $ac_status
 if $ac_init_version; then
   cat <<\_ACEOF
-Squid Web Proxy configure 5.6
+Squid Web Proxy configure 5.7
 generated by GNU Autoconf 2.71
 
 Copyright (C) 2021 Free Software Foundation, Inc.
@@ -3209,7 +3209,7 @@
 This file contains any messages produced by compilers while
 running configure, to aid debugging if configure makes a mistake.
 
-It was created by Squid Web Proxy $as_me 5.6, which was
+It was created by Squid Web Proxy $as_me 5.7, which was
 generated by GNU Autoconf 2.71.  Invocation command line was
 
   $ $0$ac_configure_args_raw
@@ -4701,7 +4701,7 @@
 
 # Define the identity of the package.
  PACKAGE='squid'
- VERSION='5.6'
+ VERSION='5.7'
 
 
 printf "%s\n" "#define PACKAGE \"$PACKAGE\"" >>confdefs.h
@@ -25257,6 +25257,12 @@
   printf "%s\n" "#define HAVE_OPENSSL_CRYPTO_H 1" >>confdefs.h
 
 fi
+ac_fn_cxx_check_header_compile "$LINENO" "openssl/decoder.h" "ac_cv_header_openssl_decoder_h" "$ac_includes_default"
+if test "x$ac_cv_header_openssl_decoder_h" = xyes
+then :
+  printf "%s\n" "#define HAVE_OPENSSL_DECODER_H 1" >>confdefs.h
+
+fi
 ac_fn_cxx_check_header_compile "$LINENO" "openssl/dh.h" "ac_cv_header_openssl_dh_h" "$ac_includes_default"
 if test "x$ac_cv_header_openssl_dh_h" = xyes
 then :
@@ -48442,7 +48448,7 @@
 # report actual input values of CONFIG_FILES etc. instead of their
 # values after options handling.
 ac_log="
-This file was extended by Squid Web Proxy $as_me 5.6, which was
+This file was extended by Squid Web Proxy $as_me 5.7, which was
 generated by GNU Autoconf 2.71.  Invocation command line was
 
   CONFIG_FILES    = $CONFIG_FILES
@@ -48510,7 +48516,7 @@
 cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
 ac_cs_config='$ac_cs_config_escaped'
 ac_cs_version="\\
-Squid Web Proxy config.status 5.6
+Squid Web Proxy config.status 5.7
 configured by $0, generated by GNU Autoconf 2.71,
   with options \\"\$ac_cs_config\\"
 
diff -u -r -N squid-5.6/configure.ac squid-5.7/configure.ac
--- squid-5.6/configure.ac	2022-06-06 10:42:04.000000000 +1200
+++ squid-5.7/configure.ac	2022-09-06 03:35:26.000000000 +1200
@@ -5,7 +5,7 @@
 ## Please see the COPYING and CONTRIBUTORS files for details.
 ##
 
-AC_INIT([Squid Web Proxy],[5.6],[http://bugs.squid-cache.org/],[squid])
+AC_INIT([Squid Web Proxy],[5.7],[http://bugs.squid-cache.org/],[squid])
 AC_PREREQ(2.61)
 AC_CONFIG_HEADERS([include/autoconf.h])
 AC_CONFIG_AUX_DIR(cfgaux)
@@ -1333,6 +1333,7 @@
     openssl/bio.h \
     openssl/bn.h \
     openssl/crypto.h \
+    openssl/decoder.h \
     openssl/dh.h \
     openssl/err.h \
     openssl/evp.h \
diff -u -r -N squid-5.6/doc/release-notes/release-5.html squid-5.7/doc/release-notes/release-5.html
--- squid-5.6/doc/release-notes/release-5.html	2022-06-06 10:47:28.000000000 +1200
+++ squid-5.7/doc/release-notes/release-5.html	2022-09-06 03:40:52.000000000 +1200
@@ -3,10 +3,10 @@
 <HEAD>
  <META NAME="GENERATOR" CONTENT="LinuxDoc-Tools 0.9.82">
  <meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
- <TITLE>Squid 5.6 release notes</TITLE>
+ <TITLE>Squid 5.7 release notes</TITLE>
 </HEAD>
 <BODY>
-<H1>Squid 5.6 release notes</H1>
+<H1>Squid 5.7 release notes</H1>
 
 <H2>Squid Developers</H2>
 <HR>
@@ -31,6 +31,7 @@
 <LI><A NAME="toc2.4">2.4</A> <A HREF="#ss2.4">TrivialDB Support</A>
 <LI><A NAME="toc2.5">2.5</A> <A HREF="#ss2.5">Loop Detection in Content Delivery Networks</A>
 <LI><A NAME="toc2.6">2.6</A> <A HREF="#ss2.6">Peering support for SSL-Bump</A>
+<LI><A NAME="toc2.7">2.7</A> <A HREF="#ss2.7">OpenSSL 3.0 Support</A>
 </UL>
 <P>
 <H2><A NAME="toc3">3.</A> <A HREF="#s3">Changes to squid.conf since Squid-4</A></H2>
@@ -61,7 +62,7 @@
 <HR>
 <H2><A NAME="s1">1.</A> <A HREF="#toc1">Notice</A></H2>
 
-<P>The Squid Team are pleased to announce the release of Squid-5.6.</P>
+<P>The Squid Team are pleased to announce the release of Squid-5.7.</P>
 <P>This new release is available for download from 
 <A HREF="http://www.squid-cache.org/Versions/v5/">http://www.squid-cache.org/Versions/v5/</A> or the
 <A HREF="http://www.squid-cache.org/Download/http-mirrors.html">mirrors</A>.</P>
@@ -95,6 +96,7 @@
 <LI>TrivialDB Support</LI>
 <LI>RFC 8586: Loop Detection in Content Delivery Networks</LI>
 <LI>Peering support for SSL-Bump</LI>
+<LI>OpenSSL 3.0 Support</LI>
 </UL>
 </P>
 <P>Most user-facing changes are reflected in squid.conf (see below).</P>
@@ -220,6 +222,21 @@
 yet do TLS-in-TLS.</P>
 
 
+<H2><A NAME="ss2.7">2.7</A> <A HREF="#toc2.7">OpenSSL 3.0 Support</A>
+</H2>
+
+<P>Squid-5.7 adds OpenSSL 3.0 support.</P>
+
+<P>This version of Squid does not add any of the new features provided by
+OpenSSL 3.0. It only contains support for features already supported by prior
+versions of Squid using new APIs provided by OpenSSL 3.0.</P>
+
+<P>Notably the libssl custom Engine feature has been deprecated by OpenSSL 3.0
+and new Providers replacement is not supported by this Squid.</P>
+
+<P>OpenSSL 3.0 uses new licensing terms.</P>
+
+
 <H2><A NAME="s3">3.</A> <A HREF="#toc3">Changes to squid.conf since Squid-4</A></H2>
 
 <P>There have been changes to Squid's configuration file since Squid-4.</P>
@@ -364,6 +381,10 @@
 <P>Codes <EM>rm</EM>, <EM>&lt;rm</EM> and <EM>&gt;rm</EM> display "-"
 instead of the made-up method NONE.</P>
 
+<DT><B>ssl_engine</B><DD>
+<P>OpenSSL 3.0 deprecates the Engine feature. This directive is
+only supported when Squid is built for older OpenSSL versions.</P>
+
 </DL>
 </P>
 
diff -u -r -N squid-5.6/include/autoconf.h.in squid-5.7/include/autoconf.h.in
--- squid-5.6/include/autoconf.h.in	2022-06-06 10:41:58.000000000 +1200
+++ squid-5.7/include/autoconf.h.in	2022-09-06 03:35:18.000000000 +1200
@@ -772,6 +772,9 @@
 /* Define to 1 if you have the <openssl/crypto.h> header file. */
 #undef HAVE_OPENSSL_CRYPTO_H
 
+/* Define to 1 if you have the <openssl/decoder.h> header file. */
+#undef HAVE_OPENSSL_DECODER_H
+
 /* Define to 1 if you have the <openssl/dh.h> header file. */
 #undef HAVE_OPENSSL_DH_H
 
diff -u -r -N squid-5.6/include/version.h squid-5.7/include/version.h
--- squid-5.6/include/version.h	2022-06-06 10:42:04.000000000 +1200
+++ squid-5.7/include/version.h	2022-09-06 03:35:26.000000000 +1200
@@ -7,7 +7,7 @@
  */
 
 #ifndef SQUID_RELEASE_TIME
-#define SQUID_RELEASE_TIME 1654468914
+#define SQUID_RELEASE_TIME 1662392113
 #endif
 
 /*
diff -u -r -N squid-5.6/lib/ntlmauth/ntlmauth.cc squid-5.7/lib/ntlmauth/ntlmauth.cc
--- squid-5.6/lib/ntlmauth/ntlmauth.cc	2022-06-06 10:11:52.000000000 +1200
+++ squid-5.7/lib/ntlmauth/ntlmauth.cc	2022-09-05 16:06:48.000000000 +1200
@@ -12,6 +12,7 @@
 #include "squid.h"
 
 #include <cstring>
+#include <ctime>
 #include <random>
 #if HAVE_STRINGS_H
 #include <strings.h>
@@ -107,10 +108,19 @@
     int32_t o = le32toh(str->offset);
     // debug("ntlm_fetch_string(plength=%d,l=%d,o=%d)\n",packet_size,l,o);
 
-    if (l < 0 || l > NTLM_MAX_FIELD_LENGTH || o + l > packet_size || o == 0) {
-        debug("ntlm_fetch_string: insane data (pkt-sz: %d, fetch len: %d, offset: %d)\n", packet_size,l,o);
+    if (l < 0 || l > NTLM_MAX_FIELD_LENGTH) {
+        debug("ntlm_fetch_string: insane string length (pkt-sz: %d, fetch len: %d, offset: %d)\n", packet_size,l,o);
         return rv;
     }
+    else if (o <= 0 || o > packet_size) {
+        debug("ntlm_fetch_string: insane string offset (pkt-sz: %d, fetch len: %d, offset: %d)\n", packet_size,l,o);
+        return rv;
+    }
+    else if (l > packet_size - o) {
+        debug("ntlm_fetch_string: truncated string data (pkt-sz: %d, fetch len: %d, offset: %d)\n", packet_size,l,o);
+        return rv;
+    }
+
     rv.str = (char *)packet + o;
     rv.l = 0;
     if ((flags & NTLM_NEGOTIATE_ASCII) == 0) {
diff -u -r -N squid-5.6/RELEASENOTES.html squid-5.7/RELEASENOTES.html
--- squid-5.6/RELEASENOTES.html	2022-06-06 10:47:28.000000000 +1200
+++ squid-5.7/RELEASENOTES.html	2022-09-06 03:40:52.000000000 +1200
@@ -3,10 +3,10 @@
 <HEAD>
  <META NAME="GENERATOR" CONTENT="LinuxDoc-Tools 0.9.82">
  <meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
- <TITLE>Squid 5.6 release notes</TITLE>
+ <TITLE>Squid 5.7 release notes</TITLE>
 </HEAD>
 <BODY>
-<H1>Squid 5.6 release notes</H1>
+<H1>Squid 5.7 release notes</H1>
 
 <H2>Squid Developers</H2>
 <HR>
@@ -31,6 +31,7 @@
 <LI><A NAME="toc2.4">2.4</A> <A HREF="#ss2.4">TrivialDB Support</A>
 <LI><A NAME="toc2.5">2.5</A> <A HREF="#ss2.5">Loop Detection in Content Delivery Networks</A>
 <LI><A NAME="toc2.6">2.6</A> <A HREF="#ss2.6">Peering support for SSL-Bump</A>
+<LI><A NAME="toc2.7">2.7</A> <A HREF="#ss2.7">OpenSSL 3.0 Support</A>
 </UL>
 <P>
 <H2><A NAME="toc3">3.</A> <A HREF="#s3">Changes to squid.conf since Squid-4</A></H2>
@@ -61,7 +62,7 @@
 <HR>
 <H2><A NAME="s1">1.</A> <A HREF="#toc1">Notice</A></H2>
 
-<P>The Squid Team are pleased to announce the release of Squid-5.6.</P>
+<P>The Squid Team are pleased to announce the release of Squid-5.7.</P>
 <P>This new release is available for download from 
 <A HREF="http://www.squid-cache.org/Versions/v5/">http://www.squid-cache.org/Versions/v5/</A> or the
 <A HREF="http://www.squid-cache.org/Download/http-mirrors.html">mirrors</A>.</P>
@@ -95,6 +96,7 @@
 <LI>TrivialDB Support</LI>
 <LI>RFC 8586: Loop Detection in Content Delivery Networks</LI>
 <LI>Peering support for SSL-Bump</LI>
+<LI>OpenSSL 3.0 Support</LI>
 </UL>
 </P>
 <P>Most user-facing changes are reflected in squid.conf (see below).</P>
@@ -220,6 +222,21 @@
 yet do TLS-in-TLS.</P>
 
 
+<H2><A NAME="ss2.7">2.7</A> <A HREF="#toc2.7">OpenSSL 3.0 Support</A>
+</H2>
+
+<P>Squid-5.7 adds OpenSSL 3.0 support.</P>
+
+<P>This version of Squid does not add any of the new features provided by
+OpenSSL 3.0. It only contains support for features already supported by prior
+versions of Squid using new APIs provided by OpenSSL 3.0.</P>
+
+<P>Notably the libssl custom Engine feature has been deprecated by OpenSSL 3.0
+and new Providers replacement is not supported by this Squid.</P>
+
+<P>OpenSSL 3.0 uses new licensing terms.</P>
+
+
 <H2><A NAME="s3">3.</A> <A HREF="#toc3">Changes to squid.conf since Squid-4</A></H2>
 
 <P>There have been changes to Squid's configuration file since Squid-4.</P>
@@ -364,6 +381,10 @@
 <P>Codes <EM>rm</EM>, <EM>&lt;rm</EM> and <EM>&gt;rm</EM> display "-"
 instead of the made-up method NONE.</P>
 
+<DT><B>ssl_engine</B><DD>
+<P>OpenSSL 3.0 deprecates the Engine feature. This directive is
+only supported when Squid is built for older OpenSSL versions.</P>
+
 </DL>
 </P>
 
diff -u -r -N squid-5.6/src/acl/external/delayer/ext_delayer_acl.8 squid-5.7/src/acl/external/delayer/ext_delayer_acl.8
--- squid-5.6/src/acl/external/delayer/ext_delayer_acl.8	2022-06-06 10:47:31.000000000 +1200
+++ squid-5.7/src/acl/external/delayer/ext_delayer_acl.8	2022-09-06 03:40:57.000000000 +1200
@@ -133,7 +133,7 @@
 .\" ========================================================================
 .\"
 .IX Title "EXT_DELAYER_ACL 8"
-.TH EXT_DELAYER_ACL 8 "2022-06-05" "perl v5.34.0" "User Contributed Perl Documentation"
+.TH EXT_DELAYER_ACL 8 "2022-09-05" "perl v5.34.0" "User Contributed Perl Documentation"
 .\" For nroff, turn off justification.  Always turn off hyphenation; it makes
 .\" way too many mistakes in technical documents.
 .if n .ad l
diff -u -r -N squid-5.6/src/acl/external/kerberos_sid_group/ext_kerberos_sid_group_acl.8 squid-5.7/src/acl/external/kerberos_sid_group/ext_kerberos_sid_group_acl.8
--- squid-5.6/src/acl/external/kerberos_sid_group/ext_kerberos_sid_group_acl.8	2022-06-06 10:47:31.000000000 +1200
+++ squid-5.7/src/acl/external/kerberos_sid_group/ext_kerberos_sid_group_acl.8	2022-09-06 03:40:58.000000000 +1200
@@ -133,7 +133,7 @@
 .\" ========================================================================
 .\"
 .IX Title "EXT_KERBEROS_SID_GROUP_ACL 8"
-.TH EXT_KERBEROS_SID_GROUP_ACL 8 "2022-06-05" "perl v5.34.0" "User Contributed Perl Documentation"
+.TH EXT_KERBEROS_SID_GROUP_ACL 8 "2022-09-05" "perl v5.34.0" "User Contributed Perl Documentation"
 .\" For nroff, turn off justification.  Always turn off hyphenation; it makes
 .\" way too many mistakes in technical documents.
 .if n .ad l
diff -u -r -N squid-5.6/src/acl/external/session/ext_session_acl.cc squid-5.7/src/acl/external/session/ext_session_acl.cc
--- squid-5.6/src/acl/external/session/ext_session_acl.cc	2022-06-06 10:11:52.000000000 +1200
+++ squid-5.7/src/acl/external/session/ext_session_acl.cc	2022-09-05 16:06:48.000000000 +1200
@@ -197,13 +197,19 @@
 static int session_active(const char *details, size_t len)
 {
 #if USE_BERKLEYDB
-    DBT key = {0};
-    DBT data = {0};
-    key.data = (void *)details;
+    DBT key = {};
+    key.data = const_cast<char*>(details);
     key.size = len;
+
+    DBT data = {};
 #elif USE_TRIVIALDB
-    TDB_DATA key;
-    TDB_DATA data;
+    TDB_DATA key = {};
+    key.dptr = reinterpret_cast<decltype(key.dptr)>(const_cast<char*>(details));
+    key.dsize = len;
+
+    TDB_DATA data = {};
+#else
+    (void)len;
 #endif
     if (fetchKey(key, &data)) {
         time_t timestamp;
diff -u -r -N squid-5.6/src/acl/external/SQL_session/ext_sql_session_acl.8 squid-5.7/src/acl/external/SQL_session/ext_sql_session_acl.8
--- squid-5.6/src/acl/external/SQL_session/ext_sql_session_acl.8	2022-06-06 10:47:31.000000000 +1200
+++ squid-5.7/src/acl/external/SQL_session/ext_sql_session_acl.8	2022-09-06 03:40:58.000000000 +1200
@@ -133,7 +133,7 @@
 .\" ========================================================================
 .\"
 .IX Title "EXT_SQL_SESSION_ACL 8"
-.TH EXT_SQL_SESSION_ACL 8 "2022-06-05" "perl v5.34.0" "User Contributed Perl Documentation"
+.TH EXT_SQL_SESSION_ACL 8 "2022-09-05" "perl v5.34.0" "User Contributed Perl Documentation"
 .\" For nroff, turn off justification.  Always turn off hyphenation; it makes
 .\" way too many mistakes in technical documents.
 .if n .ad l
diff -u -r -N squid-5.6/src/acl/external/wbinfo_group/ext_wbinfo_group_acl.8 squid-5.7/src/acl/external/wbinfo_group/ext_wbinfo_group_acl.8
--- squid-5.6/src/acl/external/wbinfo_group/ext_wbinfo_group_acl.8	2022-06-06 10:47:31.000000000 +1200
+++ squid-5.7/src/acl/external/wbinfo_group/ext_wbinfo_group_acl.8	2022-09-06 03:40:58.000000000 +1200
@@ -133,7 +133,7 @@
 .\" ========================================================================
 .\"
 .IX Title "EXT_WBINFO_GROUP_ACL 8"
-.TH EXT_WBINFO_GROUP_ACL 8 "2022-06-05" "perl v5.34.0" "User Contributed Perl Documentation"
+.TH EXT_WBINFO_GROUP_ACL 8 "2022-09-05" "perl v5.34.0" "User Contributed Perl Documentation"
 .\" For nroff, turn off justification.  Always turn off hyphenation; it makes
 .\" way too many mistakes in technical documents.
 .if n .ad l
diff -u -r -N squid-5.6/src/acl/RegexData.cc squid-5.7/src/acl/RegexData.cc
--- squid-5.6/src/acl/RegexData.cc	2022-06-06 10:11:52.000000000 +1200
+++ squid-5.7/src/acl/RegexData.cc	2022-09-05 16:06:48.000000000 +1200
@@ -83,6 +83,9 @@
 static const char *
 removeUnnecessaryWildcards(char * t)
 {
+    if (strcmp(t, ".*") == 0) // we cannot simplify that further
+        return t; // avoid "WARNING: ... Using '.*' instead" below
+
     char * orig = t;
 
     if (strncmp(t, "^.*", 3) == 0)
diff -u -r -N squid-5.6/src/auth/basic/DB/basic_db_auth.8 squid-5.7/src/auth/basic/DB/basic_db_auth.8
--- squid-5.6/src/auth/basic/DB/basic_db_auth.8	2022-06-06 10:47:32.000000000 +1200
+++ squid-5.7/src/auth/basic/DB/basic_db_auth.8	2022-09-06 03:40:59.000000000 +1200
@@ -133,7 +133,7 @@
 .\" ========================================================================
 .\"
 .IX Title "BASIC_DB_AUTH 8"
-.TH BASIC_DB_AUTH 8 "2022-06-05" "perl v5.34.0" "User Contributed Perl Documentation"
+.TH BASIC_DB_AUTH 8 "2022-09-05" "perl v5.34.0" "User Contributed Perl Documentation"
 .\" For nroff, turn off justification.  Always turn off hyphenation; it makes
 .\" way too many mistakes in technical documents.
 .if n .ad l
diff -u -r -N squid-5.6/src/auth/basic/POP3/basic_pop3_auth.8 squid-5.7/src/auth/basic/POP3/basic_pop3_auth.8
--- squid-5.6/src/auth/basic/POP3/basic_pop3_auth.8	2022-06-06 10:47:32.000000000 +1200
+++ squid-5.7/src/auth/basic/POP3/basic_pop3_auth.8	2022-09-06 03:40:59.000000000 +1200
@@ -133,7 +133,7 @@
 .\" ========================================================================
 .\"
 .IX Title "BASIC_POP3_AUTH 8"
-.TH BASIC_POP3_AUTH 8 "2022-06-05" "perl v5.34.0" "User Contributed Perl Documentation"
+.TH BASIC_POP3_AUTH 8 "2022-09-05" "perl v5.34.0" "User Contributed Perl Documentation"
 .\" For nroff, turn off justification.  Always turn off hyphenation; it makes
 .\" way too many mistakes in technical documents.
 .if n .ad l
diff -u -r -N squid-5.6/src/base/EnumIterator.h squid-5.7/src/base/EnumIterator.h
--- squid-5.6/src/base/EnumIterator.h	2022-06-06 10:11:52.000000000 +1200
+++ squid-5.7/src/base/EnumIterator.h	2022-09-05 16:06:48.000000000 +1200
@@ -20,7 +20,7 @@
  * \see EnumIterator, ReverseEnumIterator
  */
 template <typename EnumType>
-class EnumIteratorBase : public std::iterator<std::bidirectional_iterator_tag, EnumType>
+class EnumIteratorBase
 {
 protected:
 #if HAVE_STD_UNDERLYING_TYPE
@@ -30,6 +30,12 @@
 #endif
 
 public:
+    using iterator_category = std::bidirectional_iterator_tag;
+    using value_type = EnumType;
+    using difference_type = std::ptrdiff_t;
+    using pointer = EnumType *;
+    using reference = EnumType &;
+
     explicit EnumIteratorBase(EnumType e) : current(static_cast<iterator_type>(e)) {}
 
     bool operator==(const EnumIteratorBase &i) const {
diff -u -r -N squid-5.6/src/cache_cf.cc squid-5.7/src/cache_cf.cc
--- squid-5.6/src/cache_cf.cc	2022-06-06 10:11:52.000000000 +1200
+++ squid-5.7/src/cache_cf.cc	2022-09-05 16:06:48.000000000 +1200
@@ -720,7 +720,7 @@
      * the extra space is for loop detection in client_side.c -- we search
      * for substrings in the Via header.
      */
-    snprintf(ThisCache2, sizeof(ThisCache), " %s (%s)",
+    snprintf(ThisCache2, sizeof(ThisCache2), " %s (%s)",
              uniqueHostname(),
              visible_appname_string);
 
diff -u -r -N squid-5.6/src/cf.data.pre squid-5.7/src/cf.data.pre
--- squid-5.6/src/cf.data.pre	2022-06-06 10:11:52.000000000 +1200
+++ squid-5.7/src/cf.data.pre	2022-09-05 16:06:48.000000000 +1200
@@ -1036,7 +1036,7 @@
 DEFAULT: ssl::certSelfSigned ssl_error X509_V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT
 ENDIF
 DEFAULT: all src all
-DEFAULT: manager url_regex -i ^cache_object:// +i ^https?://[^/]+/squid-internal-mgr/
+DEFAULT: manager url_regex -i ^cache_object:// +i ^[^:]+://[^/]+/squid-internal-mgr/
 DEFAULT: localhost src 127.0.0.1/32 ::1
 DEFAULT: to_localhost dst 127.0.0.0/8 0.0.0.0/32 ::1/128 ::/128
 DEFAULT: CONNECT method CONNECT
@@ -3049,6 +3049,8 @@
 DOC_START
 	The OpenSSL engine to use. You will need to set this if you
 	would like to use hardware SSL acceleration for example.
+
+	Not supported in builds with OpenSSL 3.0 or newer.
 DOC_END
 
 NAME: sslproxy_session_ttl
@@ -4004,8 +4006,10 @@
 	For the purpose of this limit, Squid counts all high-level request
 	forwarding attempts, including any same-destination retries after
 	certain persistent connection failures and any attempts to use a
-	different peer. However, low-level connection reopening attempts
-	(enabled using connect_retries) are not counted.
+	different peer. However, these low-level attempts are not counted:
+	* connection reopening attempts (enabled using connect_retries)
+	* unfinished Happy Eyeballs connection attempts (prevented by setting
+	  happy_eyeballs_connect_limit to 0)
 
 	See also: forward_timeout and connect_retries.
 DOC_END
diff -u -r -N squid-5.6/src/cf_gen.cc squid-5.7/src/cf_gen.cc
--- squid-5.6/src/cf_gen.cc	2022-06-06 10:11:52.000000000 +1200
+++ squid-5.7/src/cf_gen.cc	2022-09-05 16:06:48.000000000 +1200
@@ -378,7 +378,6 @@
                 } else if (!strcmp(buff, "NOCOMMENT_START")) {
                     state = sNOCOMMENT;
                 } else { // if (buff != NULL) {
-                    assert(buff != NULL);
                     entries.back().doc.push_back(buff);
                 }
                 break;
@@ -387,7 +386,6 @@
                 if (!strcmp(buff, "NOCOMMENT_END")) {
                     state = sDOC;
                 } else { // if (buff != NULL) {
-                    assert(buff != NULL);
                     entries.back().nocomment.push_back(buff);
                 }
                 break;
diff -u -r -N squid-5.6/src/fs/ufs/RebuildState.cc squid-5.7/src/fs/ufs/RebuildState.cc
--- squid-5.6/src/fs/ufs/RebuildState.cc	2022-06-06 10:11:52.000000000 +1200
+++ squid-5.7/src/fs/ufs/RebuildState.cc	2022-09-05 16:06:48.000000000 +1200
@@ -44,8 +44,6 @@
     _done(false),
     cbdata(NULL)
 {
-    *fullpath = 0;
-    *fullfilename = 0;
 
     /*
      * If the swap.state file exists in the cache_dir, then
@@ -379,14 +377,14 @@
         }
 
         if (0 == in_dir) {  /* we need to read in a new directory */
-            snprintf(fullpath, sizeof(fullpath), "%s/%02X/%02X",
-                     sd->path,
-                     curlvl1, curlvl2);
+            fullpath.Printf("%s/%02X/%02X",
+                            sd->path,
+                            curlvl1, curlvl2);
 
             if (dirs_opened)
                 return -1;
 
-            td = opendir(fullpath);
+            td = opendir(fullpath.c_str());
 
             ++dirs_opened;
 
@@ -425,10 +423,10 @@
                 continue;
             }
 
-            snprintf(fullfilename, sizeof(fullfilename), "%s/%s",
-                     fullpath, entry->d_name);
-            debugs(47, 3, HERE << "Opening " << fullfilename);
-            fd = file_open(fullfilename, O_RDONLY | O_BINARY);
+            fullfilename.Printf(SQUIDSBUFPH "/%s",
+                                SQUIDSBUFPRINT(fullpath), entry->d_name);
+            debugs(47, 3, "Opening " << fullfilename);
+            fd = file_open(fullfilename.c_str(), O_RDONLY | O_BINARY);
 
             if (fd < 0) {
                 int xerrno = errno;
diff -u -r -N squid-5.6/src/fs/ufs/RebuildState.h squid-5.7/src/fs/ufs/RebuildState.h
--- squid-5.6/src/fs/ufs/RebuildState.h	2022-06-06 10:11:52.000000000 +1200
+++ squid-5.7/src/fs/ufs/RebuildState.h	2022-09-05 16:06:48.000000000 +1200
@@ -53,8 +53,8 @@
 
     dirent_t *entry;
     DIR *td;
-    char fullpath[MAXPATHLEN];
-    char fullfilename[MAXPATHLEN*2];
+    SBuf fullpath;
+    SBuf fullfilename;
 
     StoreRebuildData counts;
 
diff -u -r -N squid-5.6/src/FwdState.cc squid-5.7/src/FwdState.cc
--- squid-5.6/src/FwdState.cc	2022-06-06 10:11:52.000000000 +1200
+++ squid-5.7/src/FwdState.cc	2022-09-05 16:06:48.000000000 +1200
@@ -641,7 +641,6 @@
     if (transporting())
         return; // and continue to receive destinations for backup
 
-    // This is the first path candidate we have seen. Use it.
     useDestinations();
 }
 
@@ -657,12 +656,8 @@
             Must(!err); // if we tried to connect, then path selection succeeded
             fail(selectionError);
         }
-        else if (err)
-            debugs(17, 3, "Will abort forwarding because all found paths have failed.");
-        else
-            debugs(17, 3, "Will abort forwarding because path selection found no paths.");
 
-        useDestinations(); // will detect and handle the lack of paths
+        stopAndDestroy("path selection found no paths");
         return;
     }
     // else continue to use one of the previously noted destinations;
@@ -675,7 +670,16 @@
         return; // and continue to wait for FwdState::noteConnection() callback
     }
 
-    Must(transporting()); // or we would be stuck with nothing to do or wait for
+    if (transporting()) {
+        // We are already using a previously opened connection (but were also
+        // receiving more destinations in case we need to re-forward).
+        debugs(17, 7, "keep transporting");
+        return;
+    }
+
+    // destinationsFound, but none of them worked, and we were waiting for more
+    assert(err);
+    stopAndDestroy("all found paths have failed");
 }
 
 /// makes sure connection opener knows that the destinations have changed
diff -u -r -N squid-5.6/src/HappyConnOpener.cc squid-5.7/src/HappyConnOpener.cc
--- squid-5.6/src/HappyConnOpener.cc	2022-06-06 10:11:52.000000000 +1200
+++ squid-5.7/src/HappyConnOpener.cc	2022-09-05 16:06:48.000000000 +1200
@@ -568,8 +568,6 @@
     const auto conn = dest->cloneProfile();
     GetMarkingsToServer(cause.getRaw(), *conn);
 
-    ++n_tries;
-
     typedef CommCbMemFunT<HappyConnOpener, CommConnectCbParams> Dialer;
     AsyncCall::Pointer callConnect = asyncCall(48, 5, attempt.callbackMethodName,
                                      Dialer(this, attempt.callbackMethod));
@@ -611,6 +609,8 @@
     handledPath.finalize(params.conn); // closed on errors
     attempt.finish();
 
+    ++n_tries;
+
     if (params.flag == Comm::OK) {
         sendSuccess(handledPath, false, what);
         return;
diff -u -r -N squid-5.6/src/HappyConnOpener.h squid-5.7/src/HappyConnOpener.h
--- squid-5.6/src/HappyConnOpener.h	2022-06-06 10:11:52.000000000 +1200
+++ squid-5.7/src/HappyConnOpener.h	2022-09-05 16:06:48.000000000 +1200
@@ -258,7 +258,8 @@
     /// the request that needs a to-server connection
     HttpRequestPointer cause;
 
-    /// number of connection opening attempts, including those in the requestor
+    /// number of our finished connection opening attempts (including pconn
+    /// reuses) plus previously finished attempts supplied by the requestor
     int n_tries;
 
     /// Reason to ran out of time or attempts
diff -u -r -N squid-5.6/src/http/url_rewriters/LFS/url_lfs_rewrite.8 squid-5.7/src/http/url_rewriters/LFS/url_lfs_rewrite.8
--- squid-5.6/src/http/url_rewriters/LFS/url_lfs_rewrite.8	2022-06-06 10:47:32.000000000 +1200
+++ squid-5.7/src/http/url_rewriters/LFS/url_lfs_rewrite.8	2022-09-06 03:41:00.000000000 +1200
@@ -133,7 +133,7 @@
 .\" ========================================================================
 .\"
 .IX Title "URL_LFS_REWRITE 8"
-.TH URL_LFS_REWRITE 8 "2022-06-05" "perl v5.34.0" "User Contributed Perl Documentation"
+.TH URL_LFS_REWRITE 8 "2022-09-05" "perl v5.34.0" "User Contributed Perl Documentation"
 .\" For nroff, turn off justification.  Always turn off hyphenation; it makes
 .\" way too many mistakes in technical documents.
 .if n .ad l
diff -u -r -N squid-5.6/src/HttpHeaderTools.h squid-5.7/src/HttpHeaderTools.h
--- squid-5.6/src/HttpHeaderTools.h	2022-06-06 10:11:52.000000000 +1200
+++ squid-5.7/src/HttpHeaderTools.h	2022-09-05 16:06:48.000000000 +1200
@@ -67,7 +67,7 @@
 private:
     /// Case-insensitive std::string "less than" comparison functor.
     /// Fast version recommended by Meyers' "Effective STL" for ASCII c-strings.
-    class NoCaseLessThan: public std::binary_function<std::string, std::string, bool>
+    class NoCaseLessThan
     {
     public:
         bool operator()(const std::string &lhs, const std::string &rhs) const {
diff -u -r -N squid-5.6/src/log/DB/log_db_daemon.8 squid-5.7/src/log/DB/log_db_daemon.8
--- squid-5.6/src/log/DB/log_db_daemon.8	2022-06-06 10:47:33.000000000 +1200
+++ squid-5.7/src/log/DB/log_db_daemon.8	2022-09-06 03:41:00.000000000 +1200
@@ -133,7 +133,7 @@
 .\" ========================================================================
 .\"
 .IX Title "LOG_DB_DAEMON 8"
-.TH LOG_DB_DAEMON 8 "2022-06-05" "perl v5.34.0" "User Contributed Perl Documentation"
+.TH LOG_DB_DAEMON 8 "2022-09-05" "perl v5.34.0" "User Contributed Perl Documentation"
 .\" For nroff, turn off justification.  Always turn off hyphenation; it makes
 .\" way too many mistakes in technical documents.
 .if n .ad l
diff -u -r -N squid-5.6/src/main.cc squid-5.7/src/main.cc
--- squid-5.6/src/main.cc	2022-06-06 10:11:52.000000000 +1200
+++ squid-5.7/src/main.cc	2022-09-05 16:06:48.000000000 +1200
@@ -679,8 +679,10 @@
             printf("%s\n",SQUID_BUILD_INFO);
 #if USE_OPENSSL
         printf("\nThis binary uses %s. ", OpenSSL_version(OPENSSL_VERSION));
+#if OPENSSL_VERSION_MAJOR < 3
         printf("For legal restrictions on distribution see https://www.openssl.org/source/license.html\n\n");
 #endif
+#endif
         printf( "configure options: %s\n", SQUID_CONFIGURE_OPTIONS);
 
 #if USE_WIN32_SERVICE
diff -u -r -N squid-5.6/src/sbuf/SBuf.h squid-5.7/src/sbuf/SBuf.h
--- squid-5.6/src/sbuf/SBuf.h	2022-06-06 10:11:52.000000000 +1200
+++ squid-5.7/src/sbuf/SBuf.h	2022-09-05 16:06:48.000000000 +1200
@@ -45,9 +45,16 @@
  * Please note that any operation on the underlying SBuf may invalidate
  * all iterators over it, resulting in undefined behavior by them.
  */
-class SBufIterator : public std::iterator<std::input_iterator_tag, char>
+class SBufIterator
 {
 public:
+    // iterator traits
+    using iterator_category = std::input_iterator_tag;
+    using value_type = char;
+    using difference_type = std::ptrdiff_t;
+    using pointer = char*;
+    using reference = char&;
+
     friend class SBuf;
     typedef MemBlob::size_type size_type;
     bool operator==(const SBufIterator &s) const;
diff -u -r -N squid-5.6/src/security/cert_validators/fake/security_fake_certverify.8 squid-5.7/src/security/cert_validators/fake/security_fake_certverify.8
--- squid-5.6/src/security/cert_validators/fake/security_fake_certverify.8	2022-06-06 10:47:33.000000000 +1200
+++ squid-5.7/src/security/cert_validators/fake/security_fake_certverify.8	2022-09-06 03:41:00.000000000 +1200
@@ -133,7 +133,7 @@
 .\" ========================================================================
 .\"
 .IX Title "SECURITY_FAKE_CERTVERIFY 8"
-.TH SECURITY_FAKE_CERTVERIFY 8 "2022-06-05" "perl v5.34.0" "User Contributed Perl Documentation"
+.TH SECURITY_FAKE_CERTVERIFY 8 "2022-09-05" "perl v5.34.0" "User Contributed Perl Documentation"
 .\" For nroff, turn off justification.  Always turn off hyphenation; it makes
 .\" way too many mistakes in technical documents.
 .if n .ad l
diff -u -r -N squid-5.6/src/security/forward.h squid-5.7/src/security/forward.h
--- squid-5.6/src/security/forward.h	2022-06-06 10:11:52.000000000 +1200
+++ squid-5.7/src/security/forward.h	2022-09-05 16:06:48.000000000 +1200
@@ -93,10 +93,25 @@
 typedef std::list<Security::CrlPointer> CertRevokeList;
 
 #if USE_OPENSSL
+CtoCpp1(EVP_PKEY_free, EVP_PKEY *)
+using PrivateKeyPointer = Security::LockingPointer<EVP_PKEY, EVP_PKEY_free_cpp, HardFun<int, EVP_PKEY *, EVP_PKEY_up_ref>>;
+#elif USE_GNUTLS
+using PrivateKeyPointer = std::shared_ptr<struct gnutls_x509_privkey_int>;
+#else
+using PrivateKeyPointer = std::shared_ptr<void>;
+#endif
+
+#if USE_OPENSSL
+#if OPENSSL_VERSION_MAJOR < 3
 CtoCpp1(DH_free, DH *);
 typedef Security::LockingPointer<DH, DH_free_cpp, HardFun<int, DH *, DH_up_ref> > DhePointer;
 #else
-typedef void *DhePointer;
+using DhePointer = PrivateKeyPointer;
+#endif
+#elif USE_GNUTLS
+using DhePointer = void *;
+#else
+using DhePointer = void *;
 #endif
 
 class EncryptorAnswer;
@@ -159,7 +174,7 @@
 class KeyData;
 
 #if USE_OPENSSL
-typedef long ParsedOptions;
+using ParsedOptions = uint64_t;
 #elif USE_GNUTLS
 typedef std::shared_ptr<struct gnutls_priority_st> ParsedOptions;
 #else
@@ -175,15 +190,6 @@
 class BlindPeerConnector;
 class PeerOptions;
 
-#if USE_OPENSSL
-CtoCpp1(EVP_PKEY_free, EVP_PKEY *)
-typedef Security::LockingPointer<EVP_PKEY, EVP_PKEY_free_cpp, HardFun<int, EVP_PKEY *, EVP_PKEY_up_ref> > PrivateKeyPointer;
-#elif USE_GNUTLS
-typedef std::shared_ptr<struct gnutls_x509_privkey_int> PrivateKeyPointer;
-#else
-typedef std::shared_ptr<void> PrivateKeyPointer;
-#endif
-
 class ServerOptions;
 
 class ErrorDetail;
diff -u -r -N squid-5.6/src/security/PeerOptions.cc squid-5.7/src/security/PeerOptions.cc
--- squid-5.6/src/security/PeerOptions.cc	2022-06-06 10:11:52.000000000 +1200
+++ squid-5.7/src/security/PeerOptions.cc	2022-09-05 16:06:48.000000000 +1200
@@ -293,134 +293,134 @@
 /// set of options we can parse and what they map to
 static struct ssl_option {
     const char *name;
-    long value;
+    Security::ParsedOptions value;
 
 } ssl_options[] = {
 
-#if SSL_OP_NETSCAPE_REUSE_CIPHER_CHANGE_BUG
+#if defined(SSL_OP_NETSCAPE_REUSE_CIPHER_CHANGE_BUG)
     {
         "NETSCAPE_REUSE_CIPHER_CHANGE_BUG", SSL_OP_NETSCAPE_REUSE_CIPHER_CHANGE_BUG
     },
 #endif
-#if SSL_OP_SSLREF2_REUSE_CERT_TYPE_BUG
+#if defined(SSL_OP_SSLREF2_REUSE_CERT_TYPE_BUG)
     {
         "SSLREF2_REUSE_CERT_TYPE_BUG", SSL_OP_SSLREF2_REUSE_CERT_TYPE_BUG
     },
 #endif
-#if SSL_OP_MICROSOFT_BIG_SSLV3_BUFFER
+#if defined(SSL_OP_MICROSOFT_BIG_SSLV3_BUFFER)
     {
         "MICROSOFT_BIG_SSLV3_BUFFER", SSL_OP_MICROSOFT_BIG_SSLV3_BUFFER
     },
 #endif
-#if SSL_OP_SSLEAY_080_CLIENT_DH_BUG
+#if defined(SSL_OP_SSLEAY_080_CLIENT_DH_BUG)
     {
         "SSLEAY_080_CLIENT_DH_BUG", SSL_OP_SSLEAY_080_CLIENT_DH_BUG
     },
 #endif
-#if SSL_OP_TLS_D5_BUG
+#if defined(SSL_OP_TLS_D5_BUG)
     {
         "TLS_D5_BUG", SSL_OP_TLS_D5_BUG
     },
 #endif
-#if SSL_OP_TLS_BLOCK_PADDING_BUG
+#if defined(SSL_OP_TLS_BLOCK_PADDING_BUG)
     {
         "TLS_BLOCK_PADDING_BUG", SSL_OP_TLS_BLOCK_PADDING_BUG
     },
 #endif
-#if SSL_OP_TLS_ROLLBACK_BUG
+#if defined(SSL_OP_TLS_ROLLBACK_BUG)
     {
         "TLS_ROLLBACK_BUG", SSL_OP_TLS_ROLLBACK_BUG
     },
 #endif
-#if SSL_OP_ALL
+#if defined(SSL_OP_ALL)
     {
-        "ALL", (long)SSL_OP_ALL
+        "ALL", SSL_OP_ALL
     },
 #endif
-#if SSL_OP_SINGLE_DH_USE
+#if defined(SSL_OP_SINGLE_DH_USE)
     {
         "SINGLE_DH_USE", SSL_OP_SINGLE_DH_USE
     },
 #endif
-#if SSL_OP_EPHEMERAL_RSA
+#if defined(SSL_OP_EPHEMERAL_RSA)
     {
         "EPHEMERAL_RSA", SSL_OP_EPHEMERAL_RSA
     },
 #endif
-#if SSL_OP_PKCS1_CHECK_1
+#if defined(SSL_OP_PKCS1_CHECK_1)
     {
         "PKCS1_CHECK_1", SSL_OP_PKCS1_CHECK_1
     },
 #endif
-#if SSL_OP_PKCS1_CHECK_2
+#if defined(SSL_OP_PKCS1_CHECK_2)
     {
         "PKCS1_CHECK_2", SSL_OP_PKCS1_CHECK_2
     },
 #endif
-#if SSL_OP_NETSCAPE_CA_DN_BUG
+#if defined(SSL_OP_NETSCAPE_CA_DN_BUG)
     {
         "NETSCAPE_CA_DN_BUG", SSL_OP_NETSCAPE_CA_DN_BUG
     },
 #endif
-#if SSL_OP_NON_EXPORT_FIRST
+#if defined(SSL_OP_NON_EXPORT_FIRST)
     {
         "NON_EXPORT_FIRST", SSL_OP_NON_EXPORT_FIRST
     },
 #endif
-#if SSL_OP_CIPHER_SERVER_PREFERENCE
+#if defined(SSL_OP_CIPHER_SERVER_PREFERENCE)
     {
         "CIPHER_SERVER_PREFERENCE", SSL_OP_CIPHER_SERVER_PREFERENCE
     },
 #endif
-#if SSL_OP_NETSCAPE_DEMO_CIPHER_CHANGE_BUG
+#if defined(SSL_OP_NETSCAPE_DEMO_CIPHER_CHANGE_BUG)
     {
         "NETSCAPE_DEMO_CIPHER_CHANGE_BUG", SSL_OP_NETSCAPE_DEMO_CIPHER_CHANGE_BUG
     },
 #endif
-#if SSL_OP_NO_SSLv3
+#if defined(SSL_OP_NO_SSLv3)
     {
         "NO_SSLv3", SSL_OP_NO_SSLv3
     },
 #endif
-#if SSL_OP_NO_TLSv1
+#if defined(SSL_OP_NO_TLSv1)
     {
         "NO_TLSv1", SSL_OP_NO_TLSv1
     },
 #else
     { "NO_TLSv1", 0 },
 #endif
-#if SSL_OP_NO_TLSv1_1
+#if defined(SSL_OP_NO_TLSv1_1)
     {
         "NO_TLSv1_1", SSL_OP_NO_TLSv1_1
     },
 #else
     { "NO_TLSv1_1", 0 },
 #endif
-#if SSL_OP_NO_TLSv1_2
+#if defined(SSL_OP_NO_TLSv1_2)
     {
         "NO_TLSv1_2", SSL_OP_NO_TLSv1_2
     },
 #else
     { "NO_TLSv1_2", 0 },
 #endif
-#if SSL_OP_NO_TLSv1_3
+#if defined(SSL_OP_NO_TLSv1_3)
     {
         "NO_TLSv1_3", SSL_OP_NO_TLSv1_3
     },
 #else
     { "NO_TLSv1_3", 0 },
 #endif
-#if SSL_OP_NO_COMPRESSION
+#if defined(SSL_OP_NO_COMPRESSION)
     {
         "No_Compression", SSL_OP_NO_COMPRESSION
     },
 #endif
-#if SSL_OP_NO_TICKET
+#if defined(SSL_OP_NO_TICKET)
     {
         "NO_TICKET", SSL_OP_NO_TICKET
     },
 #endif
-#if SSL_OP_SINGLE_ECDH_USE
+#if defined(SSL_OP_SINGLE_ECDH_USE)
     {
         "SINGLE_ECDH_USE", SSL_OP_SINGLE_ECDH_USE
     },
@@ -455,7 +455,7 @@
 
 #if USE_OPENSSL
     ::Parser::Tokenizer tok(str);
-    long op = 0;
+    ParsedOptions op = 0;
 
     while (!tok.atEnd()) {
         enum {
@@ -472,7 +472,8 @@
         static const CharacterSet optChars = CharacterSet("TLS-option", "_") + CharacterSet::ALPHA + CharacterSet::DIGIT;
         int64_t hex = 0;
         SBuf option;
-        long value = 0;
+        ParsedOptions value = 0;
+        bool found = false;
 
         // Bug 4429: identify the full option name before determining text or numeric
         if (tok.prefix(option, optChars)) {
@@ -481,14 +482,16 @@
             for (struct ssl_option *opttmp = ssl_options; opttmp->name; ++opttmp) {
                 if (option.cmp(opttmp->name) == 0) {
                     value = opttmp->value;
+                    found = true;
                     break;
                 }
             }
 
             // Special case.. hex specification
             ::Parser::Tokenizer tmp(option);
-            if (!value && tmp.int64(hex, 16, false) && tmp.atEnd()) {
+            if (!found && tmp.int64(hex, 16, false) && tmp.atEnd()) {
                 value = hex;
+                found = true;
             }
         }
 
@@ -502,7 +505,7 @@
                 break;
             }
         } else {
-            debugs(83, DBG_PARSE_NOTE(1), "ERROR: Unknown TLS option " << option);
+            debugs(83, DBG_PARSE_NOTE(DBG_IMPORTANT), "ERROR: " << (found?"Unsupported":"Unknown") << " TLS option " << option);
         }
 
         static const CharacterSet delims("TLS-option-delim",":,");
@@ -512,9 +515,10 @@
 
     }
 
-#if SSL_OP_NO_SSLv2
+#if defined(SSL_OP_NO_SSLv2)
     // compliance with RFC 6176: Prohibiting Secure Sockets Layer (SSL) Version 2.0
-    op = op | SSL_OP_NO_SSLv2;
+    if (SSL_OP_NO_SSLv2)
+        op |= SSL_OP_NO_SSLv2;
 #endif
     parsedOptions = op;
 
diff -u -r -N squid-5.6/src/security/ServerOptions.cc squid-5.7/src/security/ServerOptions.cc
--- squid-5.6/src/security/ServerOptions.cc	2022-06-06 10:11:52.000000000 +1200
+++ squid-5.7/src/security/ServerOptions.cc	2022-09-05 16:06:48.000000000 +1200
@@ -10,8 +10,10 @@
 #include "anyp/PortCfg.h"
 #include "base/Packable.h"
 #include "cache_cf.h"
+#include "error/SysErrorDetail.h"
 #include "fatal.h"
 #include "globals.h"
+#include "security/Io.h"
 #include "security/ServerOptions.h"
 #include "security/Session.h"
 #include "SquidConfig.h"
@@ -19,6 +21,9 @@
 #include "compat/openssl.h"
 #include "ssl/support.h"
 
+#if HAVE_OPENSSL_DECODER_H
+#include <openssl/decoder.h>
+#endif
 #if HAVE_OPENSSL_ERR_H
 #include <openssl/err.h>
 #endif
@@ -352,11 +357,20 @@
     if (dhParamsFile.isEmpty())
         return;
 
+    // TODO: After loading and validating parameters, also validate that "the
+    // public and private components have the correct mathematical
+    // relationship". See EVP_PKEY_check().
+
 #if USE_OPENSSL
+#if OPENSSL_VERSION_MAJOR < 3
     DH *dhp = nullptr;
     if (FILE *in = fopen(dhParamsFile.c_str(), "r")) {
         dhp = PEM_read_DHparams(in, NULL, NULL, NULL);
         fclose(in);
+    } else {
+        const auto xerrno = errno;
+        debugs(83, DBG_IMPORTANT, "WARNING: Failed to open '" << dhParamsFile << "'" << xstrerr(xerrno));
+        return;
     }
 
     if (!dhp) {
@@ -374,7 +388,73 @@
     }
 
     parsedDhParams.resetWithoutLocking(dhp);
+
+#else // OpenSSL 3.0+
+    const auto type = eecdhCurve.isEmpty() ? "DH" : "EC";
+
+    Security::ForgetErrors();
+    EVP_PKEY *rawPkey = nullptr;
+    using DecoderContext = std::unique_ptr<OSSL_DECODER_CTX, HardFun<void, OSSL_DECODER_CTX*, &OSSL_DECODER_CTX_free> >;
+    if (const DecoderContext dctx{OSSL_DECODER_CTX_new_for_pkey(&rawPkey, "PEM", nullptr, type, 0, nullptr, nullptr)}) {
+
+        // OpenSSL documentation is vague on this, but OpenSSL code and our
+        // tests suggest that rawPkey remains nil here while rawCtx keeps
+        // rawPkey _address_ for use by the decoder (see OSSL_DECODER_from_fp()
+        // below). Thus, we must not move *rawPkey into a smart pointer until
+        // decoding is over. For cleanup code simplicity, we assert nil rawPkey.
+        assert(!rawPkey);
+
+        if (OSSL_DECODER_CTX_get_num_decoders(dctx.get()) == 0) {
+            auto ssl_error = ERR_get_error();
+            debugs(83, DBG_IMPORTANT, "WARNING: No suitable decoders found for " << type << " parameters. " << Security::ErrorString(ssl_error));
+            return;
+        }
+
+        if (const auto in = fopen(dhParamsFile.c_str(), "r")) {
+            if (OSSL_DECODER_from_fp(dctx.get(), in)) {
+                assert(rawPkey);
+                const Security::DhePointer pkey(rawPkey);
+                // TODO: verify that the loaded parameters match the curve named in eecdhCurve
+
+                if (const Ssl::EVP_PKEY_CTX_Pointer pkeyCtx{EVP_PKEY_CTX_new_from_pkey(nullptr, pkey.get(), nullptr)}) {
+                    switch (EVP_PKEY_param_check(pkeyCtx.get())) {
+                    case 1: // success
+                        parsedDhParams = pkey;
+                        break;
+                    case -2: {
+                        auto ssl_error = ERR_get_error();
+                        debugs(83, DBG_PARSE_NOTE(2), "WARNING: OpenSSL does not support " << type << " parameters check: " << dhParamsFile << ". " << Security::ErrorString(ssl_error));
+                    }
+                    break;
+                    default: {
+                        auto ssl_error = ERR_get_error();
+                        debugs(83, DBG_IMPORTANT, "ERROR: Failed to verify " << type << " parameters in " << dhParamsFile << ". " << Security::ErrorString(ssl_error));
+                    }
+                    break;
+                    }
+                } else {
+                    // TODO: Reduce error reporting code duplication.
+                    auto ssl_error = ERR_get_error();
+                    debugs(83, DBG_IMPORTANT, "ERROR: Cannot check " << type << " parameters in " << dhParamsFile << ". " << Security::ErrorString(ssl_error));
+                }
+            } else {
+                auto ssl_error = ERR_get_error();
+                debugs(83, DBG_IMPORTANT, "WARNING: Failed to decode " << type << " parameters '" << dhParamsFile << "'. " << Security::ErrorString(ssl_error));
+                EVP_PKEY_free(rawPkey); // probably still nil, but just in case
+            }
+            fclose(in);
+        } else {
+            const auto xerrno = errno;
+            debugs(83, DBG_IMPORTANT, "WARNING: Failed to open '" << dhParamsFile << "'" << xstrerr(xerrno));
+        }
+
+    } else {
+        auto ssl_error = ERR_get_error();
+        debugs(83, DBG_IMPORTANT, "WARNING: Unable to create decode context for " << type << " parameters. " << Security::ErrorString(ssl_error));
+        return;
+    }
 #endif
+#endif // USE_OPENSSL
 }
 
 bool
@@ -452,12 +532,16 @@
         debugs(83, 9, "Setting Ephemeral ECDH curve to " << eecdhCurve << ".");
 
 #if USE_OPENSSL && OPENSSL_VERSION_NUMBER >= 0x0090800fL && !defined(OPENSSL_NO_ECDH)
+
+        Security::ForgetErrors();
+
         int nid = OBJ_sn2nid(eecdhCurve.c_str());
         if (!nid) {
             debugs(83, DBG_CRITICAL, "ERROR: Unknown EECDH curve '" << eecdhCurve << "'");
             return;
         }
 
+#if OPENSSL_VERSION_MAJOR < 3
         auto ecdh = EC_KEY_new_by_curve_name(nid);
         if (!ecdh) {
             const auto x = ERR_get_error();
@@ -472,6 +556,14 @@
         EC_KEY_free(ecdh);
 
 #else
+        // TODO: Support multiple group names via SSL_CTX_set1_groups_list().
+        if (!SSL_CTX_set1_groups(ctx.get(), &nid, 1)) {
+            auto ssl_error = ERR_get_error();
+            debugs(83, DBG_CRITICAL, "ERROR: Unable to set Ephemeral ECDH: " << Security::ErrorString(ssl_error));
+            return;
+        }
+#endif
+#else
         debugs(83, DBG_CRITICAL, "ERROR: EECDH is not available in this build." <<
                " Please link against OpenSSL>=0.9.8 and ensure OPENSSL_NO_ECDH is not set.");
 #endif
diff -u -r -N squid-5.6/src/ssl/gadgets.cc squid-5.7/src/ssl/gadgets.cc
--- squid-5.6/src/ssl/gadgets.cc	2022-06-06 10:11:52.000000000 +1200
+++ squid-5.7/src/ssl/gadgets.cc	2022-09-05 16:06:48.000000000 +1200
@@ -9,36 +9,26 @@
 #include "squid.h"
 #include "ssl/gadgets.h"
 
-EVP_PKEY * Ssl::createSslPrivateKey()
+static Security::PrivateKeyPointer
+CreateRsaPrivateKey()
 {
-    Security::PrivateKeyPointer pkey(EVP_PKEY_new());
-
-    if (!pkey)
-        return NULL;
-
-    BIGNUM_Pointer bn(BN_new());
-    if (!bn)
-        return NULL;
-
-    if (!BN_set_word(bn.get(), RSA_F4))
-        return NULL;
-
-    Ssl::RSA_Pointer rsa(RSA_new());
+    Ssl::EVP_PKEY_CTX_Pointer rsa(EVP_PKEY_CTX_new_id(EVP_PKEY_RSA, nullptr));
     if (!rsa)
-        return NULL;
+        return nullptr;
 
-    int num = 2048; // Maybe use 4096 RSA keys, or better make it configurable?
-    if (!RSA_generate_key_ex(rsa.get(), num, bn.get(), NULL))
-        return NULL;
+    if (EVP_PKEY_keygen_init(rsa.get()) <= 0)
+        return nullptr;
 
-    if (!rsa)
-        return NULL;
+    int num = 2048; // Maybe use 4096 RSA keys, or better make it configurable?
+    if (EVP_PKEY_CTX_set_rsa_keygen_bits(rsa.get(), num) <= 0)
+        return nullptr;
 
-    if (!EVP_PKEY_assign_RSA(pkey.get(), (rsa.get())))
-        return NULL;
+    /* Generate key */
+    EVP_PKEY *pkey = nullptr;
+    if (EVP_PKEY_keygen(rsa.get(), &pkey) <= 0)
+        return nullptr;
 
-    rsa.release();
-    return pkey.release();
+    return Security::PrivateKeyPointer(pkey);
 }
 
 /**
@@ -56,7 +46,7 @@
         if (!bn)
             return false;
 
-        if (!BN_pseudo_rand(bn.get(), 64, 0, 0))
+        if (!BN_rand(bn.get(), 64, 0, 0))
             return false;
     }
 
@@ -375,7 +365,11 @@
     // XXX: Add PublicKeyPointer. In OpenSSL, public and private keys are
     // internally represented by EVP_PKEY pair, but GnuTLS uses distinct types.
     const Security::PrivateKeyPointer certKey(X509_get_pubkey(mimicCert.get()));
+#if OPENSSL_VERSION_MAJOR < 3
     const auto rsaPkey = EVP_PKEY_get0_RSA(certKey.get()) != nullptr;
+#else
+    const auto rsaPkey = EVP_PKEY_is_a(certKey.get(), "RSA") == 1;
+#endif
 
     int added = 0;
     int nid;
@@ -544,13 +538,8 @@
 
 static bool generateFakeSslCertificate(Security::CertPointer & certToStore, Security::PrivateKeyPointer & pkeyToStore, Ssl::CertificateProperties const &properties,  Ssl::BIGNUM_Pointer const &serial)
 {
-    Security::PrivateKeyPointer pkey;
     // Use signing certificates private key as generated certificate private key
-    if (properties.signWithPkey.get())
-        pkey.resetAndLock(properties.signWithPkey.get());
-    else // if not exist generate one
-        pkey.resetWithoutLocking(Ssl::createSslPrivateKey());
-
+    const auto pkey = properties.signWithPkey ? properties.signWithPkey : CreateRsaPrivateKey();
     if (!pkey)
         return false;
 
diff -u -r -N squid-5.6/src/ssl/gadgets.h squid-5.7/src/ssl/gadgets.h
--- squid-5.6/src/ssl/gadgets.h	2022-06-06 10:11:52.000000000 +1200
+++ squid-5.7/src/ssl/gadgets.h	2022-09-05 16:06:48.000000000 +1200
@@ -58,7 +58,7 @@
 
 typedef std::unique_ptr<X509_NAME, HardFun<void, X509_NAME*, &X509_NAME_free>> X509_NAME_Pointer;
 
-typedef std::unique_ptr<RSA, HardFun<void, RSA*, &RSA_free>> RSA_Pointer;
+using EVP_PKEY_CTX_Pointer = std::unique_ptr<EVP_PKEY_CTX, HardFun<void, EVP_PKEY_CTX*, &EVP_PKEY_CTX_free>>;
 
 typedef std::unique_ptr<X509_REQ, HardFun<void, X509_REQ*, &X509_REQ_free>> X509_REQ_Pointer;
 
@@ -74,12 +74,6 @@
 typedef std::unique_ptr<X509_STORE_CTX, HardFun<void, X509_STORE_CTX *, &X509_STORE_CTX_free>> X509_STORE_CTX_Pointer;
 /**
  \ingroup SslCrtdSslAPI
- * Create 1024 bits rsa key.
- */
-EVP_PKEY * createSslPrivateKey();
-
-/**
- \ingroup SslCrtdSslAPI
  * Write private key and SSL certificate to memory.
  */
 bool writeCertAndPrivateKeyToMemory(Security::CertPointer const & cert, Security::PrivateKeyPointer const & pkey, std::string & bufferToWrite);
diff -u -r -N squid-5.6/src/ssl/support.cc squid-5.7/src/ssl/support.cc
--- squid-5.6/src/ssl/support.cc	2022-06-06 10:11:52.000000000 +1200
+++ squid-5.7/src/ssl/support.cc	2022-09-05 16:06:48.000000000 +1200
@@ -557,7 +557,11 @@
 }
 
 // "dup" function for SSL_get_ex_new_index("cert_err_check")
-#if SQUID_USE_CONST_CRYPTO_EX_DATA_DUP
+#if OPENSSL_VERSION_MAJOR >= 3
+static int
+ssl_dupAclChecklist(CRYPTO_EX_DATA *, const CRYPTO_EX_DATA *, void **,
+                    int, long, void *)
+#elif SQUID_USE_CONST_CRYPTO_EX_DATA_DUP
 static int
 ssl_dupAclChecklist(CRYPTO_EX_DATA *, const CRYPTO_EX_DATA *, void *,
                     int, long, void *)
@@ -654,8 +658,12 @@
 
     SQUID_OPENSSL_init_ssl();
 
-#if !defined(OPENSSL_NO_ENGINE)
     if (::Config.SSL.ssl_engine) {
+#if OPENSSL_VERSION_MAJOR < 3
+        debugs(83, DBG_PARSE_NOTE(DBG_IMPORTANT), "WARNING: Support for ssl_engine is deprecated " <<
+               "in Squids built with OpenSSL 1.x (like this Squid). " <<
+               "It is removed in Squids built with OpenSSL 3.0 or newer.");
+#if !defined(OPENSSL_NO_ENGINE)
         ENGINE_load_builtin_engines();
         ENGINE *e;
         if (!(e = ENGINE_by_id(::Config.SSL.ssl_engine)))
@@ -665,11 +673,14 @@
             const auto ssl_error = ERR_get_error();
             fatalf("Failed to initialise SSL engine: %s\n", Security::ErrorString(ssl_error));
         }
-    }
-#else
-    if (::Config.SSL.ssl_engine)
-        fatalf("Your OpenSSL has no SSL engine support\n");
+#else /* OPENSSL_NO_ENGINE */
+        throw TextException("Cannot use ssl_engine in Squid built with OpenSSL configured to disable SSL engine support", Here());
+#endif
+
+#else /* OPENSSL_VERSION_MAJOR */
+        throw TextException("Cannot use ssl_engine in Squid built with OpenSSL 3.0 or newer", Here());
 #endif
+    }
 
     const char *defName = ::Config.SSL.certSignHash ? ::Config.SSL.certSignHash : SQUID_SSL_SIGN_HASH_IF_NONE;
     Ssl::DefaultSignHash = EVP_get_digestbyname(defName);
diff -u -r -N squid-5.6/src/store/id_rewriters/file/storeid_file_rewrite.8 squid-5.7/src/store/id_rewriters/file/storeid_file_rewrite.8
--- squid-5.6/src/store/id_rewriters/file/storeid_file_rewrite.8	2022-06-06 10:47:31.000000000 +1200
+++ squid-5.7/src/store/id_rewriters/file/storeid_file_rewrite.8	2022-09-06 03:40:58.000000000 +1200
@@ -133,7 +133,7 @@
 .\" ========================================================================
 .\"
 .IX Title "STOREID_FILE_REWRITE 8"
-.TH STOREID_FILE_REWRITE 8 "2022-06-05" "perl v5.34.0" "User Contributed Perl Documentation"
+.TH STOREID_FILE_REWRITE 8 "2022-09-05" "perl v5.34.0" "User Contributed Perl Documentation"
 .\" For nroff, turn off justification.  Always turn off hyphenation; it makes
 .\" way too many mistakes in technical documents.
 .if n .ad l
diff -u -r -N squid-5.6/src/tests/testStoreHashIndex.cc squid-5.7/src/tests/testStoreHashIndex.cc
--- squid-5.6/src/tests/testStoreHashIndex.cc	2022-06-06 10:11:52.000000000 +1200
+++ squid-5.7/src/tests/testStoreHashIndex.cc	2022-09-05 16:06:48.000000000 +1200
@@ -102,6 +102,8 @@
     if (inited)
         return;
 
+    inited = true;
+
     Mem::Init();
 
     Config.Store.avgObjectSize = 1024;
@@ -109,6 +111,10 @@
     Config.Store.objectsPerBucket = 20;
 
     Config.Store.maxObjectSize = 2048;
+
+    Config.memShared.defaultTo(false);
+
+    Config.store_dir_select_algorithm = xstrdup("round-robin");
 }
 
 /* TODO make this a cbdata class */
diff -u -r -N squid-5.6/src/tunnel.cc squid-5.7/src/tunnel.cc
--- squid-5.6/src/tunnel.cc	2022-06-06 10:11:52.000000000 +1200
+++ squid-5.7/src/tunnel.cc	2022-09-05 16:06:48.000000000 +1200
@@ -97,6 +97,10 @@
         return (server.conn != NULL && server.conn->getPeer() ? server.conn->getPeer()->host : request->url.host());
     };
 
+    /// store the given to-server connection; prohibit retries and do not look
+    /// for any other destinations
+    void commitToServer(const Comm::ConnectionPointer &);
+
     /// Whether the client sent a CONNECT request to us.
     bool clientExpectsConnectResponse() const {
         // If we are forcing a tunnel after receiving a client CONNECT, then we
@@ -186,6 +190,10 @@
     /// whether another destination may be still attempted if the TCP connection
     /// was unexpectedly closed
     bool retriable;
+
+    /// whether the decision to tunnel to a particular destination was final
+    bool committedToServer;
+
     // TODO: remove after fixing deferred reads in TunnelStateData::copyRead()
     CodeContext::Pointer codeContext; ///< our creator context
 
@@ -263,9 +271,8 @@
 
     /// \returns whether the request should be retried (nil) or the description why it should not
     const char *checkRetry();
-    /// whether the successfully selected path destination or the established
-    /// server connection is still in use
-    bool usingDestination() const;
+
+    bool transporting() const;
 
     /// details of the "last tunneling attempt" failure (if it failed)
     ErrorState *savedError = nullptr;
@@ -362,6 +369,7 @@
     destinations(new ResolvedPeers()),
     destinationsFound(false),
     retriable(true),
+    committedToServer(false),
     codeContext(CodeContext::Current())
 {
     debugs(26, 3, "TunnelStateData constructed this=" << this);
@@ -1009,8 +1017,7 @@
 TunnelStateData::notePeerReadyToShovel(const Comm::ConnectionPointer &conn)
 {
     assert(!client.dirty);
-    retriable = false;
-    server.initConnection(conn, tunnelServerClosed, "tunnelServerClosed", this);
+    commitToServer(conn);
 
     if (!clientExpectsConnectResponse())
         tunnelStartShoveling(this); // ssl-bumped connection, be quiet
@@ -1025,6 +1032,15 @@
     }
 }
 
+void
+TunnelStateData::commitToServer(const Comm::ConnectionPointer &conn)
+{
+    committedToServer = true;
+    retriable = false; // may already be false
+    PeerSelectionInitiator::subscribed = false; // may already be false
+    server.initConnection(conn, tunnelServerClosed, "tunnelServerClosed", this);
+}
+
 static void
 tunnelErrorComplete(int fd/*const Comm::ConnectionPointer &*/, void *data, size_t)
 {
@@ -1252,18 +1268,15 @@
 
     destinations->addPath(path);
 
-    if (usingDestination()) {
-        // We are already using a previously opened connection but also
-        // receiving destinations in case we need to re-forward.
-        Must(!transportWait);
-        return;
-    }
-
     if (transportWait) {
+        assert(!transporting());
         notifyConnOpener();
         return; // and continue to wait for tunnelConnectDone() callback
     }
 
+    if (transporting())
+        return; // and continue to receive destinations for backup
+
     startConnecting();
 }
 
@@ -1279,8 +1292,9 @@
         if (selectionError)
             return sendError(selectionError, "path selection has failed");
 
+        // TODO: Merge with FwdState and remove this likely unnecessary check.
         if (savedError)
-            return sendError(savedError, "all found paths have failed");
+            return sendError(savedError, "path selection found no paths (with an impossible early error)");
 
         return sendError(new ErrorState(ERR_CANNOT_FORWARD, Http::scInternalServerError, request.getRaw(), al),
                          "path selection found no paths");
@@ -1289,21 +1303,32 @@
     // if all of them fail, tunneling as whole will fail
     Must(!selectionError); // finding at least one path means selection succeeded
 
-    if (usingDestination()) {
-        // We are already using a previously opened connection but also
-        // receiving destinations in case we need to re-forward.
-        Must(!transportWait);
+    if (transportWait) {
+        assert(!transporting());
+        notifyConnOpener();
+        return; // and continue to wait for the noteConnection() callback
+    }
+
+    if (transporting()) {
+        // We are already using a previously opened connection (but were also
+        // receiving more destinations in case we need to re-forward).
+        debugs(17, 7, "keep transporting");
         return;
     }
 
-    Must(transportWait); // or we would be stuck with nothing to do or wait for
-    notifyConnOpener();
+    // destinationsFound, but none of them worked, and we were waiting for more
+    assert(savedError);
+    // XXX: Honor clientExpectsConnectResponse() before replying.
+    sendError(savedError, "all found paths have failed");
 }
 
+/// Whether a tunneling attempt to some selected destination X is in progress
+/// (after successfully opening/reusing a transport connection to X).
+/// \sa transportWait
 bool
-TunnelStateData::usingDestination() const
+TunnelStateData::transporting() const
 {
-    return encryptionWait || peerWait || Comm::IsConnOpen(server.conn);
+    return encryptionWait || peerWait || committedToServer;
 }
 
 /// remembers an error to be used if there will be no more connection attempts
@@ -1362,7 +1387,7 @@
         request->hier.startPeerClock();
 
     assert(!destinations->empty());
-    assert(!usingDestination());
+    assert(!transporting());
     AsyncCall::Pointer callback = asyncCall(17, 5, "TunnelStateData::noteConnection", HappyConnOpener::CbDialer<TunnelStateData>(&TunnelStateData::noteConnection, this));
     const auto cs = new HappyConnOpener(destinations, callback, request, startTime, 0, al);
     cs->setHost(request->url.host());
@@ -1457,12 +1482,10 @@
     debugs(26, 3, request->method << " " << context->http->uri << " " << request->http_ver);
 
     TunnelStateData *tunnelState = new TunnelStateData(context->http);
-    tunnelState->retriable = false;
+    tunnelState->commitToServer(srvConn);
 
     request->hier.resetPeerNotes(srvConn, tunnelState->getHost());
 
-    tunnelState->server.initConnection(srvConn, tunnelServerClosed, "tunnelServerClosed", tunnelState);
-
 #if USE_DELAY_POOLS
     /* no point using the delayIsNoDelay stuff since tunnel is nice and simple */
     if (!srvConn->getPeer() || !srvConn->getPeer()->options.no_delay)
diff -u -r -N squid-5.6/tools/helper-mux/helper-mux.8 squid-5.7/tools/helper-mux/helper-mux.8
--- squid-5.6/tools/helper-mux/helper-mux.8	2022-06-06 10:47:33.000000000 +1200
+++ squid-5.7/tools/helper-mux/helper-mux.8	2022-09-06 03:41:01.000000000 +1200
@@ -133,7 +133,7 @@
 .\" ========================================================================
 .\"
 .IX Title "HELPER-MUX 8"
-.TH HELPER-MUX 8 "2022-06-05" "perl v5.34.0" "User Contributed Perl Documentation"
+.TH HELPER-MUX 8 "2022-09-05" "perl v5.34.0" "User Contributed Perl Documentation"
 .\" For nroff, turn off justification.  Always turn off hyphenation; it makes
 .\" way too many mistakes in technical documents.
 .if n .ad l
