squid 4.4: latest patches (04-08)

Message ID 20181227125041.25923-1-matthias.fischer@ipfire.org
State Superseded
Headers
Series squid 4.4: latest patches (04-08) |

Commit Message

Matthias Fischer Dec. 27, 2018, 11:50 p.m. UTC
  For details see:
http://www.squid-cache.org/Versions/v4/changesets/

Best,
Matthias

Signed-off-by: Matthias Fischer <matthias.fischer@ipfire.org>
---
 lfs/squid                                     |   5 +
 ...documentation_and_implementation_277.patch | 164 ++++++++++
 ...onfig_when_configure-ing_libxml2_338.patch |  89 ++++++
 ...s_Improved_lexgrog_compatibility_340.patch |  24 ++
 ...from_accessing_some_web_contents_304.patch | 285 ++++++++++++++++++
 ..._a_sslcrtvalidator_used_together_328.patch |  24 ++
 .../squid-4.4-fix-max-file-descriptors.patch  |   4 +-
 7 files changed, 593 insertions(+), 2 deletions(-)
 create mode 100644 src/patches/squid/04_Fixed_forward_max_tries_documentation_and_implementation_277.patch
 create mode 100644 src/patches/squid/05_Use_and_prefer_pkg-config_when_configure-ing_libxml2_338.patch
 create mode 100644 src/patches/squid/06_Docs_Improved_lexgrog_compatibility_340.patch
 create mode 100644 src/patches/squid/07_Bug_4253_ssl_bump_prevents_from_accessing_some_web_contents_304.patch
 create mode 100644 src/patches/squid/08_Squid_crashes_when_ICAPS_and_a_sslcrtvalidator_used_together_328.patch
  

Comments

Matthias Fischer Jan. 2, 2019, 4:34 a.m. UTC | #1
Hi,

On 27.12.2018 13:50, Matthias Fischer wrote:
> For details see:
> http://www.squid-cache.org/Versions/v4/changesets/
> ...

Please don't merge this, 4.5 is on its way... ;-)

Best,
Matthias
  

Patch

diff --git a/lfs/squid b/lfs/squid
index aaa2d0b96..113b4c3aa 100644
--- a/lfs/squid
+++ b/lfs/squid
@@ -75,6 +75,11 @@  $(TARGET) : $(patsubst %,$(DIR_DL)/%,$(objects))
 	cd $(DIR_APP) && patch -Np1 -i $(DIR_SRC)/src/patches/squid/01_Fix_netdb_exchange_with_a_TLS_cache_peer_307.patch
 	cd $(DIR_APP) && patch -Np1 -i $(DIR_SRC)/src/patches/squid/02_Maintenance_add_xz_tarball_format_formally_to_make_dist_325.patch
 	cd $(DIR_APP) && patch -Np1 -i $(DIR_SRC)/src/patches/squid/03_The_handshake_logformat_code_331.patch
+	cd $(DIR_APP) && patch -Np1 -i $(DIR_SRC)/src/patches/squid/04_Fixed_forward_max_tries_documentation_and_implementation_277.patch
+	cd $(DIR_APP) && patch -Np1 -i $(DIR_SRC)/src/patches/squid/05_Use_and_prefer_pkg-config_when_configure-ing_libxml2_338.patch
+	cd $(DIR_APP) && patch -Np1 -i $(DIR_SRC)/src/patches/squid/06_Docs_Improved_lexgrog_compatibility_340.patch
+	cd $(DIR_APP) && patch -Np1 -i $(DIR_SRC)/src/patches/squid/07_Bug_4253_ssl_bump_prevents_from_accessing_some_web_contents_304.patch
+	cd $(DIR_APP) && patch -Np1 -i $(DIR_SRC)/src/patches/squid/08_Squid_crashes_when_ICAPS_and_a_sslcrtvalidator_used_together_328.patch
 	cd $(DIR_APP) && patch -Np0 -i $(DIR_SRC)/src/patches/squid/squid-4.4-fix-max-file-descriptors.patch
 
 	cd $(DIR_APP) && autoreconf -vfi
diff --git a/src/patches/squid/04_Fixed_forward_max_tries_documentation_and_implementation_277.patch b/src/patches/squid/04_Fixed_forward_max_tries_documentation_and_implementation_277.patch
new file mode 100644
index 000000000..52c75e097
--- /dev/null
+++ b/src/patches/squid/04_Fixed_forward_max_tries_documentation_and_implementation_277.patch
@@ -0,0 +1,164 @@ 
+commit b3699887c2ffa807c65f153639cd13feb93f4c0f
+Author: Eduard Bagdasaryan <eduard.bagdasaryan@measurement-factory.com>
+Date:   2018-11-28 23:55:29 +0000
+
+    Fixed forward_max_tries documentation and implementation (#277)
+    
+    Before 1c8f25b, FwdState::n_tries counted the total number of forwarding
+    attempts, including pinned and persistent connection retries. Since that
+    revision, it started counting just those retries. What should n_tries
+    count? The counter is used to honor the forward_max_tries directive, but
+    that directive was documented to limit the number of _different_ paths
+    to try. Neither 1c8f25b~1 nor 1c8f25b code matched that documentation!
+    
+    Continuing to count just pinned and persistent connection retries (as in
+    1c8f25b) would violate any reasonable forward_max_tries intent and admin
+    expectations. There are two ways to fix this problem, synchronizing code
+    and documentation:
+    
+    * Count just the attempts to use a different forwarding path, matching
+      forward_max_tries documentation but not what Squid has ever done. This
+      approach makes it difficult for an admin to limit the total number of
+      forwarding attempts in environments where, say, the second attempt is
+      unlikely to succeed and will just incur wasteful delays (Squid bug
+      4788 report is probably about one of such use cases). Also,
+      implementing this approach may be more difficult because it requires
+      adding a new counter for retries and, for some interpretations of
+      "different", even a container of previously visited paths.
+    
+    * Count all forwarding attempts (as before 1c8f25b) and adjust
+      forward_max_tries documentation to match this historical behavior.
+      This approach does not have known unique flaws.
+    
+    Also fixed FwdState::n_tries off-by-one comparison bug discussed during
+    Squid bug 4788 triage.
+    
+    Also fixed admin concern behind Squid bug 4788 "forward_max_tries 1 does
+    not prevent some retries": While the old forward_max_tries documentation
+    actually excluded pconn retries, technically invalidating the bug
+    report, the admin now has a knob to limit those retries.
+
+diff --git a/src/FwdState.cc b/src/FwdState.cc
+index f201333..b218240 100644
+--- a/src/FwdState.cc
++++ b/src/FwdState.cc
+@@ -587,7 +587,7 @@ FwdState::checkRetry()
+     if (!entry->isEmpty())
+         return false;
+ 
+-    if (n_tries > Config.forward_max_tries)
++    if (exhaustedTries())
+         return false;
+ 
+     if (!EnoughTimeToReForward(start_t))
+@@ -921,6 +921,7 @@ FwdState::connectStart()
+     Comm::ConnOpener *cs = new Comm::ConnOpener(serverDestinations[0], calls.connector, connTimeout);
+     if (host)
+         cs->setHost(host);
++    ++n_tries;
+     AsyncJob::Start(cs);
+ }
+ 
+@@ -1072,7 +1073,7 @@ FwdState::reforward()
+         return 0;
+     }
+ 
+-    if (n_tries > Config.forward_max_tries)
++    if (exhaustedTries())
+         return 0;
+ 
+     if (request->bodyNibbled())
+@@ -1222,6 +1223,12 @@ FwdState::logReplyStatus(int tries, const Http::StatusCode status)
+     ++ FwdReplyCodes[tries][status];
+ }
+ 
++bool
++FwdState::exhaustedTries() const
++{
++    return n_tries >= Config.forward_max_tries;
++}
++
+ /**** PRIVATE NON-MEMBER FUNCTIONS ********************************************/
+ 
+ /*
+diff --git a/src/FwdState.h b/src/FwdState.h
+index 6619c64..85f0fb9 100644
+--- a/src/FwdState.h
++++ b/src/FwdState.h
+@@ -127,6 +127,9 @@ private:
+     void syncWithServerConn(const char *host);
+     void syncHierNote(const Comm::ConnectionPointer &server, const char *host);
+ 
++    /// whether we have used up all permitted forwarding attempts
++    bool exhaustedTries() const;
++
+ public:
+     StoreEntry *entry;
+     HttpRequest *request;
+@@ -139,7 +142,7 @@ private:
+     ErrorState *err;
+     Comm::ConnectionPointer clientConn;        ///< a possibly open connection to the client.
+     time_t start_t;
+-    int n_tries;
++    int n_tries; ///< the number of forwarding attempts so far
+ 
+     // AsyncCalls which we set and may need cancelling.
+     struct {
+diff --git a/src/cf.data.pre b/src/cf.data.pre
+index a8ca587..7a7d271 100644
+--- a/src/cf.data.pre
++++ b/src/cf.data.pre
+@@ -3791,11 +3791,15 @@ DEFAULT: 25
+ TYPE: int
+ LOC: Config.forward_max_tries
+ DOC_START
+-	Controls how many different forward paths Squid will try
+-	before giving up. See also forward_timeout.
++	Limits the number of attempts to forward the request.
++
++	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.
+ 	
+-	NOTE: connect_retries (default: none) can make each of these
+-	possible forwarding paths be tried multiple times.
++	See also: forward_timeout and connect_retries.
+ DOC_END
+ 
+ COMMENT_START
+@@ -9854,19 +9858,23 @@ LOC: Config.connect_retries
+ DEFAULT: 0
+ DEFAULT_DOC: Do not retry failed connections.
+ DOC_START
+-	This sets the maximum number of connection attempts made for each
+-	TCP connection. The connect_retries attempts must all still
+-	complete within the connection timeout period.
++	Limits the number of reopening attempts when establishing a single
++	TCP connection. All these attempts must still complete before the
++	applicable connection opening timeout expires.
++
++	By default and when connect_retries is set to zero, Squid does not
++	retry failed connection opening attempts.
+ 
+-	The default is not to re-try if the first connection attempt fails.
+-	The (not recommended) maximum is 10 tries.
++	The (not recommended) maximum is 10 tries. An attempt to configure a
++	higher value results in the value of 10 being used (with a warning).
+ 
+-	A warning message will be generated if it is set to a too-high
+-	value and the configured value will be over-ridden.
++	Squid may open connections to retry various high-level forwarding
++	failures. For an outside observer, that activity may look like a
++	low-level connection reopening attempt, but those high-level retries
++	are governed by forward_max_tries instead.
+ 
+-	Note: These re-tries are in addition to forward_max_tries
+-	which limit how many different addresses may be tried to find
+-	a useful server.
++	See also: connect_timeout, forward_timeout, icap_connect_timeout,
++	ident_timeout, and forward_max_tries.
+ DOC_END
+ 
+ NAME: retry_on_error
diff --git a/src/patches/squid/05_Use_and_prefer_pkg-config_when_configure-ing_libxml2_338.patch b/src/patches/squid/05_Use_and_prefer_pkg-config_when_configure-ing_libxml2_338.patch
new file mode 100644
index 000000000..7685a9637
--- /dev/null
+++ b/src/patches/squid/05_Use_and_prefer_pkg-config_when_configure-ing_libxml2_338.patch
@@ -0,0 +1,89 @@ 
+commit c34582b9e8c40529db7eb9c490b081a37972f6d4
+Author: Fabrice Fontaine <fontaine.fabrice@gmail.com>
+Date:   2018-12-04 17:23:25 +0000
+
+    Use and prefer pkg-config when ./configure-ing libxml2 (#338)
+    
+    The old method of trying to locate libxml2 via AC_CHECK_LIB() is
+    preserved to accommodate environments without pkg-config.
+    
+    pkg-config knows about libxml2 dependencies like lz or -liconv that the
+    old method misses.
+
+diff --git a/configure.ac b/configure.ac
+index f668567..ef20a53 100644
+--- a/configure.ac
++++ b/configure.ac
+@@ -922,41 +922,45 @@ fi
+ 
+ AC_ARG_WITH(libxml2, AS_HELP_STRING([--without-libxml2],[Do not use libxml2 for ESI. Default: auto-detect]))
+ if test "x$squid_opt_use_esi" != "xno" -a "x$with_libxml2" != "xno" ; then
+-  AC_CHECK_LIB([xml2], [main], [XMLLIB="-lxml2"; HAVE_LIBXML2=1])
+-  dnl Find the main header and include path...
+-  AC_CACHE_CHECK([location of libxml2 include files], [ac_cv_libxml2_include], [
+-    AC_CHECK_HEADERS([libxml/parser.h], [], [
+-      AC_MSG_NOTICE([Testing in /usr/include/libxml2])
+-      SAVED_CPPFLAGS="$CPPFLAGS"
+-      CPPFLAGS="-I/usr/include/libxml2 $CPPFLAGS"
+-      unset ac_cv_header_libxml_parser_h
+-      AC_CHECK_HEADERS([libxml/parser.h], [ac_cv_libxml2_include="-I/usr/include/libxml2"], [
+-        AC_MSG_NOTICE([Testing in /usr/local/include/libxml2])
+-        CPPFLAGS="-I/usr/local/include/libxml2 $SAVED_CPPFLAGS"
++  SQUID_STATE_SAVE([squid_libxml2_save])
++  PKG_CHECK_MODULES([LIBXML2],[libxml-2.0],[],[
++    AC_CHECK_LIB([xml2], [main], [LIBXML2_LIBS="$LIBXML2_LIBS -lxml2"])
++    dnl Find the main header and include path...
++    AC_CACHE_CHECK([location of libxml2 include files], [ac_cv_libxml2_include], [
++      AC_CHECK_HEADERS([libxml/parser.h], [], [
++        AC_MSG_NOTICE([Testing in /usr/include/libxml2])
++        SAVED_CPPFLAGS="$CPPFLAGS"
++        CPPFLAGS="-I/usr/include/libxml2 $CPPFLAGS"
+         unset ac_cv_header_libxml_parser_h
+-        AC_CHECK_HEADERS([libxml/parser.h], [ac_cv_libxml2_include="-I/usr/local/include/libxml2"], [
+-          AC_MSG_NOTICE([Failed to find libxml2 header file libxml/parser.h])
++        AC_CHECK_HEADERS([libxml/parser.h], [LIBXML2_CFLAGS="$LIBXML2_CFLAGS -I/usr/include/libxml2"], [
++          AC_MSG_NOTICE([Testing in /usr/local/include/libxml2])
++          CPPFLAGS="-I/usr/local/include/libxml2 $SAVED_CPPFLAGS"
++          unset ac_cv_header_libxml_parser_h
++          AC_CHECK_HEADERS([libxml/parser.h], [LIBXML2_CFLAGS="$LIBXML2_CFLAGS -I/usr/local/include/libxml2"], [
++            AC_MSG_NOTICE([Failed to find libxml2 header file libxml/parser.h])
++          ])
+         ])
++        CPPFLAGS="$SAVED_CPPFLAGS"
+       ])
+-      CPPFLAGS="$SAVED_CPPFLAGS"
+     ])
+   ])
+-  if test "x$ac_cv_libxml2_include" != "x"; then
+-      SQUID_CXXFLAGS="$ac_cv_libxml2_include $SQUID_CXXFLAGS"
+-      CPPFLAGS="$ac_cv_libxml2_include $CPPFLAGS"
+-  fi
++  CPPFLAGS="$CPPFLAGS $LIBXML2_CFLAGS"
+   dnl Now that we know where to look find the headers...
+   AC_CHECK_HEADERS(libxml/parser.h libxml/HTMLparser.h libxml/HTMLtree.h)
+-  AC_DEFINE_UNQUOTED(HAVE_LIBXML2, $HAVE_LIBXML2, [Define to 1 if you have the libxml2 library])
+-  AS_IF(test "x$HAVE_LIBXML2" = "x1",[
++  SQUID_STATE_ROLLBACK([squid_libxml2_save])
++
++  if test "x$LIBXML2_LIBS" != "x"; then
++    HAVE_LIBXML2=1
+     squid_opt_use_esi=yes
+-  ],[
+-    AS_IF(test "x$with_libxml2" = "xyes",[
+-      AC_MSG_ERROR([Required library libxml2 not found.])
+-    ],[
+-      AC_MSG_NOTICE([Library libxml2 not found.])
+-    ])
+-  ])
++    SQUID_CXXFLAGS="$SQUID_CXXFLAGS $LIBXML2_CFLAGS"
++    CPPFLAGS="$CPPFLAGS $LIBXML2_CFLAGS"
++    XMLLIB="$LIBXML2_LIBS"
++    AC_DEFINE_UNQUOTED(HAVE_LIBXML2, $HAVE_LIBXML2, [Define to 1 if you have the libxml2 library])
++  elif test "x$with_libxml2" = "xyes"; then
++    AC_MSG_ERROR([Required library libxml2 not found])
++  else
++    AC_MSG_NOTICE([Library libxml2 not found.])
++  fi
+ fi
+ 
+ AS_IF([test "x$squid_opt_use_esi" = "xyes"],[
diff --git a/src/patches/squid/06_Docs_Improved_lexgrog_compatibility_340.patch b/src/patches/squid/06_Docs_Improved_lexgrog_compatibility_340.patch
new file mode 100644
index 000000000..3ffd9724d
--- /dev/null
+++ b/src/patches/squid/06_Docs_Improved_lexgrog_compatibility_340.patch
@@ -0,0 +1,24 @@ 
+commit b5ee1b8a8dd80cabe5de701d6dc59b90841bbb1c
+Author: uhliarik <luhliari@redhat.com>
+Date:   2018-12-11 23:09:46 +0000
+
+    Docs: Improved lexgrog compatibility (#340)
+    
+    The generated url_lfs_reqwrite.8 manpage was not parsable by lexgrog:
+    
+        $ lexgrog url_lfs_rewrite.8.gz
+        url_lfs_rewrite.8.gz: parse failed
+
+diff --git a/src/http/url_rewriters/LFS/url_lfs_rewrite.pl.in b/src/http/url_rewriters/LFS/url_lfs_rewrite.pl.in
+index a7168e0..2e92769 100755
+--- a/src/http/url_rewriters/LFS/url_lfs_rewrite.pl.in
++++ b/src/http/url_rewriters/LFS/url_lfs_rewrite.pl.in
+@@ -8,7 +8,7 @@ use Pod::Usage;
+ 
+ =head1 NAME
+ 
+-B<url_lfs_rewrite>
++ url_lfs_rewrite - a URL-rewriter based on local file existence
+ 
+ =head1 SYNOPSIS
+ 
diff --git a/src/patches/squid/07_Bug_4253_ssl_bump_prevents_from_accessing_some_web_contents_304.patch b/src/patches/squid/07_Bug_4253_ssl_bump_prevents_from_accessing_some_web_contents_304.patch
new file mode 100644
index 000000000..146561870
--- /dev/null
+++ b/src/patches/squid/07_Bug_4253_ssl_bump_prevents_from_accessing_some_web_contents_304.patch
@@ -0,0 +1,285 @@ 
+commit 06bae9e152a7f0d8e4f3c301dfdbd13231fec725
+Author: Christos Tsantilas <christos@chtsanti.net>
+Date:   2018-12-25 13:37:26 +0000
+
+    Bug 4253: ssl_bump prevents from accessing some web contents (#304)
+    
+    Surrogate-Capability should only be sent on accel traffic, not
+    on bumped traffic.
+    
+    This is a Measurement Factory project
+
+diff --git a/src/client_side.cc b/src/client_side.cc
+index d61e278..b3e3977 100644
+--- a/src/client_side.cc
++++ b/src/client_side.cc
+@@ -1081,20 +1081,18 @@ findTrailingHTTPVersion(const char *uriAndHTTPVersion, const char *end)
+     return NULL;
+ }
+ 
+-static void
+-prepareAcceleratedURL(ConnStateData * conn, ClientHttpRequest *http, const Http1::RequestParserPointer &hp)
++static char *
++prepareAcceleratedURL(ConnStateData * conn, const Http1::RequestParserPointer &hp)
+ {
+     int vhost = conn->port->vhost;
+     int vport = conn->port->vport;
+     static char ipbuf[MAX_IPSTRLEN];
+ 
+-    http->flags.accel = true;
+-
+     /* BUG: Squid cannot deal with '*' URLs (RFC2616 5.1.2) */
+ 
+     static const SBuf cache_object("cache_object://");
+     if (hp->requestUri().startsWith(cache_object))
+-        return; /* already in good shape */
++        return nullptr; /* already in good shape */
+ 
+     // XXX: re-use proper URL parser for this
+     SBuf url = hp->requestUri(); // use full provided URI if we abort
+@@ -1104,7 +1102,7 @@ prepareAcceleratedURL(ConnStateData * conn, ClientHttpRequest *http, const Http1
+             break;
+ 
+         if (conn->port->vhost)
+-            return; /* already in good shape */
++            return nullptr; /* already in good shape */
+ 
+         // skip the URI scheme
+         static const CharacterSet uriScheme = CharacterSet("URI-scheme","+-.") + CharacterSet::ALPHA + CharacterSet::DIGIT;
+@@ -1141,18 +1139,16 @@ prepareAcceleratedURL(ConnStateData * conn, ClientHttpRequest *http, const Http1
+ #endif
+ 
+     if (vport < 0)
+-        vport = http->getConn()->clientConnection->local.port();
++        vport = conn->clientConnection->local.port();
+ 
+-    const bool switchedToHttps = conn->switchedToHttps();
+-    const bool tryHostHeader = vhost || switchedToHttps;
+     char *host = NULL;
+-    if (tryHostHeader && (host = hp->getHeaderField("Host"))) {
++    if (vhost && (host = hp->getHeaderField("Host"))) {
+         debugs(33, 5, "ACCEL VHOST REWRITE: vhost=" << host << " + vport=" << vport);
+         char thost[256];
+         if (vport > 0) {
+             thost[0] = '\0';
+             char *t = NULL;
+-            if (host[strlen(host)] != ']' && (t = strrchr(host,':')) != NULL) {
++            if (host[strlen(host) - 1] != ']' && (t = strrchr(host,':')) != nullptr) {
+                 strncpy(thost, host, (t-host));
+                 snprintf(thost+(t-host), sizeof(thost)-(t-host), ":%d", vport);
+                 host = thost;
+@@ -1161,67 +1157,116 @@ prepareAcceleratedURL(ConnStateData * conn, ClientHttpRequest *http, const Http1
+                 host = thost;
+             }
+         } // else nothing to alter port-wise.
+-        const int url_sz = hp->requestUri().length() + 32 + Config.appendDomainLen + strlen(host);
+-        http->uri = (char *)xcalloc(url_sz, 1);
+         const SBuf &scheme = AnyP::UriScheme(conn->transferProtocol.protocol).image();
+-        snprintf(http->uri, url_sz, SQUIDSBUFPH "://%s" SQUIDSBUFPH, SQUIDSBUFPRINT(scheme), host, SQUIDSBUFPRINT(url));
+-        debugs(33, 5, "ACCEL VHOST REWRITE: " << http->uri);
++        const int url_sz = scheme.length() + strlen(host) + url.length() + 32;
++        char *uri = static_cast<char *>(xcalloc(url_sz, 1));
++        snprintf(uri, url_sz, SQUIDSBUFPH "://%s" SQUIDSBUFPH, SQUIDSBUFPRINT(scheme), host, SQUIDSBUFPRINT(url));
++        debugs(33, 5, "ACCEL VHOST REWRITE: " << uri);
++        return uri;
+     } else if (conn->port->defaultsite /* && !vhost */) {
+         debugs(33, 5, "ACCEL DEFAULTSITE REWRITE: defaultsite=" << conn->port->defaultsite << " + vport=" << vport);
+-        const int url_sz = hp->requestUri().length() + 32 + Config.appendDomainLen +
+-                           strlen(conn->port->defaultsite);
+-        http->uri = (char *)xcalloc(url_sz, 1);
+         char vportStr[32];
+         vportStr[0] = '\0';
+         if (vport > 0) {
+             snprintf(vportStr, sizeof(vportStr),":%d",vport);
+         }
+         const SBuf &scheme = AnyP::UriScheme(conn->transferProtocol.protocol).image();
+-        snprintf(http->uri, url_sz, SQUIDSBUFPH "://%s%s" SQUIDSBUFPH,
++        const int url_sz = scheme.length() + strlen(conn->port->defaultsite) + sizeof(vportStr) + url.length() + 32;
++        char *uri = static_cast<char *>(xcalloc(url_sz, 1));
++        snprintf(uri, url_sz, SQUIDSBUFPH "://%s%s" SQUIDSBUFPH,
+                  SQUIDSBUFPRINT(scheme), conn->port->defaultsite, vportStr, SQUIDSBUFPRINT(url));
+-        debugs(33, 5, "ACCEL DEFAULTSITE REWRITE: " << http->uri);
++        debugs(33, 5, "ACCEL DEFAULTSITE REWRITE: " << uri);
++        return uri;
+     } else if (vport > 0 /* && (!vhost || no Host:) */) {
+         debugs(33, 5, "ACCEL VPORT REWRITE: *_port IP + vport=" << vport);
+         /* Put the local socket IP address as the hostname, with whatever vport we found  */
+-        const int url_sz = hp->requestUri().length() + 32 + Config.appendDomainLen;
+-        http->uri = (char *)xcalloc(url_sz, 1);
+-        http->getConn()->clientConnection->local.toHostStr(ipbuf,MAX_IPSTRLEN);
++        conn->clientConnection->local.toHostStr(ipbuf,MAX_IPSTRLEN);
+         const SBuf &scheme = AnyP::UriScheme(conn->transferProtocol.protocol).image();
+-        snprintf(http->uri, url_sz, SQUIDSBUFPH "://%s:%d" SQUIDSBUFPH,
++        const int url_sz = scheme.length() + sizeof(ipbuf) + url.length() + 32;
++        char *uri = static_cast<char *>(xcalloc(url_sz, 1));
++        snprintf(uri, url_sz, SQUIDSBUFPH "://%s:%d" SQUIDSBUFPH,
+                  SQUIDSBUFPRINT(scheme), ipbuf, vport, SQUIDSBUFPRINT(url));
+-        debugs(33, 5, "ACCEL VPORT REWRITE: " << http->uri);
++        debugs(33, 5, "ACCEL VPORT REWRITE: " << uri);
++        return uri;
+     }
++
++    return nullptr;
+ }
+ 
+-static void
+-prepareTransparentURL(ConnStateData * conn, ClientHttpRequest *http, const Http1::RequestParserPointer &hp)
++static char *
++buildUrlFromHost(ConnStateData * conn, const Http1::RequestParserPointer &hp)
+ {
+-    // TODO Must() on URI !empty when the parser supports throw. For now avoid assert().
+-    if (!hp->requestUri().isEmpty() && hp->requestUri()[0] != '/')
+-        return; /* already in good shape */
+-
++    char *uri = nullptr;
+     /* BUG: Squid cannot deal with '*' URLs (RFC2616 5.1.2) */
+-
+     if (const char *host = hp->getHeaderField("Host")) {
+-        const int url_sz = hp->requestUri().length() + 32 + Config.appendDomainLen +
+-                           strlen(host);
+-        http->uri = (char *)xcalloc(url_sz, 1);
+         const SBuf &scheme = AnyP::UriScheme(conn->transferProtocol.protocol).image();
+-        snprintf(http->uri, url_sz, SQUIDSBUFPH "://%s" SQUIDSBUFPH,
+-                 SQUIDSBUFPRINT(scheme), host, SQUIDSBUFPRINT(hp->requestUri()));
+-        debugs(33, 5, "TRANSPARENT HOST REWRITE: " << http->uri);
+-    } else {
++        const int url_sz = scheme.length() + strlen(host) + hp->requestUri().length() + 32;
++        uri = static_cast<char *>(xcalloc(url_sz, 1));
++        snprintf(uri, url_sz, SQUIDSBUFPH "://%s" SQUIDSBUFPH,
++                 SQUIDSBUFPRINT(scheme),
++                 host,
++                 SQUIDSBUFPRINT(hp->requestUri()));
++    }
++    return uri;
++}
++
++char *
++ConnStateData::prepareTlsSwitchingURL(const Http1::RequestParserPointer &hp)
++{
++    Must(switchedToHttps());
++
++    if (!hp->requestUri().isEmpty() && hp->requestUri()[0] != '/')
++        return nullptr; /* already in good shape */
++
++    char *uri = buildUrlFromHost(this, hp);
++#if USE_OPENSSL
++    if (!uri) {
++        Must(tlsConnectPort);
++        Must(sslConnectHostOrIp.size());
++        SBuf useHost;
++        if (!tlsClientSni().isEmpty())
++            useHost = tlsClientSni();
++        else
++            useHost.assign(sslConnectHostOrIp.rawBuf(), sslConnectHostOrIp.size());
++
++        const SBuf &scheme = AnyP::UriScheme(transferProtocol.protocol).image();
++        const int url_sz = scheme.length() + useHost.length() + hp->requestUri().length() + 32;
++        uri = static_cast<char *>(xcalloc(url_sz, 1));
++        snprintf(uri, url_sz, SQUIDSBUFPH "://" SQUIDSBUFPH ":%d" SQUIDSBUFPH,
++                 SQUIDSBUFPRINT(scheme),
++                 SQUIDSBUFPRINT(useHost),
++                 tlsConnectPort,
++                 SQUIDSBUFPRINT(hp->requestUri()));
++    }
++#endif
++    if (uri)
++        debugs(33, 5, "TLS switching host rewrite: " << uri);
++    return uri;
++}
++
++static char *
++prepareTransparentURL(ConnStateData * conn, const Http1::RequestParserPointer &hp)
++{
++    // TODO Must() on URI !empty when the parser supports throw. For now avoid assert().
++    if (!hp->requestUri().isEmpty() && hp->requestUri()[0] != '/')
++        return nullptr; /* already in good shape */
++
++    char *uri = buildUrlFromHost(conn, hp);
++    if (!uri) {
+         /* Put the local socket IP address as the hostname.  */
+-        const int url_sz = hp->requestUri().length() + 32 + Config.appendDomainLen;
+-        http->uri = (char *)xcalloc(url_sz, 1);
+         static char ipbuf[MAX_IPSTRLEN];
+-        http->getConn()->clientConnection->local.toHostStr(ipbuf,MAX_IPSTRLEN);
+-        const SBuf &scheme = AnyP::UriScheme(http->getConn()->transferProtocol.protocol).image();
+-        snprintf(http->uri, url_sz, SQUIDSBUFPH "://%s:%d" SQUIDSBUFPH,
++        conn->clientConnection->local.toHostStr(ipbuf,MAX_IPSTRLEN);
++        const SBuf &scheme = AnyP::UriScheme(conn->transferProtocol.protocol).image();
++        const int url_sz = sizeof(ipbuf) + hp->requestUri().length() + 32;
++        uri = static_cast<char *>(xcalloc(url_sz, 1));
++        snprintf(uri, url_sz, SQUIDSBUFPH "://%s:%d" SQUIDSBUFPH,
+                  SQUIDSBUFPRINT(scheme),
+-                 ipbuf, http->getConn()->clientConnection->local.port(), SQUIDSBUFPRINT(hp->requestUri()));
+-        debugs(33, 5, "TRANSPARENT REWRITE: " << http->uri);
++                 ipbuf, conn->clientConnection->local.port(), SQUIDSBUFPRINT(hp->requestUri()));
+     }
++
++    if (uri)
++        debugs(33, 5, "TRANSPARENT REWRITE: " << uri);
++    return uri;
+ }
+ 
+ /** Parse an HTTP request
+@@ -1341,9 +1386,11 @@ parseHttpRequest(ConnStateData *csd, const Http1::RequestParserPointer &hp)
+      *  - remote interception with PROXY protocol
+      *  - remote reverse-proxy with PROXY protocol
+      */
+-    if (csd->transparent()) {
++    if (csd->switchedToHttps()) {
++        http->uri = csd->prepareTlsSwitchingURL(hp);
++    } else if (csd->transparent()) {
+         /* intercept or transparent mode, properly working with no failures */
+-        prepareTransparentURL(csd, http, hp);
++        http->uri = prepareTransparentURL(csd, hp);
+ 
+     } else if (internalCheck(hp->requestUri())) { // NP: only matches relative-URI
+         /* internal URL mode */
+@@ -1353,9 +1400,10 @@ parseHttpRequest(ConnStateData *csd, const Http1::RequestParserPointer &hp)
+         //  But have not parsed there yet!! flag for local-only handling.
+         http->flags.internal = true;
+ 
+-    } else if (csd->port->flags.accelSurrogate || csd->switchedToHttps()) {
++    } else if (csd->port->flags.accelSurrogate) {
+         /* accelerator mode */
+-        prepareAcceleratedURL(csd, http, hp);
++        http->uri = prepareAcceleratedURL(csd, hp);
++        http->flags.accel = true;
+     }
+ 
+     if (!http->uri) {
+@@ -2315,6 +2363,7 @@ ConnStateData::ConnStateData(const MasterXaction::Pointer &xact) :
+ #if USE_OPENSSL
+     switchedToHttps_(false),
+     parsingTlsHandshake(false),
++    tlsConnectPort(0),
+     sslServerBump(NULL),
+     signAlgorithm(Ssl::algSignTrusted),
+ #endif
+@@ -3050,6 +3099,7 @@ ConnStateData::switchToHttps(HttpRequest *request, Ssl::BumpMode bumpServerMode)
+     assert(!switchedToHttps_);
+ 
+     sslConnectHostOrIp = request->url.host();
++    tlsConnectPort = request->url.port();
+     resetSslCommonName(request->url.host());
+ 
+     // We are going to read new request
+diff --git a/src/client_side.h b/src/client_side.h
+index bd4ceb0..70db8ab 100644
+--- a/src/client_side.h
++++ b/src/client_side.h
+@@ -274,6 +274,7 @@ public:
+ #else
+     bool switchedToHttps() const { return false; }
+ #endif
++    char *prepareTlsSwitchingURL(const Http1::RequestParserPointer &hp);
+ 
+     /* clt_conn_tag=tag annotation access */
+     const SBuf &connectionTag() const { return connectionTag_; }
+@@ -393,6 +394,7 @@ private:
+ 
+     /// The SSL server host name appears in CONNECT request or the server ip address for the intercepted requests
+     String sslConnectHostOrIp; ///< The SSL server host name as passed in the CONNECT request
++    unsigned short tlsConnectPort; ///< The TLS server port number as passed in the CONNECT request
+     SBuf sslCommonName_; ///< CN name for SSL certificate generation
+ 
+     /// TLS client delivered SNI value. Empty string if none has been received.
diff --git a/src/patches/squid/08_Squid_crashes_when_ICAPS_and_a_sslcrtvalidator_used_together_328.patch b/src/patches/squid/08_Squid_crashes_when_ICAPS_and_a_sslcrtvalidator_used_together_328.patch
new file mode 100644
index 000000000..611ff43ea
--- /dev/null
+++ b/src/patches/squid/08_Squid_crashes_when_ICAPS_and_a_sslcrtvalidator_used_together_328.patch
@@ -0,0 +1,24 @@ 
+commit 95251ebca6f285360485369297bea39b85c777ad (refs/remotes/origin/v4)
+Author: Christos Tsantilas <christos@chtsanti.net>
+Date:   2018-12-25 17:01:39 +0000
+
+    Squid crashes when ICAPS and a sslcrtvalidator used together (#328)
+    
+    Squid hits an assertions when tries to remove an comm_close handler from
+    the already closed connection object.
+    
+    This is a Measurement Factory project
+
+diff --git a/src/adaptation/icap/Xaction.cc b/src/adaptation/icap/Xaction.cc
+index 7005b47..6a0f8ad 100644
+--- a/src/adaptation/icap/Xaction.cc
++++ b/src/adaptation/icap/Xaction.cc
+@@ -744,7 +744,7 @@ Adaptation::Icap::Xaction::handleSecuredPeer(Security::EncryptorAnswer &answer)
+     securer = NULL;
+ 
+     if (closer != NULL) {
+-        if (answer.conn != NULL)
++        if (Comm::IsConnOpen(answer.conn))
+             comm_remove_close_handler(answer.conn->fd, closer);
+         else
+             closer->cancel("securing completed");
diff --git a/src/patches/squid/squid-4.4-fix-max-file-descriptors.patch b/src/patches/squid/squid-4.4-fix-max-file-descriptors.patch
index 8d1a4e03a..57fd0a6a6 100644
--- a/src/patches/squid/squid-4.4-fix-max-file-descriptors.patch
+++ b/src/patches/squid/squid-4.4-fix-max-file-descriptors.patch
@@ -1,6 +1,6 @@ 
 --- configure.ac.~	Wed Apr 20 14:26:07 2016
 +++ configure.ac	Fri Apr 22 17:20:46 2016
-@@ -3156,6 +3156,9 @@
+@@ -3160,6 +3160,9 @@
      ;;
  esac
  
@@ -10,7 +10,7 @@ 
  dnl --with-maxfd present for compatibility with Squid-2.
  dnl undocumented in ./configure --help  to encourage using the Squid-3 directive
  AC_ARG_WITH(maxfd,,
-@@ -3186,8 +3189,6 @@
+@@ -3190,8 +3193,6 @@
      esac
  ])