diff -u -r -N squid-3.5.15/ChangeLog squid-3.5.16/ChangeLog --- squid-3.5.15/ChangeLog 2016-02-24 05:25:46.000000000 +1300 +++ squid-3.5.16/ChangeLog 2016-04-02 10:02:59.000000000 +1300 @@ -1,3 +1,21 @@ +Changes to squid-3.5.16 (02 Apr 2016): + + - Bug 4476: Removed duplicated #include lines + - Bug 4452: squid -z segfaults with ufs + - Bug 4447:FwdState.cc:447 "serverConnection() == conn" assertion + - Bug 4423: adding stdio: prefix to cache_log directive produces FATAL error + - Bug 4409: compile error when two Heimdal libraries are installed + - Bug 2831: Cache-control: max-age not sent on TCP_IMS_HIT/304 + - pinger: Fix buffer overflow in Icmp6::Recv + - pinger: Fix select(2) to actually use max_fd + - pinger: drop capabilities on Linux + - Fix memory leak of HttpRequest objects + - Fix memory leak when the cache of sslcrtvalidator_program is disabled via ttl=0 + - Fix assertion failed: Write.cc:41: "!ccb->active()" + - Fix crash on shutdown while cleaning up idle ICAP connections + - RFC 7725: Add registry entry for 451 status text + - ... and some build issues + Changes to squid-3.5.15 (23 Feb 2016): - Bug 3870: assertion failed: String.cc: 'len_ + len <65536' in ESI::CustomParser diff -u -r -N squid-3.5.15/configure squid-3.5.16/configure --- squid-3.5.15/configure 2016-02-24 05:28:54.000000000 +1300 +++ squid-3.5.16/configure 2016-04-02 10:06:42.000000000 +1300 @@ -1,7 +1,7 @@ #! /bin/sh # From configure.ac Revision. # Guess values for system-dependent variables and create Makefiles. -# Generated by GNU Autoconf 2.69 for Squid Web Proxy 3.5.15. +# Generated by GNU Autoconf 2.69 for Squid Web Proxy 3.5.16. # # Report bugs to . # @@ -595,8 +595,8 @@ # Identity of this package. PACKAGE_NAME='Squid Web Proxy' PACKAGE_TARNAME='squid' -PACKAGE_VERSION='3.5.15' -PACKAGE_STRING='Squid Web Proxy 3.5.15' +PACKAGE_VERSION='3.5.16' +PACKAGE_STRING='Squid Web Proxy 3.5.16' PACKAGE_BUGREPORT='http://bugs.squid-cache.org/' PACKAGE_URL='' @@ -1636,7 +1636,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 3.5.15 to adapt to many kinds of systems. +\`configure' configures Squid Web Proxy 3.5.16 to adapt to many kinds of systems. Usage: $0 [OPTION]... [VAR=VALUE]... @@ -1707,7 +1707,7 @@ if test -n "$ac_init_help"; then case $ac_init_help in - short | recursive ) echo "Configuration of Squid Web Proxy 3.5.15:";; + short | recursive ) echo "Configuration of Squid Web Proxy 3.5.16:";; esac cat <<\_ACEOF @@ -2119,7 +2119,7 @@ test -n "$ac_init_help" && exit $ac_status if $ac_init_version; then cat <<\_ACEOF -Squid Web Proxy configure 3.5.15 +Squid Web Proxy configure 3.5.16 generated by GNU Autoconf 2.69 Copyright (C) 2012 Free Software Foundation, Inc. @@ -3223,7 +3223,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 3.5.15, which was +It was created by Squid Web Proxy $as_me 3.5.16, which was generated by GNU Autoconf 2.69. Invocation command line was $ $0 $@ @@ -4090,7 +4090,7 @@ # Define the identity of the package. PACKAGE='squid' - VERSION='3.5.15' + VERSION='3.5.16' cat >>confdefs.h <<_ACEOF @@ -20688,7 +20688,7 @@ SQUID_CFLAGS="$squid_cv_cc_option_wall -Wpointer-arith -Wwrite-strings -Wmissing-prototypes -Wmissing-declarations -Wcomments -Wshadow" ;; esac - SQUID_CXXFLAGS="$squid_cv_cc_option_wall -Wpointer-arith -Wwrite-strings -Wcomments -Wshadow" + SQUID_CXXFLAGS="$squid_cv_cc_option_wall -Wpointer-arith -Wwrite-strings -Wcomments -Wshadow -Woverloaded-virtual" else SQUID_CFLAGS= SQUID_CXXFLAGS= @@ -21804,15 +21804,18 @@ fi ;; rock) - if test "x$squid_disk_module_candidates_IpcIo" != "xyes" -a \ - "x$squid_disk_module_candidates_Blocking" != "xyes"; then - as_fn_error $? "Storage module Rock requires IpcIo or Blocking DiskIO module" "$LINENO" 5 - fi - squid_do_build_rock=true - ;; + if test "x$squid_disk_module_candidates_IpcIo" != "xyes" -a \ + "x$squid_disk_module_candidates_Blocking" != "xyes"; then + as_fn_error $? "Storage module Rock requires DiskIO module: Blocking or IpcIo" "$LINENO" 5 + fi + squid_do_build_rock=true + ;; ufs) - squid_do_build_ufs=true - ;; + if test "x$squid_disk_module_candidates_Blocking" != "xyes"; then + as_fn_error $? "Storage module ufs requires DiskIO module: Blocking" "$LINENO" 5 + fi + squid_do_build_ufs=true + ;; esac done @@ -27731,7 +27734,7 @@ squid_pc_krb5_name="heimdal-gssapi" fi fi - if test "x$squid_pc_krb5_name" != "x" -a "$cross_compiling" = "no"; then + if test "x$squid_pc_krb5_name" = "x" -a "$cross_compiling" = "no"; then # Look for krb5-config (unless cross-compiling) # Extract the first word of "krb5-config", so it can be a program name with args. set dummy krb5-config; ac_word=$2 @@ -27777,7 +27780,7 @@ if test "x$ac_cv_path_krb5_config" != "xno" ; then krb5confpath="`dirname $ac_cv_path_krb5_config`" ac_heimdal="`$ac_cv_path_krb5_config --version 2>/dev/null | grep -c -i heimdal`" - if test "x$with_heimdal_krb5" = "xyes"; then + if test "x$with_heimdal_krb5" = "xyes" -a $ac_heimdal = 0; then as_fn_error $? "Could not find pkg-config or krb5-config for Heimdal Kerberos" "$LINENO" 5 fi else @@ -41869,7 +41872,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 3.5.15, which was +This file was extended by Squid Web Proxy $as_me 3.5.16, which was generated by GNU Autoconf 2.69. Invocation command line was CONFIG_FILES = $CONFIG_FILES @@ -41935,7 +41938,7 @@ cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`" ac_cs_version="\\ -Squid Web Proxy config.status 3.5.15 +Squid Web Proxy config.status 3.5.16 configured by $0, generated by GNU Autoconf 2.69, with options \\"\$ac_cs_config\\" diff -u -r -N squid-3.5.15/configure.ac squid-3.5.16/configure.ac --- squid-3.5.15/configure.ac 2016-02-24 05:28:54.000000000 +1300 +++ squid-3.5.16/configure.ac 2016-04-02 10:06:41.000000000 +1300 @@ -5,7 +5,7 @@ ## Please see the COPYING and CONTRIBUTORS files for details. ## -AC_INIT([Squid Web Proxy],[3.5.15],[http://bugs.squid-cache.org/],[squid]) +AC_INIT([Squid Web Proxy],[3.5.16],[http://bugs.squid-cache.org/],[squid]) AC_PREREQ(2.61) AC_CONFIG_HEADERS([include/autoconf.h]) AC_CONFIG_AUX_DIR(cfgaux) @@ -371,7 +371,7 @@ SQUID_CFLAGS="$squid_cv_cc_option_wall -Wpointer-arith -Wwrite-strings -Wmissing-prototypes -Wmissing-declarations -Wcomments -Wshadow" ;; esac - SQUID_CXXFLAGS="$squid_cv_cc_option_wall -Wpointer-arith -Wwrite-strings -Wcomments -Wshadow" + SQUID_CXXFLAGS="$squid_cv_cc_option_wall -Wpointer-arith -Wwrite-strings -Wcomments -Wshadow -Woverloaded-virtual" else SQUID_CFLAGS= SQUID_CXXFLAGS= @@ -833,15 +833,18 @@ fi ;; rock) - if test "x$squid_disk_module_candidates_IpcIo" != "xyes" -a \ - "x$squid_disk_module_candidates_Blocking" != "xyes"; then - AC_MSG_ERROR([Storage module Rock requires IpcIo or Blocking DiskIO module]) - fi - squid_do_build_rock=true - ;; + if test "x$squid_disk_module_candidates_IpcIo" != "xyes" -a \ + "x$squid_disk_module_candidates_Blocking" != "xyes"; then + AC_MSG_ERROR([Storage module Rock requires DiskIO module: Blocking or IpcIo]) + fi + squid_do_build_rock=true + ;; ufs) - squid_do_build_ufs=true - ;; + if test "x$squid_disk_module_candidates_Blocking" != "xyes"; then + AC_MSG_ERROR([Storage module ufs requires DiskIO module: Blocking]) + fi + squid_do_build_ufs=true + ;; esac done @@ -1640,13 +1643,13 @@ if test "x$squid_pc_krb5_name" = "x"; then PKG_CHECK_EXISTS(heimdal-gssapi, [squid_pc_krb5_name="heimdal-gssapi"]) fi - if test "x$squid_pc_krb5_name" != "x" -a "$cross_compiling" = "no"; then + if test "x$squid_pc_krb5_name" = "x" -a "$cross_compiling" = "no"; then # Look for krb5-config (unless cross-compiling) AC_PATH_PROG(krb5_config,krb5-config,no) if test "x$ac_cv_path_krb5_config" != "xno" ; then krb5confpath="`dirname $ac_cv_path_krb5_config`" ac_heimdal="`$ac_cv_path_krb5_config --version 2>/dev/null | grep -c -i heimdal`" - if test "x$with_heimdal_krb5" = "xyes"; then + if test "x$with_heimdal_krb5" = "xyes" -a $ac_heimdal = 0; then AC_MSG_ERROR([Could not find pkg-config or krb5-config for Heimdal Kerberos]) fi else diff -u -r -N squid-3.5.15/doc/release-notes/release-3.5.html squid-3.5.16/doc/release-notes/release-3.5.html --- squid-3.5.15/doc/release-notes/release-3.5.html 2016-02-24 06:14:19.000000000 +1300 +++ squid-3.5.16/doc/release-notes/release-3.5.html 2016-04-02 11:42:35.000000000 +1300 @@ -2,10 +2,10 @@ - Squid 3.5.15 release notes + Squid 3.5.16 release notes -

Squid 3.5.15 release notes

+

Squid 3.5.16 release notes

Squid Developers


@@ -64,7 +64,7 @@

1. Notice

-

The Squid Team are pleased to announce the release of Squid-3.5.15.

+

The Squid Team are pleased to announce the release of Squid-3.5.16.

This new release is available for download from http://www.squid-cache.org/Versions/v3/3.5/ or the mirrors.

diff -u -r -N squid-3.5.15/helpers/basic_auth/DB/basic_db_auth.8 squid-3.5.16/helpers/basic_auth/DB/basic_db_auth.8 --- squid-3.5.15/helpers/basic_auth/DB/basic_db_auth.8 2016-02-24 06:14:23.000000000 +1300 +++ squid-3.5.16/helpers/basic_auth/DB/basic_db_auth.8 2016-04-02 11:42:44.000000000 +1300 @@ -133,7 +133,7 @@ .\" ======================================================================== .\" .IX Title "BASIC_DB_AUTH 8" -.TH BASIC_DB_AUTH 8 "2016-02-23" "perl v5.22.1" "User Contributed Perl Documentation" +.TH BASIC_DB_AUTH 8 "2016-04-01" "perl v5.22.1" "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-3.5.15/helpers/basic_auth/MSNT-multi-domain/basic_msnt_multi_domain_auth.8 squid-3.5.16/helpers/basic_auth/MSNT-multi-domain/basic_msnt_multi_domain_auth.8 --- squid-3.5.15/helpers/basic_auth/MSNT-multi-domain/basic_msnt_multi_domain_auth.8 2016-02-24 06:14:29.000000000 +1300 +++ squid-3.5.16/helpers/basic_auth/MSNT-multi-domain/basic_msnt_multi_domain_auth.8 2016-04-02 11:42:55.000000000 +1300 @@ -133,7 +133,7 @@ .\" ======================================================================== .\" .IX Title "BASIC_MSNT_MULTI_DOMAIN_AUTH 1" -.TH BASIC_MSNT_MULTI_DOMAIN_AUTH 1 "2016-02-23" "perl v5.22.1" "User Contributed Perl Documentation" +.TH BASIC_MSNT_MULTI_DOMAIN_AUTH 1 "2016-04-01" "perl v5.22.1" "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-3.5.15/helpers/basic_auth/POP3/basic_pop3_auth.8 squid-3.5.16/helpers/basic_auth/POP3/basic_pop3_auth.8 --- squid-3.5.15/helpers/basic_auth/POP3/basic_pop3_auth.8 2016-02-24 06:14:33.000000000 +1300 +++ squid-3.5.16/helpers/basic_auth/POP3/basic_pop3_auth.8 2016-04-02 11:43:05.000000000 +1300 @@ -133,7 +133,7 @@ .\" ======================================================================== .\" .IX Title "BASIC_POP3_AUTH 8" -.TH BASIC_POP3_AUTH 8 "2016-02-23" "perl v5.22.1" "User Contributed Perl Documentation" +.TH BASIC_POP3_AUTH 8 "2016-04-01" "perl v5.22.1" "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-3.5.15/helpers/external_acl/delayer/ext_delayer_acl.8 squid-3.5.16/helpers/external_acl/delayer/ext_delayer_acl.8 --- squid-3.5.15/helpers/external_acl/delayer/ext_delayer_acl.8 2016-02-24 06:14:47.000000000 +1300 +++ squid-3.5.16/helpers/external_acl/delayer/ext_delayer_acl.8 2016-04-02 11:43:27.000000000 +1300 @@ -133,7 +133,7 @@ .\" ======================================================================== .\" .IX Title "EXT_DELAYER_ACL 8" -.TH EXT_DELAYER_ACL 8 "2016-02-23" "perl v5.22.1" "User Contributed Perl Documentation" +.TH EXT_DELAYER_ACL 8 "2016-04-01" "perl v5.22.1" "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-3.5.15/helpers/external_acl/SQL_session/ext_sql_session_acl.8 squid-3.5.16/helpers/external_acl/SQL_session/ext_sql_session_acl.8 --- squid-3.5.15/helpers/external_acl/SQL_session/ext_sql_session_acl.8 2016-02-24 06:14:54.000000000 +1300 +++ squid-3.5.16/helpers/external_acl/SQL_session/ext_sql_session_acl.8 2016-04-02 11:43:41.000000000 +1300 @@ -133,7 +133,7 @@ .\" ======================================================================== .\" .IX Title "EXT_SQL_SESSION_ACL 8" -.TH EXT_SQL_SESSION_ACL 8 "2016-02-23" "perl v5.22.1" "User Contributed Perl Documentation" +.TH EXT_SQL_SESSION_ACL 8 "2016-04-01" "perl v5.22.1" "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-3.5.15/helpers/external_acl/wbinfo_group/ext_wbinfo_group_acl.8 squid-3.5.16/helpers/external_acl/wbinfo_group/ext_wbinfo_group_acl.8 --- squid-3.5.15/helpers/external_acl/wbinfo_group/ext_wbinfo_group_acl.8 2016-02-24 06:14:57.000000000 +1300 +++ squid-3.5.16/helpers/external_acl/wbinfo_group/ext_wbinfo_group_acl.8 2016-04-02 11:43:47.000000000 +1300 @@ -133,7 +133,7 @@ .\" ======================================================================== .\" .IX Title "EXT_WBINFO_GROUP_ACL 8" -.TH EXT_WBINFO_GROUP_ACL 8 "2016-02-23" "perl v5.22.1" "User Contributed Perl Documentation" +.TH EXT_WBINFO_GROUP_ACL 8 "2016-04-01" "perl v5.22.1" "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-3.5.15/helpers/log_daemon/DB/log_db_daemon.8 squid-3.5.16/helpers/log_daemon/DB/log_db_daemon.8 --- squid-3.5.15/helpers/log_daemon/DB/log_db_daemon.8 2016-02-24 06:14:59.000000000 +1300 +++ squid-3.5.16/helpers/log_daemon/DB/log_db_daemon.8 2016-04-02 11:43:51.000000000 +1300 @@ -133,7 +133,7 @@ .\" ======================================================================== .\" .IX Title "LOG_DB_DAEMON 8" -.TH LOG_DB_DAEMON 8 "2016-02-23" "perl v5.22.1" "User Contributed Perl Documentation" +.TH LOG_DB_DAEMON 8 "2016-04-01" "perl v5.22.1" "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-3.5.15/helpers/storeid_rewrite/file/storeid_file_rewrite.8 squid-3.5.16/helpers/storeid_rewrite/file/storeid_file_rewrite.8 --- squid-3.5.15/helpers/storeid_rewrite/file/storeid_file_rewrite.8 2016-02-24 06:15:12.000000000 +1300 +++ squid-3.5.16/helpers/storeid_rewrite/file/storeid_file_rewrite.8 2016-04-02 11:44:15.000000000 +1300 @@ -133,7 +133,7 @@ .\" ======================================================================== .\" .IX Title "STOREID_FILE_REWRITE 8" -.TH STOREID_FILE_REWRITE 8 "2016-02-23" "perl v5.22.1" "User Contributed Perl Documentation" +.TH STOREID_FILE_REWRITE 8 "2016-04-01" "perl v5.22.1" "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-3.5.15/include/version.h squid-3.5.16/include/version.h --- squid-3.5.15/include/version.h 2016-02-24 05:28:55.000000000 +1300 +++ squid-3.5.16/include/version.h 2016-04-02 10:06:42.000000000 +1300 @@ -7,7 +7,7 @@ */ #ifndef SQUID_RELEASE_TIME -#define SQUID_RELEASE_TIME 1456244734 +#define SQUID_RELEASE_TIME 1459544569 #endif /* diff -u -r -N squid-3.5.15/RELEASENOTES.html squid-3.5.16/RELEASENOTES.html --- squid-3.5.15/RELEASENOTES.html 2016-02-24 06:14:19.000000000 +1300 +++ squid-3.5.16/RELEASENOTES.html 2016-04-02 11:42:35.000000000 +1300 @@ -2,10 +2,10 @@ - Squid 3.5.15 release notes + Squid 3.5.16 release notes -

Squid 3.5.15 release notes

+

Squid 3.5.16 release notes

Squid Developers


@@ -64,7 +64,7 @@

1. Notice

-

The Squid Team are pleased to announce the release of Squid-3.5.15.

+

The Squid Team are pleased to announce the release of Squid-3.5.16.

This new release is available for download from http://www.squid-cache.org/Versions/v3/3.5/ or the mirrors.

diff -u -r -N squid-3.5.15/src/acl/Asn.cc squid-3.5.16/src/acl/Asn.cc --- squid-3.5.15/src/acl/Asn.cc 2016-02-24 05:25:46.000000000 +1300 +++ squid-3.5.16/src/acl/Asn.cc 2016-04-02 10:02:59.000000000 +1300 @@ -26,7 +26,6 @@ #include "SquidConfig.h" #include "Store.h" #include "StoreClient.h" -#include "StoreClient.h" #define WHOIS_PORT 43 #define AS_REQBUF_SZ 4096 diff -u -r -N squid-3.5.15/src/clients/Client.h squid-3.5.16/src/clients/Client.h --- squid-3.5.15/src/clients/Client.h 2016-02-24 05:25:46.000000000 +1300 +++ squid-3.5.16/src/clients/Client.h 2016-04-02 10:02:59.000000000 +1300 @@ -104,7 +104,9 @@ virtual void sentRequestBody(const CommIoCbParams &io) = 0; virtual void doneSendingRequestBody() = 0; - virtual void closeServer() = 0; /**< end communication with the server */ + /// Use this to end communication with the server. The call cancels our + /// closure handler and tells FwdState to forget about the connection. + virtual void closeServer() = 0; virtual bool doneWithServer() const = 0; /**< did we end communication? */ /// whether we may receive more virgin response body bytes virtual bool mayReadVirginReplyBody() const = 0; diff -u -r -N squid-3.5.15/src/clients/FtpRelay.cc squid-3.5.16/src/clients/FtpRelay.cc --- squid-3.5.15/src/clients/FtpRelay.cc 2016-02-24 05:25:46.000000000 +1300 +++ squid-3.5.16/src/clients/FtpRelay.cc 2016-04-02 10:02:59.000000000 +1300 @@ -42,7 +42,7 @@ void serverState(const Ftp::ServerState newState); /* Ftp::Client API */ - virtual void failed(err_type error = ERR_NONE, int xerrno = 0); + virtual void failed(err_type error = ERR_NONE, int xerrno = 0, ErrorState *ftperr = NULL); virtual void dataChannelConnected(const CommConnectCbParams &io); /* Client API */ @@ -56,6 +56,7 @@ /* AsyncJob API */ virtual void start(); + virtual void swanSong(); void forwardReply(); void forwardError(err_type error = ERR_NONE, int xerrno = 0); @@ -87,12 +88,18 @@ void readUserOrPassReply(); void scheduleReadControlReply(); - void finalizeDataDownload(); + + /// Inform Ftp::Server that we are done if originWaitInProgress + void stopOriginWait(int code); static void abort(void *d); // TODO: Capitalize this and FwdState::abort(). bool forwardingCompleted; ///< completeForwarding() has been called + /// whether we are between Ftp::Server::startWaitingForOrigin() and + /// Ftp::Server::stopWaitingForOrigin() calls + bool originWaitInProgress; + struct { wordlist *message; ///< reply message, one wordlist entry per message line char *lastCommand; ///< the command caused the reply @@ -142,7 +149,8 @@ AsyncJob("Ftp::Relay"), Ftp::Client(fwdState), thePreliminaryCb(NULL), - forwardingCompleted(false) + forwardingCompleted(false), + originWaitInProgress(false) { savedReply.message = NULL; savedReply.lastCommand = NULL; @@ -178,11 +186,20 @@ sendCommand(); } +void +Ftp::Relay::swanSong() +{ + stopOriginWait(0); + Ftp::Client::swanSong(); +} + /// Keep control connection for future requests, after we are done with it. /// Similar to COMPLETE_PERSISTENT_MSG handling in http.cc. void Ftp::Relay::serverComplete() { + stopOriginWait(ctrl.replycode); + CbcPointer &mgr = fwd->request->clientConnectionManager; if (mgr.valid()) { if (Comm::IsConnOpen(ctrl.conn)) { @@ -255,7 +272,7 @@ } void -Ftp::Relay::failed(err_type error, int xerrno) +Ftp::Relay::failed(err_type error, int xerrno, ErrorState *ftpErr) { if (!doneWithServer()) serverState(fssError); @@ -264,7 +281,7 @@ if (entry->isEmpty()) failedErrorMessage(error, xerrno); // as a reply - Ftp::Client::failed(error, xerrno); + Ftp::Client::failed(error, xerrno, ftpErr); } void @@ -527,6 +544,19 @@ serverState() == fssConnected ? SENT_USER : serverState() == fssHandlePass ? SENT_PASS : SENT_COMMAND; + + if (state == SENT_DATA_REQUEST) { + CbcPointer &mgr = fwd->request->clientConnectionManager; + if (mgr.valid()) { + if (Ftp::Server *srv = dynamic_cast(mgr.get())) { + typedef NullaryMemFunT CbDialer; + AsyncCall::Pointer call = JobCallback(11, 3, CbDialer, srv, + Ftp::Server::startWaitingForOrigin); + ScheduleCallHere(call); + originWaitInProgress = true; + } + } + } } void @@ -683,7 +713,9 @@ " after reading response data"); } - finalizeDataDownload(); + debugs(9, 2, "Complete data downloading"); + + serverComplete(); } void @@ -711,25 +743,6 @@ Ftp::Client::scheduleReadControlReply(0); } -void -Ftp::Relay::finalizeDataDownload() -{ - debugs(9, 2, "Complete data downloading/Uploading"); - - updateMaster().waitForOriginData = false; - - CbcPointer &mgr = fwd->request->clientConnectionManager; - if (mgr.valid()) { - if (Ftp::Server *srv = dynamic_cast(mgr.get())) { - typedef NullaryMemFunT CbDialer; - AsyncCall::Pointer call = JobCallback(11, 3, CbDialer, srv, - Ftp::Server::originDataCompletionCheckpoint); - ScheduleCallHere(call); - } - } - serverComplete(); -} - bool Ftp::Relay::abortOnData(const char *reason) { @@ -750,6 +763,23 @@ } void +Ftp::Relay::stopOriginWait(int code) +{ + if (originWaitInProgress) { + CbcPointer &mgr = fwd->request->clientConnectionManager; + if (mgr.valid()) { + if (Ftp::Server *srv = dynamic_cast(mgr.get())) { + typedef UnaryMemFunT CbDialer; + AsyncCall::Pointer call = asyncCall(11, 3, "Ftp::Server::stopWaitingForOrigin", + CbDialer(srv, &Ftp::Server::stopWaitingForOrigin, code)); + ScheduleCallHere(call); + } + } + originWaitInProgress = false; + } +} + +void Ftp::Relay::abort(void *d) { Ftp::Relay *ftpClient = (Ftp::Relay *)d; diff -u -r -N squid-3.5.15/src/client_side.cc squid-3.5.16/src/client_side.cc --- squid-3.5.15/src/client_side.cc 2016-02-24 05:25:46.000000000 +1300 +++ squid-3.5.16/src/client_side.cc 2016-04-02 10:02:59.000000000 +1300 @@ -639,6 +639,7 @@ } if (request) { + HTTPMSGUNLOCK(al->adapted_request); al->adapted_request = request; HTTPMSGLOCK(al->adapted_request); } @@ -4683,20 +4684,19 @@ int varyEvaluateMatch(StoreEntry * entry, HttpRequest * request) { - const char *vary = request->vary_headers; + SBuf vary(request->vary_headers); int has_vary = entry->getReply()->header.has(HDR_VARY); #if X_ACCELERATOR_VARY - has_vary |= entry->getReply()->header.has(HDR_X_ACCELERATOR_VARY); #endif - if (!has_vary || !entry->mem_obj->vary_headers) { - if (vary) { + if (!has_vary || entry->mem_obj->vary_headers.isEmpty()) { + if (!vary.isEmpty()) { /* Oops... something odd is going on here.. */ debugs(33, DBG_IMPORTANT, "varyEvaluateMatch: Oops. Not a Vary object on second attempt, '" << entry->mem_obj->urlXXX() << "' '" << vary << "'"); - safe_free(request->vary_headers); + request->vary_headers.clear(); return VARY_CANCEL; } @@ -4710,8 +4710,8 @@ */ vary = httpMakeVaryMark(request, entry->getReply()); - if (vary) { - request->vary_headers = xstrdup(vary); + if (!vary.isEmpty()) { + request->vary_headers = vary; return VARY_OTHER; } else { /* Ouch.. we cannot handle this kind of variance */ @@ -4719,18 +4719,18 @@ return VARY_CANCEL; } } else { - if (!vary) { + if (vary.isEmpty()) { vary = httpMakeVaryMark(request, entry->getReply()); - if (vary) - request->vary_headers = xstrdup(vary); + if (!vary.isEmpty()) + request->vary_headers = vary; } - if (!vary) { + if (vary.isEmpty()) { /* Ouch.. we cannot handle this kind of variance */ /* XXX This cannot really happen, but just to be complete */ return VARY_CANCEL; - } else if (strcmp(vary, entry->mem_obj->vary_headers) == 0) { + } else if (vary.cmp(entry->mem_obj->vary_headers) == 0) { return VARY_MATCH; } else { /* Oops.. we have already been here and still haven't diff -u -r -N squid-3.5.15/src/client_side_reply.cc squid-3.5.16/src/client_side_reply.cc --- squid-3.5.15/src/client_side_reply.cc 2016-02-24 05:25:46.000000000 +1300 +++ squid-3.5.16/src/client_side_reply.cc 2016-04-02 10:02:59.000000000 +1300 @@ -20,7 +20,6 @@ #include "format/Token.h" #include "FwdState.h" #include "globals.h" -#include "globals.h" #include "HttpHeaderTools.h" #include "HttpReply.h" #include "HttpRequest.h" @@ -988,9 +987,8 @@ } /* And for Vary, release the base URI if none of the headers was included in the request */ - - if (http->request->vary_headers - && !strstr(http->request->vary_headers, "=")) { + if (!http->request->vary_headers.isEmpty() + && http->request->vary_headers.find('=') != SBuf::npos) { StoreEntry *entry = storeGetPublic(urlCanonical(http->request), Http::METHOD_GET); if (entry) { diff -u -r -N squid-3.5.15/src/comm.cc squid-3.5.16/src/comm.cc --- squid-3.5.15/src/comm.cc 2016-02-24 05:25:46.000000000 +1300 +++ squid-3.5.16/src/comm.cc 2016-04-02 10:02:59.000000000 +1300 @@ -976,7 +976,7 @@ return Comm::COMM_ERROR; } -void +AsyncCall::Pointer comm_add_close_handler(int fd, CLCB * handler, void *data) { debugs(5, 5, "comm_add_close_handler: FD " << fd << ", handler=" << @@ -985,6 +985,7 @@ AsyncCall::Pointer call=commCbCall(5,4, "SomeCloseHandler", CommCloseCbPtrFun(handler, data)); comm_add_close_handler(fd, call); + return call; } void diff -u -r -N squid-3.5.15/src/comm.h squid-3.5.16/src/comm.h --- squid-3.5.15/src/comm.h 2016-02-24 05:25:46.000000000 +1300 +++ squid-3.5.16/src/comm.h 2016-04-02 10:02:59.000000000 +1300 @@ -79,7 +79,7 @@ void commCloseAllSockets(void); void checkTimeouts(void); -void comm_add_close_handler(int fd, CLCB *, void *); +AsyncCall::Pointer comm_add_close_handler(int fd, CLCB *, void *); void comm_add_close_handler(int fd, AsyncCall::Pointer &); void comm_remove_close_handler(int fd, CLCB *, void *); void comm_remove_close_handler(int fd, AsyncCall::Pointer &); diff -u -r -N squid-3.5.15/src/debug.cc squid-3.5.16/src/debug.cc --- squid-3.5.15/src/debug.cc 2016-02-24 05:25:46.000000000 +1300 +++ squid-3.5.16/src/debug.cc 2016-04-02 10:02:59.000000000 +1300 @@ -222,7 +222,14 @@ if (debug_log && debug_log != stderr) fclose(debug_log); - debug_log = fopen(logfile, "a+"); + // Bug 4423: ignore the stdio: logging module name if present + const char *logfilename; + if (strncmp(logfile, "stdio:",6) == 0) + logfilename = logfile + 6; + else + logfilename = logfile; + + debug_log = fopen(logfilename, "a+"); if (!debug_log) { fprintf(stderr, "WARNING: Cannot write log file: %s\n", logfile); diff -u -r -N squid-3.5.15/src/eui/Eui48.cc squid-3.5.16/src/eui/Eui48.cc --- squid-3.5.15/src/eui/Eui48.cc 2016-02-24 05:25:46.000000000 +1300 +++ squid-3.5.16/src/eui/Eui48.cc 2016-04-02 10:02:59.000000000 +1300 @@ -181,6 +181,7 @@ close(tmpSocket); if (arpReq.arp_ha.sa_family != ARPHRD_ETHER) { + debugs(28, 4, "id=" << (void*)this << " ... not an Ethernet interface: " << arpReq.arp_ha.sa_data); clear(); return false; } diff -u -r -N squid-3.5.15/src/FwdState.cc squid-3.5.16/src/FwdState.cc --- squid-3.5.15/src/FwdState.cc 2016-02-24 05:25:46.000000000 +1300 +++ squid-3.5.16/src/FwdState.cc 2016-04-02 10:02:59.000000000 +1300 @@ -119,7 +119,8 @@ FwdState::closeServerConnection(const char *reason) { debugs(17, 3, "because " << reason << "; " << serverConn); - comm_remove_close_handler(serverConn->fd, fwdServerClosedWrapper, this); + comm_remove_close_handler(serverConn->fd, closeHandler); + closeHandler = NULL; fwdPconnPool->noteUses(fd_table[serverConn->fd].pconn.uses); serverConn->close(); } @@ -446,7 +447,8 @@ debugs(17, 3, HERE << entry->url() ); assert(serverConnection() == conn); assert(Comm::IsConnOpen(conn)); - comm_remove_close_handler(conn->fd, fwdServerClosedWrapper, this); + comm_remove_close_handler(conn->fd, closeHandler); + closeHandler = NULL; serverConn = NULL; } @@ -677,7 +679,7 @@ serverConn = conn; debugs(17, 3, HERE << serverConnection() << ": '" << entry->url() << "'" ); - comm_add_close_handler(serverConnection()->fd, fwdServerClosedWrapper, this); + closeHandler = comm_add_close_handler(serverConnection()->fd, fwdServerClosedWrapper, this); #if USE_OPENSSL if (!request->flags.pinned) { @@ -833,7 +835,8 @@ request->flags.pinned = true; if (pinned_connection->pinnedAuth()) request->flags.auth = true; - comm_add_close_handler(serverConn->fd, fwdServerClosedWrapper, this); + + closeHandler = comm_add_close_handler(serverConn->fd, fwdServerClosedWrapper, this); syncWithServerConn(pinned_connection->pinning.host); @@ -872,7 +875,7 @@ debugs(17, 3, HERE << "reusing pconn " << serverConnection()); ++n_tries; - comm_add_close_handler(serverConnection()->fd, fwdServerClosedWrapper, this); + closeHandler = comm_add_close_handler(serverConnection()->fd, fwdServerClosedWrapper, this); syncWithServerConn(request->GetHost()); diff -u -r -N squid-3.5.15/src/FwdState.h squid-3.5.16/src/FwdState.h --- squid-3.5.15/src/FwdState.h 2016-02-24 05:25:46.000000000 +1300 +++ squid-3.5.16/src/FwdState.h 2016-04-02 10:02:59.000000000 +1300 @@ -152,6 +152,8 @@ Comm::ConnectionPointer serverConn; ///< a successfully opened connection to a server. + AsyncCall::Pointer closeHandler; ///< The serverConn close handler + /// possible pconn race states typedef enum { raceImpossible, racePossible, raceHappened } PconnRace; PconnRace pconnRace; ///< current pconn race state diff -u -r -N squid-3.5.15/src/http/StatusCode.cc squid-3.5.16/src/http/StatusCode.cc --- squid-3.5.15/src/http/StatusCode.cc 2016-02-24 05:25:46.000000000 +1300 +++ squid-3.5.16/src/http/StatusCode.cc 2016-04-02 10:02:59.000000000 +1300 @@ -212,6 +212,10 @@ return "Request Header Fields Too Large"; break; + case scUnavailableForLegalReasons: + return "Unavailable For Legal Reasons"; + break; + // 500-599 case Http::scInternalServerError: return "Internal Server Error"; diff -u -r -N squid-3.5.15/src/http/StatusCode.h squid-3.5.16/src/http/StatusCode.h --- squid-3.5.15/src/http/StatusCode.h 2016-02-24 05:25:46.000000000 +1300 +++ squid-3.5.16/src/http/StatusCode.h 2016-04-02 10:02:59.000000000 +1300 @@ -66,6 +66,7 @@ scPreconditionRequired = 428, /**< RFC6585 */ scTooManyRequests = 429, /**< RFC6585 */ scRequestHeaderFieldsTooLarge = 431, /**< RFC6585 */ + scUnavailableForLegalReasons = 451, /**< RFC7725 */ scInternalServerError = 500, scNotImplemented = 501, scBadGateway = 502, diff -u -r -N squid-3.5.15/src/http.cc squid-3.5.16/src/http.cc --- squid-3.5.15/src/http.cc 2016-02-24 05:25:46.000000000 +1300 +++ squid-3.5.16/src/http.cc 2016-04-02 10:02:59.000000000 +1300 @@ -165,7 +165,8 @@ fwd->fail(new ErrorState(ERR_READ_TIMEOUT, Http::scGatewayTimeout, fwd->request)); } - serverConnection->close(); + closeServer(); + mustStop("HttpStateData::httpTimeout"); } /// Remove an existing public store entry if the incoming response (to be @@ -574,9 +575,9 @@ /* * For Vary, store the relevant request headers as * virtual headers in the reply - * Returns false if the variance cannot be stored + * Returns an empty SBuf if the variance cannot be stored */ -const char * +SBuf httpMakeVaryMark(HttpRequest * request, HttpReply const * reply) { String vary, hdr; @@ -584,9 +585,9 @@ const char *item; const char *value; int ilen; - static String vstr; + SBuf vstr; + static const SBuf asterisk("*"); - vstr.clean(); vary = reply->header.getList(HDR_VARY); while (strListGetItem(&vary, ',', &item, &ilen, &pos)) { @@ -597,11 +598,13 @@ if (strcmp(name, "*") == 0) { /* Can not handle "Vary: *" withtout ETag support */ safe_free(name); - vstr.clean(); + vstr.clear(); break; } - strListAdd(&vstr, name, ','); + if (!vstr.isEmpty()) + vstr.append(", ", 2); + vstr.append(name); hdr = request->header.getByName(name); safe_free(name); value = hdr.termedBuf(); @@ -626,7 +629,17 @@ char *name = (char *)xmalloc(ilen + 1); xstrncpy(name, item, ilen + 1); Tolower(name); - strListAdd(&vstr, name, ','); + + if (strcmp(name, "*") == 0) { + /* Can not handle "Vary: *" withtout ETag support */ + safe_free(name); + vstr.clear(); + break; + } + + if (!vstr.isEmpty()) + vstr.append(", ", 2); + vstr.append(name); hdr = request->header.getByName(name); safe_free(name); value = hdr.termedBuf(); @@ -644,8 +657,8 @@ vary.clean(); #endif - debugs(11, 3, "httpMakeVaryMark: " << vstr); - return vstr.termedBuf(); + debugs(11, 3, vstr); + return vstr; } void @@ -915,15 +928,15 @@ || rep->header.has(HDR_X_ACCELERATOR_VARY) #endif ) { - const char *vary = httpMakeVaryMark(request, rep); + const SBuf vary(httpMakeVaryMark(request, rep)); - if (!vary) { + if (vary.isEmpty()) { entry->makePrivate(); if (!fwd->reforwardableStatus(rep->sline.status())) EBIT_CLR(entry->flags, ENTRY_FWD_HDR_WAIT); varyFailure = true; } else { - entry->mem_obj->vary_headers = xstrdup(vary); + entry->mem_obj->vary_headers = vary; } } @@ -1150,7 +1163,8 @@ err->xerrno = io.xerrno; fwd->fail(err); flags.do_next_read = false; - serverConnection->close(); + closeServer(); + mustStop("HttpStateData::readReply"); } return; @@ -1306,7 +1320,8 @@ entry->reset(); fwd->fail(new ErrorState(error, Http::scBadGateway, fwd->request)); flags.do_next_read = false; - serverConnection->close(); + closeServer(); + mustStop("HttpStateData::continueAfterParsingHeader"); return false; // quit on error } @@ -1540,7 +1555,8 @@ ErrorState *err = new ErrorState(ERR_WRITE_ERROR, Http::scBadGateway, fwd->request); err->xerrno = io.xerrno; fwd->fail(err); - serverConnection->close(); + closeServer(); + mustStop("HttpStateData::wroteLast"); return; } @@ -1568,7 +1584,6 @@ request->hier.peer_http_request_sent = current_time; } -// Close the HTTP server connection. Used by serverComplete(). void HttpStateData::closeServer() { @@ -2371,7 +2386,8 @@ debugs(11, DBG_IMPORTANT, "http handleMoreRequestBodyAvailable: Likely proxy abuse detected '" << request->client_addr << "' -> '" << entry->url() << "'" ); if (virginReply()->sline.status() == Http::scInvalidHeader) { - serverConnection->close(); + closeServer(); + mustStop("HttpStateData::handleMoreRequestBodyAvailable"); return; } } diff -u -r -N squid-3.5.15/src/http.h squid-3.5.16/src/http.h --- squid-3.5.15/src/http.h 2016-02-24 05:25:46.000000000 +1300 +++ squid-3.5.16/src/http.h 2016-04-02 10:02:59.000000000 +1300 @@ -12,6 +12,7 @@ #include "clients/Client.h" #include "comm.h" #include "HttpStateFlags.h" +#include "SBuf.h" class ChunkedCodingParser; class FwdState; @@ -117,7 +118,7 @@ int httpCachable(const HttpRequestMethod&); void httpStart(FwdState *); -const char *httpMakeVaryMark(HttpRequest * request, HttpReply const * reply); +SBuf httpMakeVaryMark(HttpRequest * request, HttpReply const * reply); #endif /* SQUID_HTTP_H */ diff -u -r -N squid-3.5.15/src/HttpMsg.cc squid-3.5.16/src/HttpMsg.cc --- squid-3.5.15/src/HttpMsg.cc 2016-02-24 05:25:46.000000000 +1300 +++ squid-3.5.16/src/HttpMsg.cc 2016-04-02 10:02:59.000000000 +1300 @@ -10,6 +10,7 @@ #include "squid.h" #include "Debug.h" +#include "HttpHdrCc.h" #include "HttpHeaderTools.h" #include "HttpMsg.h" #include "MemBuf.h" @@ -27,6 +28,25 @@ assert(!body_pipe); } +void +HttpMsg::putCc(const HttpHdrCc *otherCc) +{ + // get rid of the old CC, if any + if (cache_control) { + delete cache_control; + cache_control = NULL; + if (!otherCc) + header.delById(HDR_CACHE_CONTROL); + // else it will be deleted inside putCc() below + } + + // add new CC, if any + if (otherCc) { + cache_control = new HttpHdrCc(*otherCc); + header.putCc(cache_control); + } +} + HttpMsgParseState &operator++ (HttpMsgParseState &aState) { int tmp = (int)aState; diff -u -r -N squid-3.5.15/src/HttpMsg.h squid-3.5.16/src/HttpMsg.h --- squid-3.5.15/src/HttpMsg.h 2016-02-24 05:25:46.000000000 +1300 +++ squid-3.5.16/src/HttpMsg.h 2016-04-02 10:02:59.000000000 +1300 @@ -64,6 +64,9 @@ BodyPipe::Pointer body_pipe; // optional pipeline to receive message body + /// copies Cache-Control header to this message + void putCc(const HttpHdrCc *otherCc); + // returns true and sets hdr_sz on success // returns false and sets *error to zero when needs more data // returns false and sets *error to a positive Http::StatusCode on error diff -u -r -N squid-3.5.15/src/HttpReply.cc squid-3.5.16/src/HttpReply.cc --- squid-3.5.15/src/HttpReply.cc 2016-02-24 05:25:46.000000000 +1300 +++ squid-3.5.16/src/HttpReply.cc 2016-04-02 10:02:59.000000000 +1300 @@ -150,7 +150,6 @@ rv->last_modified = last_modified; rv->expires = expires; rv->content_type = content_type; - /* rv->cache_control */ /* rv->content_range */ /* rv->keep_alive */ rv->sline.set(Http::ProtocolVersion(1,1), Http::scNotModified, NULL); @@ -159,6 +158,8 @@ if ((e = header.findEntry(ImsEntries[t]))) rv->header.addEntry(e->clone()); + rv->putCc(cache_control); + /* rv->body */ return rv; } diff -u -r -N squid-3.5.15/src/HttpRequest.cc squid-3.5.16/src/HttpRequest.cc --- squid-3.5.15/src/HttpRequest.cc 2016-02-24 05:25:46.000000000 +1300 +++ squid-3.5.16/src/HttpRequest.cc 2016-04-02 10:02:59.000000000 +1300 @@ -92,7 +92,7 @@ peer_login = NULL; // not allocated/deallocated by this class peer_domain = NULL; // not allocated/deallocated by this class peer_host = NULL; - vary_headers = NULL; + vary_headers = SBuf(); myportname = null_string; tag = null_string; #if USE_AUTH @@ -124,9 +124,7 @@ auth_user_request = NULL; #endif safe_free(canonical); - - safe_free(vary_headers); - + vary_headers.clear(); url.clear(); urlpath.clean(); @@ -203,7 +201,7 @@ copy->lastmod = lastmod; copy->etag = etag; - copy->vary_headers = vary_headers ? xstrdup(vary_headers) : NULL; + copy->vary_headers = vary_headers; // XXX: what to do with copy->peer_domain? copy->tag = tag; diff -u -r -N squid-3.5.15/src/HttpRequest.h squid-3.5.16/src/HttpRequest.h --- squid-3.5.15/src/HttpRequest.h 2016-02-24 05:25:46.000000000 +1300 +++ squid-3.5.16/src/HttpRequest.h 2016-04-02 10:02:59.000000000 +1300 @@ -179,7 +179,8 @@ time_t lastmod; /* Used on refreshes */ - const char *vary_headers; /* Used when varying entities are detected. Changes how the store key is calculated */ + /// The variant second-stage cache key. Generated from Vary header pattern for this request. + SBuf vary_headers; char *peer_domain; /* Configured peer forceddomain */ diff -u -r -N squid-3.5.15/src/icmp/Icmp6.cc squid-3.5.16/src/icmp/Icmp6.cc --- squid-3.5.15/src/icmp/Icmp6.cc 2016-02-24 05:25:46.000000000 +1300 +++ squid-3.5.16/src/icmp/Icmp6.cc 2016-04-02 10:02:59.000000000 +1300 @@ -256,7 +256,7 @@ #define ip6_hops // HOPS!!! (can it be true??) ip = (struct ip6_hdr *) pkt; - pkt += sizeof(ip6_hdr); + NP: echo size needs to +sizeof(ip6_hdr); debugs(42, DBG_CRITICAL, HERE << "ip6_nxt=" << ip->ip6_nxt << ", ip6_plen=" << ip->ip6_plen << @@ -267,7 +267,6 @@ */ icmp6header = (struct icmp6_hdr *) pkt; - pkt += sizeof(icmp6_hdr); if (icmp6header->icmp6_type != ICMP6_ECHO_REPLY) { @@ -292,7 +291,7 @@ return; } - echo = (icmpEchoData *) pkt; + echo = (icmpEchoData *) (pkt + sizeof(icmp6_hdr)); preply.opcode = echo->opcode; diff -u -r -N squid-3.5.15/src/icmp/pinger.cc squid-3.5.16/src/icmp/pinger.cc --- squid-3.5.15/src/icmp/pinger.cc 2016-02-24 05:25:46.000000000 +1300 +++ squid-3.5.16/src/icmp/pinger.cc 2016-04-02 10:02:59.000000000 +1300 @@ -162,18 +162,46 @@ max_fd = max(max_fd, squid_link); if (setgid(getgid()) < 0) { - debugs(42, DBG_CRITICAL, "FATAL: pinger: setgid(" << getgid() << ") failed: " << xstrerror()); + int xerrno = errno; + debugs(42, DBG_CRITICAL, "FATAL: pinger: setgid(" << getgid() << ") failed: " << xstrerr(xerrno)); icmp4.Close(); icmp6.Close(); exit (1); } if (setuid(getuid()) < 0) { - debugs(42, DBG_CRITICAL, "FATAL: pinger: setuid(" << getuid() << ") failed: " << xstrerror()); + int xerrno = errno; + debugs(42, DBG_CRITICAL, "FATAL: pinger: setuid(" << getuid() << ") failed: " << xstrerr(xerrno)); icmp4.Close(); icmp6.Close(); exit (1); } +#if USE_LIBCAP + // Drop remaining capabilities (if installed as non-setuid setcap cap_net_raw=ep). + // If pinger binary was installed setuid root, setuid() above already dropped all + // capabilities, and this is no-op. + cap_t caps; + caps = cap_init(); + if (!caps) { + int xerrno = errno; + debugs(42, DBG_CRITICAL, "FATAL: pinger: cap_init() failed: " << xstrerr(xerrno)); + icmp4.Close(); + icmp6.Close(); + exit (1); + } else { + if (cap_set_proc(caps) != 0) { + int xerrno = errno; + // cap_set_proc(cap_init()) is expected to never fail + debugs(42, DBG_CRITICAL, "FATAL: pinger: cap_set_proc(none) failed: " << xstrerr(xerrno)); + cap_free(caps); + icmp4.Close(); + icmp6.Close(); + exit (1); + } + cap_free(caps); + } +#endif + last_check_time = squid_curtime; for (;;) { @@ -188,11 +216,12 @@ } FD_SET(squid_link, &R); - x = select(10, &R, NULL, NULL, &tv); + x = select(max_fd+1, &R, NULL, NULL, &tv); getCurrentTime(); if (x < 0) { - debugs(42, DBG_CRITICAL, HERE << " FATAL Shutdown. select()==" << x << ", ERR: " << xstrerror()); + int xerrno = errno; + debugs(42, DBG_CRITICAL, HERE << " FATAL Shutdown. select()==" << x << ", ERR: " << xstrerr(xerrno)); control.Close(); exit(1); } diff -u -r -N squid-3.5.15/src/log/access_log.cc squid-3.5.16/src/log/access_log.cc --- squid-3.5.15/src/log/access_log.cc 2016-02-24 05:25:46.000000000 +1300 +++ squid-3.5.16/src/log/access_log.cc 2016-04-02 10:02:59.000000000 +1300 @@ -17,8 +17,6 @@ #include "CachePeer.h" #include "err_detail_type.h" #include "errorpage.h" -#include "errorpage.h" -#include "errorpage.h" #include "format/Token.h" #include "globals.h" #include "hier_code.h" diff -u -r -N squid-3.5.15/src/main.cc squid-3.5.16/src/main.cc --- squid-3.5.15/src/main.cc 2016-02-24 05:25:46.000000000 +1300 +++ squid-3.5.16/src/main.cc 2016-04-02 10:02:59.000000000 +1300 @@ -1899,6 +1899,9 @@ WIN32_svcstatusupdate(SERVICE_STOP_PENDING, 10000); #endif +#if ICAP_CLIENT + Adaptation::Icap::TheConfig.freeService(); +#endif Store::Root().sync(); /* Flush pending object writes/unlinks */ diff -u -r -N squid-3.5.15/src/MemObject.cc squid-3.5.16/src/MemObject.cc --- squid-3.5.15/src/MemObject.cc 2016-02-24 05:25:46.000000000 +1300 +++ squid-3.5.16/src/MemObject.cc 2016-04-02 10:02:59.000000000 +1300 @@ -136,8 +136,6 @@ HTTPMSGUNLOCK(request); ctx_exit(ctx); /* must exit before we free mem->url */ - - safe_free(vary_headers); } void @@ -221,8 +219,8 @@ MemObject::stat(MemBuf * mb) const { mb->Printf("\t" SQUIDSBUFPH " %s\n", SQUIDSBUFPRINT(method.image()), logUri()); - if (vary_headers) - mb->Printf("\tvary_headers: %s\n", vary_headers); + if (!vary_headers.isEmpty()) + mb->Printf("\tvary_headers: " SQUIDSBUFPH "\n", SQUIDSBUFPRINT(vary_headers)); mb->Printf("\tinmem_lo: %" PRId64 "\n", inmem_lo); mb->Printf("\tinmem_hi: %" PRId64 "\n", data_hdr.endOffset()); mb->Printf("\tswapout: %" PRId64 " bytes queued\n", diff -u -r -N squid-3.5.15/src/MemObject.h squid-3.5.16/src/MemObject.h --- squid-3.5.15/src/MemObject.h 2016-02-24 05:25:46.000000000 +1300 +++ squid-3.5.16/src/MemObject.h 2016-04-02 10:02:59.000000000 +1300 @@ -13,6 +13,7 @@ #include "dlink.h" #include "HttpRequestMethod.h" #include "RemovalPolicy.h" +#include "SBuf.h" #include "stmem.h" #include "StoreIOBuffer.h" #include "StoreIOState.h" @@ -167,7 +168,7 @@ unsigned int chksum; #endif - const char *vary_headers; + SBuf vary_headers; void delayRead(DeferredRead const &); void kickReads(); diff -u -r -N squid-3.5.15/src/MemStore.cc squid-3.5.16/src/MemStore.cc --- squid-3.5.15/src/MemStore.cc 2016-02-24 05:25:46.000000000 +1300 +++ squid-3.5.16/src/MemStore.cc 2016-04-02 10:02:59.000000000 +1300 @@ -443,7 +443,7 @@ assert(e.mem_obj); - if (e.mem_obj->vary_headers) { + if (!e.mem_obj->vary_headers.isEmpty()) { // XXX: We must store/load SerialisedMetaData to cache Vary in RAM debugs(20, 5, "Vary not yet supported: " << e.mem_obj->vary_headers); return false; diff -u -r -N squid-3.5.15/src/servers/FtpServer.cc squid-3.5.16/src/servers/FtpServer.cc --- squid-3.5.15/src/servers/FtpServer.cc 2016-02-24 05:25:46.000000000 +1300 +++ squid-3.5.16/src/servers/FtpServer.cc 2016-04-02 10:02:59.000000000 +1300 @@ -59,7 +59,9 @@ uploadAvailSize(0), listener(), connector(), - reader() + reader(), + waitingForOrigin(false), + originDataDownloadAbortedOnError(false) { flags.readMore = false; // we need to announce ourselves first *uploadBuf = 0; @@ -1033,6 +1035,12 @@ { Must(reply); + if (waitingForOrigin) { + Must(delayedReply == NULL); + delayedReply = reply; + return; + } + const HttpHeader &header = reply->header; // adaptation and forwarding errors lack HDR_FTP_STATUS if (!header.has(HDR_FTP_STATUS)) { @@ -1489,8 +1497,8 @@ if (!checkDataConnPre()) return false; - master->waitForOriginData = true; master->userDataDone = 0; + originDataDownloadAbortedOnError = false; changeState(fssHandleDataRequest, "handleDataRequest"); @@ -1503,9 +1511,6 @@ if (!checkDataConnPre()) return false; - master->waitForOriginData = true; - master->userDataDone = 0; - changeState(fssHandleUploadRequest, "handleDataRequest"); return true; @@ -1705,14 +1710,46 @@ } void -Ftp::Server::originDataCompletionCheckpoint() +Ftp::Server::startWaitingForOrigin() { - if (!master->userDataDone) { - debugs(33, 5, "Transfering from/to client not finished yet"); - return; + debugs(33, 5, "waiting for Ftp::Client data transfer to end"); + waitingForOrigin = true; +} + +void +Ftp::Server::stopWaitingForOrigin(int originStatus) +{ + Must(waitingForOrigin); + waitingForOrigin = false; + + // if we have already decided how to respond, respond now + if (delayedReply != NULL) { + HttpReply::Pointer reply = delayedReply; + delayedReply = NULL; + writeForwardedReply(reply.getRaw()); + return; // do not completeDataDownload() after an earlier response } - completeDataExchange(); + if (master->serverState != fssHandleDataRequest) + return; + + // completeDataDownload() could be waitingForOrigin in fssHandleDataRequest + // Depending on which side has finished downloading first, either trust + // master->userDataDone status or set originDataDownloadAbortedOnError: + if (master->userDataDone) { + // We finished downloading before Ftp::Client. Most likely, the + // adaptation shortened the origin response or we hit an error. + // Our status (stored in master->userDataDone) is more informative. + // Use master->userDataDone; avoid originDataDownloadAbortedOnError. + completeDataDownload(); + } else { + debugs(33, 5, "too early to write the response"); + // Ftp::Client naturally finished downloading before us. Set + // originDataDownloadAbortedOnError to overwrite future + // master->userDataDone and relay Ftp::Client error, if there was + // any, to the user. + originDataDownloadAbortedOnError = (originStatus >= 400); + } } void Ftp::Server::userDataCompletionCheckpoint(int finalStatusCode) @@ -1723,23 +1760,24 @@ if (in.bodyParser) finishDechunkingRequest(false); - // The origin control connection is gone, nothing to wait for - if (!Comm::IsConnOpen(pinning.serverConnection)) - master->waitForOriginData = false; - - if (master->waitForOriginData) { - // The completeDataExchange() is not called here unconditionally + if (waitingForOrigin) { + // The completeDataDownload() is not called here unconditionally // because we want to signal the FTP user that we are not fully // done processing its data stream, even though all data bytes // have been sent or received already. - debugs(33, 5, "Transfering from/to FTP server is not complete"); + debugs(33, 5, "Transfering from FTP server is not complete"); return; } - completeDataExchange(); + // Adjust our reply if the server aborted with an error before we are done. + if (master->userDataDone == 226 && originDataDownloadAbortedOnError) { + debugs(33, 5, "Transfering from FTP server terminated with an error, adjust status code"); + master->userDataDone = 451; + } + completeDataDownload(); } -void Ftp::Server::completeDataExchange() +void Ftp::Server::completeDataDownload() { writeCustomReply(master->userDataDone, master->userDataDone == 226 ? "Transfer complete" : "Server error; transfer aborted"); closeDataConnection(); diff -u -r -N squid-3.5.15/src/servers/FtpServer.h squid-3.5.16/src/servers/FtpServer.h --- squid-3.5.15/src/servers/FtpServer.h 2016-02-24 05:25:46.000000000 +1300 +++ squid-3.5.16/src/servers/FtpServer.h 2016-04-02 10:02:59.000000000 +1300 @@ -41,7 +41,7 @@ public: typedef RefCount Pointer; - MasterState(): serverState(fssBegin), clientReadGreeting(false), userDataDone(0), waitForOriginData(false) {} + MasterState(): serverState(fssBegin), clientReadGreeting(false), userDataDone(0) {} Ip::Address clientDataAddr; ///< address of our FTP client data connection SBuf workingDir; ///< estimated current working directory for URI formation @@ -49,8 +49,6 @@ bool clientReadGreeting; ///< whether our FTP client read their FTP server greeting /// Squid will send or has sent this final status code to the FTP client int userDataDone; - /// whether the transfer on the Squid-origin data connection is not over yet - bool waitForOriginData; }; /// Manages a control connection from an FTP client. @@ -62,10 +60,14 @@ /* AsyncJob API */ virtual void callException(const std::exception &e); + /// Called by Ftp::Client class when it is start receiving or + /// sending data. + void startWaitingForOrigin(); + /// Called by Ftp::Client class when it is done receiving or /// sending data. Waits for both agents to be done before /// responding to the FTP client and closing the data connection. - void originDataCompletionCheckpoint(); + void stopWaitingForOrigin(int status); // This is a pointer in hope to minimize future changes when MasterState // becomes a part of MasterXaction. Guaranteed not to be nil. @@ -121,7 +123,7 @@ /// Writes the data-transfer status reply to the FTP client and /// closes the data connection. - void completeDataExchange(); + void completeDataDownload(); void calcUri(const SBuf *file); void changeState(const Ftp::ServerState newState, const char *reason); @@ -186,6 +188,14 @@ AsyncCall::Pointer connector; ///< set when we are actively connecting AsyncCall::Pointer reader; ///< set when we are reading FTP data + /// whether we wait for the origin data transfer to end + bool waitingForOrigin; + /// whether the origin data transfer aborted + bool originDataDownloadAbortedOnError; + + /// a response which writing was postponed until stopWaitingForOrigin() + HttpReply::Pointer delayedReply; + CBDATA_CLASS2(Server); }; diff -u -r -N squid-3.5.15/src/ssl/helper.cc squid-3.5.16/src/ssl/helper.cc --- squid-3.5.15/src/ssl/helper.cc 2016-02-24 05:25:46.000000000 +1300 +++ squid-3.5.16/src/ssl/helper.cc 2016-04-02 10:02:59.000000000 +1300 @@ -243,7 +243,8 @@ if (Ssl::CertValidationHelper::HelperCache && (validationResponse->resultCode == ::Helper::Okay || validationResponse->resultCode == ::Helper::Error)) { Ssl::CertValidationResponse::Pointer *item = new Ssl::CertValidationResponse::Pointer(validationResponse); - Ssl::CertValidationHelper::HelperCache->add(crtdvdData->query.c_str(), item); + if (!Ssl::CertValidationHelper::HelperCache->add(crtdvdData->query.c_str(), item)) + delete item; } SSL_free(crtdvdData->ssl); diff -u -r -N squid-3.5.15/src/store.cc squid-3.5.16/src/store.cc --- squid-3.5.15/src/store.cc 2016-02-24 05:25:46.000000000 +1300 +++ squid-3.5.16/src/store.cc 2016-04-02 10:02:59.000000000 +1300 @@ -34,7 +34,6 @@ #include "Store.h" #include "store_digest.h" #include "store_key_md5.h" -#include "store_key_md5.h" #include "store_log.h" #include "store_rebuild.h" #include "StoreClient.h" @@ -684,31 +683,27 @@ if (mem_obj->request) { HttpRequest *request = mem_obj->request; - if (!mem_obj->vary_headers) { + if (mem_obj->vary_headers.isEmpty()) { /* First handle the case where the object no longer varies */ - safe_free(request->vary_headers); + request->vary_headers.clear(); } else { - if (request->vary_headers && strcmp(request->vary_headers, mem_obj->vary_headers) != 0) { + if (!request->vary_headers.isEmpty() && request->vary_headers.cmp(mem_obj->vary_headers) != 0) { /* Oops.. the variance has changed. Kill the base object * to record the new variance key */ - safe_free(request->vary_headers); /* free old "bad" variance key */ + request->vary_headers.clear(); /* free old "bad" variance key */ if (StoreEntry *pe = storeGetPublic(mem_obj->storeId(), mem_obj->method)) pe->release(); } /* Make sure the request knows the variance status */ - if (!request->vary_headers) { - const char *vary = httpMakeVaryMark(request, mem_obj->getReply()); - - if (vary) - request->vary_headers = xstrdup(vary); - } + if (request->vary_headers.isEmpty()) + request->vary_headers = httpMakeVaryMark(request, mem_obj->getReply()); } // TODO: storeGetPublic() calls below may create unlocked entries. // We should add/use storeHas() API or lock/unlock those entries. - if (mem_obj->vary_headers && !storeGetPublic(mem_obj->storeId(), mem_obj->method)) { + if (!mem_obj->vary_headers.isEmpty() && !storeGetPublic(mem_obj->storeId(), mem_obj->method)) { /* Create "vary" base object */ String vary; StoreEntry *pe = storeCreateEntry(mem_obj->storeId(), mem_obj->logUri(), request->flags, request->method); diff -u -r -N squid-3.5.15/src/store_key_md5.cc squid-3.5.16/src/store_key_md5.cc --- squid-3.5.15/src/store_key_md5.cc 2016-02-24 05:25:46.000000000 +1300 +++ squid-3.5.16/src/store_key_md5.cc 2016-04-02 10:02:59.000000000 +1300 @@ -125,8 +125,8 @@ SquidMD5Update(&M, &m, sizeof(m)); SquidMD5Update(&M, (unsigned char *) url, strlen(url)); - if (request->vary_headers) { - SquidMD5Update(&M, (unsigned char *) request->vary_headers, strlen(request->vary_headers)); + if (!request->vary_headers.isEmpty()) { + SquidMD5Update(&M, request->vary_headers.rawContent(), request->vary_headers.length()); debugs(20, 3, "updating public key by vary headers: " << request->vary_headers << " for: " << url); } diff -u -r -N squid-3.5.15/src/StoreMetaVary.cc squid-3.5.16/src/StoreMetaVary.cc --- squid-3.5.15/src/StoreMetaVary.cc 2016-02-24 05:25:46.000000000 +1300 +++ squid-3.5.16/src/StoreMetaVary.cc 2016-04-02 10:02:59.000000000 +1300 @@ -18,14 +18,14 @@ { assert (getType() == STORE_META_VARY_HEADERS); - if (!e->mem_obj->vary_headers) { + if (e->mem_obj->vary_headers.isEmpty()) { /* XXX separate this mutator from the query */ /* Assume the object is OK.. remember the vary request headers */ - e->mem_obj->vary_headers = xstrdup((char *)value); + e->mem_obj->vary_headers.assign(static_cast(value), length); return true; } - if (strcmp(e->mem_obj->vary_headers, (char *)value) != 0) + if (e->mem_obj->vary_headers.cmp(static_cast(value), length) != 0) return false; return true; diff -u -r -N squid-3.5.15/src/store_swapmeta.cc squid-3.5.16/src/store_swapmeta.cc --- squid-3.5.15/src/store_swapmeta.cc 2016-02-24 05:25:46.000000000 +1300 +++ squid-3.5.16/src/store_swapmeta.cc 2016-04-02 10:02:59.000000000 +1300 @@ -40,7 +40,6 @@ tlv *TLV = NULL; /* we'll return this */ tlv **T = &TLV; const char *url; - const char *vary; assert(e->mem_obj != NULL); const int64_t objsize = e->mem_obj->expectedReplySize(); assert(e->swap_status == SWAPOUT_WRITING); @@ -87,10 +86,12 @@ } T = StoreMeta::Add(T, t); - vary = e->mem_obj->vary_headers; + SBuf vary(e->mem_obj->vary_headers); - if (vary) { - t =StoreMeta::Factory(STORE_META_VARY_HEADERS, strlen(vary) + 1, vary); + if (!vary.isEmpty()) { + // TODO: do we still need +1 here? StoreMetaVary::checkConsistency + // no longer relies on nul-termination, but other things might. + t = StoreMeta::Factory(STORE_META_VARY_HEADERS, vary.length() + 1, vary.c_str()); if (!t) { storeSwapTLVFree(TLV); diff -u -r -N squid-3.5.15/src/tests/stub_comm.cc squid-3.5.16/src/tests/stub_comm.cc --- squid-3.5.15/src/tests/stub_comm.cc 2016-02-24 05:25:46.000000000 +1300 +++ squid-3.5.16/src/tests/stub_comm.cc 2016-04-02 10:02:59.000000000 +1300 @@ -57,7 +57,7 @@ int ignoreErrno(int ierrno) STUB_RETVAL(-1) void commCloseAllSockets(void) STUB void checkTimeouts(void) STUB -void comm_add_close_handler(int fd, CLCB *, void *) STUB +AsyncCall::Pointer comm_add_close_handler(int fd, CLCB *, void *) STUB void comm_add_close_handler(int fd, AsyncCall::Pointer &) STUB void comm_remove_close_handler(int fd, CLCB *, void *) STUB void comm_remove_close_handler(int fd, AsyncCall::Pointer &)STUB diff -u -r -N squid-3.5.15/src/tests/stub_http.cc squid-3.5.16/src/tests/stub_http.cc --- squid-3.5.15/src/tests/stub_http.cc 2016-02-24 05:25:46.000000000 +1300 +++ squid-3.5.16/src/tests/stub_http.cc 2016-04-02 10:02:59.000000000 +1300 @@ -7,12 +7,12 @@ */ #include "squid.h" - #include "HttpReply.h" #include "HttpRequest.h" +#include "SBuf.h" #define STUB_API "http.cc" #include "tests/STUB.h" -const char * httpMakeVaryMark(HttpRequest * request, HttpReply const * reply) STUB_RETVAL(NULL) +SBuf httpMakeVaryMark(HttpRequest *, HttpReply const *) STUB_RETVAL(SBuf()) diff -u -r -N squid-3.5.15/src/tests/stub_MemObject.cc squid-3.5.16/src/tests/stub_MemObject.cc --- squid-3.5.15/src/tests/stub_MemObject.cc 2016-02-24 05:25:46.000000000 +1300 +++ squid-3.5.16/src/tests/stub_MemObject.cc 2016-04-02 10:02:59.000000000 +1300 @@ -38,7 +38,6 @@ id(0), object_sz(-1), swap_hdr_sz(0), - vary_headers(NULL), _reply(NULL) { memset(&clients, 0, sizeof(clients));