From patchwork Thu Dec 27 23:50:41 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Matthias Fischer X-Patchwork-Id: 2007 Return-Path: Received: from mail01.ipfire.org (mail01.i.ipfire.org [172.28.1.200]) (using TLSv1.2 with cipher ECDHE-ECDSA-AES256-GCM-SHA384 (256/256 bits)) (Client CN "mail01.ipfire.org", Issuer "Let's Encrypt Authority X3" (verified OK)) by web07.i.ipfire.org (Postfix) with ESMTPS id 83A488ABDC8 for ; Thu, 27 Dec 2018 12:50:53 +0000 (GMT) Received: from mail01.i.ipfire.org (localhost [IPv6:::1]) by mail01.ipfire.org (Postfix) with ESMTP id 826A7213171A; Thu, 27 Dec 2018 12:50:52 +0000 (GMT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=ipfire.org; s=201801; t=1545915052; h=from:from:sender:sender:reply-to:subject:subject:date:date: message-id:message-id:to:to:cc:mime-version:content-type: content-transfer-encoding:in-reply-to:references:list-id: list-unsubscribe:list-subscribe:list-post; bh=htHl+lYc5FDKIiWOg6dKIe+wLha0Ldu/Qf5sydETGCw=; b=M6npbOPqxyUmROL2tUNEZ2250yWRyVlNV6eKD88E4e95JCcBICJJTdV2yhgQMuRPYc6OAH O4cWzsovDOKTN/a2o21QeVp1Loihjw00Ajiax4ju+U4byPAituTYS+JEc4/DldUu5KVoa7 UHJENivTLW2n6FVrcDZJoggODzlosE4p3FGNlLq1NM18eFJA+1+1eZ90VViMEjW9+CUCZq 2S9jY2KdOOiHaxL8n04gmLkOoBrQ8JSg8WFSaFLHKYTCQgrAu6BFAfKJ6Qlj55JoBrRDe8 cBhh4TGUbiGADQGt8VkrwpHyq6vBg0V8QMeFgvfFVUxqarWus+QqNfgOP923nw== Received: from Devel.localdomain (p4FF5633E.dip0.t-ipconnect.de [79.245.99.62]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mail01.ipfire.org (Postfix) with ESMTPSA id 8D2AF2131718 for ; Thu, 27 Dec 2018 12:50:45 +0000 (GMT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=ipfire.org; s=201801; t=1545915045; h=from:from:sender:reply-to:subject:subject:date:date: message-id:message-id:to:to:cc:mime-version:content-type: content-transfer-encoding:in-reply-to:references; bh=htHl+lYc5FDKIiWOg6dKIe+wLha0Ldu/Qf5sydETGCw=; b=jqA5dUFH/LAwBVTNzX1hfEWCzvGynaL2+RjC+hYo2jziieT/3qfZnA7KkikPdmIwXj69YS yyMAFc5gUozYlitYChilwwS6f0Ur/u4QyuvMyw+LNY41nnOlp6KFtSWg7fo9bfv5tKNlTt tmllwsxBFc/gzA1K+ti9gTaL6L01F0bDev9Hn7N/DxJmwbYMCvwuHSIzVCdvkHsFHUY3aD zmL97aCUZgpIE6Uk2gGeHZVrbcOk5ctqlhuJbSRZTV2qwsQO4nASErvKNk1BPYSBD+07ir EeU2P0J/4Dpp3Wpaj5+P+Q+QahU1h+OHltucIKcqP4dCpjEBkDdDST7T7l12TA== From: Matthias Fischer To: development@lists.ipfire.org Subject: [PATCH] squid 4.4: latest patches (04-08) Date: Thu, 27 Dec 2018 13:50:41 +0100 Message-Id: <20181227125041.25923-1-matthias.fischer@ipfire.org> X-Mailer: git-send-email 2.18.0 Authentication-Results: mail01.ipfire.org; auth=pass smtp.auth=mfischer smtp.mailfrom=matthias.fischer@ipfire.org X-Spamd-Result: default: False [0.48 / 11.00]; ARC_NA(0.00)[]; FROM_HAS_DN(0.00)[]; TO_MATCH_ENVRCPT_ALL(0.00)[]; MIME_GOOD(-0.10)[text/plain]; TO_DN_NONE(0.00)[]; NEURAL_SPAM(2.58)[0.858,0]; RCPT_COUNT_ONE(0.00)[1]; DKIM_SIGNED(0.00)[]; MID_CONTAINS_FROM(1.00)[]; RCVD_COUNT_ZERO(0.00)[0]; FROM_EQ_ENVFROM(0.00)[]; MIME_TRACE(0.00)[0:+]; ASN(0.00)[asn:3320, ipnet:79.192.0.0/10, country:DE]; RCVD_TLS_ALL(0.00)[]; BAYES_HAM(-3.00)[100.00%] X-Spam-Status: No, score=0.48 X-Rspamd-Server: mail01.i.ipfire.org X-BeenThere: development@lists.ipfire.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: IPFire development talk List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: development-bounces@lists.ipfire.org Sender: "Development" For details see: http://www.squid-cache.org/Versions/v4/changesets/ Best, Matthias Signed-off-by: Matthias Fischer --- 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 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 +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 +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 +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 - 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 +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(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(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(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(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(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(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 +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 ])