diff -u -r -N squid-4.0.20/aclocal.m4 squid-4.0.21/aclocal.m4 --- squid-4.0.20/aclocal.m4 2017-06-02 00:51:04.000000000 +1200 +++ squid-4.0.21/aclocal.m4 2017-07-02 20:41:21.000000000 +1200 @@ -1,6 +1,6 @@ -# generated automatically by aclocal 1.15 -*- Autoconf -*- +# generated automatically by aclocal 1.15.1 -*- Autoconf -*- -# Copyright (C) 1996-2014 Free Software Foundation, Inc. +# Copyright (C) 1996-2017 Free Software Foundation, Inc. # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -10052,7 +10052,7 @@ m4_ifndef([_LT_PROG_FC], [AC_DEFUN([_LT_PROG_FC])]) m4_ifndef([_LT_PROG_CXX], [AC_DEFUN([_LT_PROG_CXX])]) -# Copyright (C) 2002-2014 Free Software Foundation, Inc. +# Copyright (C) 2002-2017 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -10067,7 +10067,7 @@ [am__api_version='1.15' dnl Some users find AM_AUTOMAKE_VERSION and mistake it for a way to dnl require some minimum version. Point them to the right macro. -m4_if([$1], [1.15], [], +m4_if([$1], [1.15.1], [], [AC_FATAL([Do not call $0, use AM_INIT_AUTOMAKE([$1]).])])dnl ]) @@ -10083,14 +10083,14 @@ # Call AM_AUTOMAKE_VERSION and AM_AUTOMAKE_VERSION so they can be traced. # This function is AC_REQUIREd by AM_INIT_AUTOMAKE. AC_DEFUN([AM_SET_CURRENT_AUTOMAKE_VERSION], -[AM_AUTOMAKE_VERSION([1.15])dnl +[AM_AUTOMAKE_VERSION([1.15.1])dnl m4_ifndef([AC_AUTOCONF_VERSION], [m4_copy([m4_PACKAGE_VERSION], [AC_AUTOCONF_VERSION])])dnl _AM_AUTOCONF_VERSION(m4_defn([AC_AUTOCONF_VERSION]))]) # AM_AUX_DIR_EXPAND -*- Autoconf -*- -# Copyright (C) 2001-2014 Free Software Foundation, Inc. +# Copyright (C) 2001-2017 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -10142,7 +10142,7 @@ # AM_CONDITIONAL -*- Autoconf -*- -# Copyright (C) 1997-2014 Free Software Foundation, Inc. +# Copyright (C) 1997-2017 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -10173,7 +10173,7 @@ Usually this means the macro was only invoked conditionally.]]) fi])]) -# Copyright (C) 1999-2014 Free Software Foundation, Inc. +# Copyright (C) 1999-2017 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -10364,7 +10364,7 @@ # Generate code to set up dependency tracking. -*- Autoconf -*- -# Copyright (C) 1999-2014 Free Software Foundation, Inc. +# Copyright (C) 1999-2017 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -10440,7 +10440,7 @@ # Do all the work for Automake. -*- Autoconf -*- -# Copyright (C) 1996-2014 Free Software Foundation, Inc. +# Copyright (C) 1996-2017 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -10637,7 +10637,7 @@ done echo "timestamp for $_am_arg" >`AS_DIRNAME(["$_am_arg"])`/stamp-h[]$_am_stamp_count]) -# Copyright (C) 2001-2014 Free Software Foundation, Inc. +# Copyright (C) 2001-2017 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -10658,7 +10658,7 @@ fi AC_SUBST([install_sh])]) -# Copyright (C) 2003-2014 Free Software Foundation, Inc. +# Copyright (C) 2003-2017 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -10680,7 +10680,7 @@ # Add --enable-maintainer-mode option to configure. -*- Autoconf -*- # From Jim Meyering -# Copyright (C) 1996-2014 Free Software Foundation, Inc. +# Copyright (C) 1996-2017 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -10715,7 +10715,7 @@ # Check to see how 'make' treats includes. -*- Autoconf -*- -# Copyright (C) 2001-2014 Free Software Foundation, Inc. +# Copyright (C) 2001-2017 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -10765,7 +10765,7 @@ # Fake the existence of programs that GNU maintainers use. -*- Autoconf -*- -# Copyright (C) 1997-2014 Free Software Foundation, Inc. +# Copyright (C) 1997-2017 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -10804,7 +10804,7 @@ # Helper functions for option handling. -*- Autoconf -*- -# Copyright (C) 2001-2014 Free Software Foundation, Inc. +# Copyright (C) 2001-2017 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -10833,7 +10833,7 @@ AC_DEFUN([_AM_IF_OPTION], [m4_ifset(_AM_MANGLE_OPTION([$1]), [$2], [$3])]) -# Copyright (C) 1999-2014 Free Software Foundation, Inc. +# Copyright (C) 1999-2017 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -10880,7 +10880,7 @@ # For backward compatibility. AC_DEFUN_ONCE([AM_PROG_CC_C_O], [AC_REQUIRE([AC_PROG_CC])]) -# Copyright (C) 2001-2014 Free Software Foundation, Inc. +# Copyright (C) 2001-2017 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -10899,7 +10899,7 @@ # Check to make sure that the build environment is sane. -*- Autoconf -*- -# Copyright (C) 1996-2014 Free Software Foundation, Inc. +# Copyright (C) 1996-2017 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -10980,7 +10980,7 @@ rm -f conftest.file ]) -# Copyright (C) 2009-2014 Free Software Foundation, Inc. +# Copyright (C) 2009-2017 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -11040,7 +11040,7 @@ _AM_SUBST_NOTMAKE([AM_BACKSLASH])dnl ]) -# Copyright (C) 2001-2014 Free Software Foundation, Inc. +# Copyright (C) 2001-2017 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -11068,7 +11068,7 @@ INSTALL_STRIP_PROGRAM="\$(install_sh) -c -s" AC_SUBST([INSTALL_STRIP_PROGRAM])]) -# Copyright (C) 2006-2014 Free Software Foundation, Inc. +# Copyright (C) 2006-2017 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -11087,7 +11087,7 @@ # Check how to create a tarball. -*- Autoconf -*- -# Copyright (C) 2004-2014 Free Software Foundation, Inc. +# Copyright (C) 2004-2017 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, diff -u -r -N squid-4.0.20/cfgaux/depcomp squid-4.0.21/cfgaux/depcomp --- squid-4.0.20/cfgaux/depcomp 2017-06-02 01:01:27.000000000 +1200 +++ squid-4.0.21/cfgaux/depcomp 2017-07-02 20:41:28.000000000 +1200 @@ -1,9 +1,9 @@ #! /bin/sh # depcomp - compile a program generating dependencies as side-effects -scriptversion=2013-05-30.07; # UTC +scriptversion=2016-01-11.22; # UTC -# Copyright (C) 1999-2014 Free Software Foundation, Inc. +# Copyright (C) 1999-2017 Free Software Foundation, Inc. # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by @@ -786,6 +786,6 @@ # eval: (add-hook 'write-file-hooks 'time-stamp) # time-stamp-start: "scriptversion=" # time-stamp-format: "%:y-%02m-%02d.%02H" -# time-stamp-time-zone: "UTC" +# time-stamp-time-zone: "UTC0" # time-stamp-end: "; # UTC" # End: diff -u -r -N squid-4.0.20/ChangeLog squid-4.0.21/ChangeLog --- squid-4.0.20/ChangeLog 2017-06-02 00:49:17.000000000 +1200 +++ squid-4.0.21/ChangeLog 2017-07-02 20:41:18.000000000 +1200 @@ -1,3 +1,22 @@ +Changes to squid-4.0.21 (02 Jul 2017): + + - Bug 4730: segfault while processing internal HTTP requests + - Bug 4492: Chunk extension parser is too pedantic + - Bug 1961: Redesign urlParse() API + - TLS: recognise tls:: namespace on logformat tokens + - SSL-Bump: tproxy does not spoof spliced connections + - security_file_certgen: collapse queued requests + - Add a basic apparmour profile + - Add transaction_initiator ACL for detecting various unusual transactions + - Add ssl::server_name options to control matching logic + - Support for --long-acl-options + - Do not die silently when dying via std::terminate() + - Fix option --foreground to implement expected behavior + - Translations: update .po and .pot to latest texts + - ... and some documentation updates + - ... and many code cleanup and stability fixes + - ... and all fixes from 3.5.27 + Changes to squid-4.0.20 (01 Jun 2017): - Bug #4692: SslBump breaks intercepted IPv6 connections @@ -16,7 +35,7 @@ - ext_session_acl: cope with new logformat inputs - ... and some documentation updates - ... and some code stability fixes - - ... and all fixes from 3.5.25 + - ... and all fixes from 3.5.26 Changes to squid-4.0.19 (02 Apr 2017): diff -u -r -N squid-4.0.20/compat/Makefile.in squid-4.0.21/compat/Makefile.in --- squid-4.0.20/compat/Makefile.in 2017-06-02 00:52:42.000000000 +1200 +++ squid-4.0.21/compat/Makefile.in 2017-07-02 20:41:23.000000000 +1200 @@ -1,7 +1,7 @@ -# Makefile.in generated by automake 1.15 from Makefile.am. +# Makefile.in generated by automake 1.15.1 from Makefile.am. # @configure_input@ -# Copyright (C) 1994-2014 Free Software Foundation, Inc. +# Copyright (C) 1994-2017 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, diff -u -r -N squid-4.0.20/configure squid-4.0.21/configure --- squid-4.0.20/configure 2017-06-02 01:01:44.000000000 +1200 +++ squid-4.0.21/configure 2017-07-02 20:41:29.000000000 +1200 @@ -1,7 +1,7 @@ #! /bin/sh # From configure.ac Revision. # Guess values for system-dependent variables and create Makefiles. -# Generated by GNU Autoconf 2.69 for Squid Web Proxy 4.0.20. +# Generated by GNU Autoconf 2.69 for Squid Web Proxy 4.0.21. # # Report bugs to . # @@ -595,8 +595,8 @@ # Identity of this package. PACKAGE_NAME='Squid Web Proxy' PACKAGE_TARNAME='squid' -PACKAGE_VERSION='4.0.20' -PACKAGE_STRING='Squid Web Proxy 4.0.20' +PACKAGE_VERSION='4.0.21' +PACKAGE_STRING='Squid Web Proxy 4.0.21' PACKAGE_BUGREPORT='http://bugs.squid-cache.org/' PACKAGE_URL='' @@ -1647,7 +1647,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 4.0.20 to adapt to many kinds of systems. +\`configure' configures Squid Web Proxy 4.0.21 to adapt to many kinds of systems. Usage: $0 [OPTION]... [VAR=VALUE]... @@ -1718,7 +1718,7 @@ if test -n "$ac_init_help"; then case $ac_init_help in - short | recursive ) echo "Configuration of Squid Web Proxy 4.0.20:";; + short | recursive ) echo "Configuration of Squid Web Proxy 4.0.21:";; esac cat <<\_ACEOF @@ -2147,7 +2147,7 @@ test -n "$ac_init_help" && exit $ac_status if $ac_init_version; then cat <<\_ACEOF -Squid Web Proxy configure 4.0.20 +Squid Web Proxy configure 4.0.21 generated by GNU Autoconf 2.69 Copyright (C) 2012 Free Software Foundation, Inc. @@ -3251,7 +3251,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 4.0.20, which was +It was created by Squid Web Proxy $as_me 4.0.21, which was generated by GNU Autoconf 2.69. Invocation command line was $ $0 $@ @@ -4118,7 +4118,7 @@ # Define the identity of the package. PACKAGE='squid' - VERSION='4.0.20' + VERSION='4.0.21' cat >>confdefs.h <<_ACEOF @@ -42910,7 +42910,7 @@ rm -f core -ac_config_files="$ac_config_files Makefile compat/Makefile contrib/Makefile doc/Makefile doc/manuals/Makefile doc/release-notes/Makefile errors/Makefile icons/Makefile lib/Makefile lib/libTrie/Makefile lib/libTrie/test/Makefile lib/ntlmauth/Makefile lib/profiler/Makefile lib/rfcnb/Makefile lib/smblib/Makefile lib/snmplib/Makefile scripts/Makefile src/Makefile src/acl/Makefile src/acl/external/Makefile src/acl/external/AD_group/Makefile src/acl/external/delayer/Makefile src/acl/external/eDirectory_userip/Makefile src/acl/external/file_userip/Makefile src/acl/external/kerberos_ldap_group/Makefile src/acl/external/LDAP_group/Makefile src/acl/external/LM_group/Makefile src/acl/external/session/Makefile src/acl/external/SQL_session/Makefile src/acl/external/unix_group/Makefile src/acl/external/wbinfo_group/Makefile src/acl/external/time_quota/Makefile src/adaptation/Makefile src/adaptation/icap/Makefile src/adaptation/ecap/Makefile src/anyp/Makefile src/auth/Makefile src/auth/basic/Makefile src/auth/basic/DB/Makefile src/auth/basic/fake/Makefile src/auth/basic/getpwnam/Makefile src/auth/basic/LDAP/Makefile src/auth/basic/NCSA/Makefile src/auth/basic/NIS/Makefile src/auth/basic/PAM/Makefile src/auth/basic/POP3/Makefile src/auth/basic/RADIUS/Makefile src/auth/basic/SASL/Makefile src/auth/basic/SMB/Makefile src/auth/basic/SMB_LM/Makefile src/auth/basic/SSPI/Makefile src/auth/digest/Makefile src/auth/digest/eDirectory/Makefile src/auth/digest/file/Makefile src/auth/digest/LDAP/Makefile src/auth/negotiate/Makefile src/auth/negotiate/kerberos/Makefile src/auth/negotiate/SSPI/Makefile src/auth/negotiate/wrapper/Makefile src/auth/ntlm/Makefile src/auth/ntlm/fake/Makefile src/auth/ntlm/SMB_LM/Makefile src/auth/ntlm/SSPI/Makefile src/base/Makefile src/clients/Makefile src/comm/Makefile src/dns/Makefile src/DiskIO/Makefile src/DiskIO/AIO/Makefile src/DiskIO/Blocking/Makefile src/DiskIO/DiskDaemon/Makefile src/DiskIO/DiskThreads/Makefile src/DiskIO/IpcIo/Makefile src/DiskIO/Mmapped/Makefile src/esi/Makefile src/eui/Makefile src/format/Makefile src/fs/Makefile src/ftp/Makefile src/helper/Makefile src/http/Makefile src/http/one/Makefile src/http/url_rewriters/Makefile src/http/url_rewriters/fake/Makefile src/http/url_rewriters/LFS/Makefile src/icmp/Makefile src/ident/Makefile src/ip/Makefile src/ipc/Makefile src/log/Makefile src/log/DB/Makefile src/log/file/Makefile src/mem/Makefile src/mgr/Makefile src/parser/Makefile src/repl/Makefile src/sbuf/Makefile src/security/Makefile src/security/cert_generators/Makefile src/security/cert_generators/file/Makefile src/security/cert_validators/Makefile src/security/cert_validators/fake/Makefile src/servers/Makefile src/snmp/Makefile src/ssl/Makefile src/store/Makefile src/store/id_rewriters/Makefile src/store/id_rewriters/file/Makefile test-suite/Makefile tools/Makefile tools/helper-mux/Makefile tools/purge/Makefile tools/squidclient/Makefile tools/systemd/Makefile tools/sysvinit/Makefile" +ac_config_files="$ac_config_files Makefile compat/Makefile contrib/Makefile doc/Makefile doc/manuals/Makefile doc/release-notes/Makefile errors/Makefile icons/Makefile lib/Makefile lib/libTrie/Makefile lib/libTrie/test/Makefile lib/ntlmauth/Makefile lib/profiler/Makefile lib/rfcnb/Makefile lib/smblib/Makefile lib/snmplib/Makefile scripts/Makefile src/Makefile src/acl/Makefile src/acl/external/Makefile src/acl/external/AD_group/Makefile src/acl/external/delayer/Makefile src/acl/external/eDirectory_userip/Makefile src/acl/external/file_userip/Makefile src/acl/external/kerberos_ldap_group/Makefile src/acl/external/LDAP_group/Makefile src/acl/external/LM_group/Makefile src/acl/external/session/Makefile src/acl/external/SQL_session/Makefile src/acl/external/unix_group/Makefile src/acl/external/wbinfo_group/Makefile src/acl/external/time_quota/Makefile src/adaptation/Makefile src/adaptation/icap/Makefile src/adaptation/ecap/Makefile src/anyp/Makefile src/auth/Makefile src/auth/basic/Makefile src/auth/basic/DB/Makefile src/auth/basic/fake/Makefile src/auth/basic/getpwnam/Makefile src/auth/basic/LDAP/Makefile src/auth/basic/NCSA/Makefile src/auth/basic/NIS/Makefile src/auth/basic/PAM/Makefile src/auth/basic/POP3/Makefile src/auth/basic/RADIUS/Makefile src/auth/basic/SASL/Makefile src/auth/basic/SMB/Makefile src/auth/basic/SMB_LM/Makefile src/auth/basic/SSPI/Makefile src/auth/digest/Makefile src/auth/digest/eDirectory/Makefile src/auth/digest/file/Makefile src/auth/digest/LDAP/Makefile src/auth/negotiate/Makefile src/auth/negotiate/kerberos/Makefile src/auth/negotiate/SSPI/Makefile src/auth/negotiate/wrapper/Makefile src/auth/ntlm/Makefile src/auth/ntlm/fake/Makefile src/auth/ntlm/SMB_LM/Makefile src/auth/ntlm/SSPI/Makefile src/base/Makefile src/clients/Makefile src/comm/Makefile src/dns/Makefile src/DiskIO/Makefile src/DiskIO/AIO/Makefile src/DiskIO/Blocking/Makefile src/DiskIO/DiskDaemon/Makefile src/DiskIO/DiskThreads/Makefile src/DiskIO/IpcIo/Makefile src/DiskIO/Mmapped/Makefile src/esi/Makefile src/eui/Makefile src/format/Makefile src/fs/Makefile src/ftp/Makefile src/helper/Makefile src/http/Makefile src/http/one/Makefile src/http/url_rewriters/Makefile src/http/url_rewriters/fake/Makefile src/http/url_rewriters/LFS/Makefile src/icmp/Makefile src/ident/Makefile src/ip/Makefile src/ipc/Makefile src/log/Makefile src/log/DB/Makefile src/log/file/Makefile src/mem/Makefile src/mgr/Makefile src/parser/Makefile src/repl/Makefile src/sbuf/Makefile src/security/Makefile src/security/cert_generators/Makefile src/security/cert_generators/file/Makefile src/security/cert_validators/Makefile src/security/cert_validators/fake/Makefile src/servers/Makefile src/snmp/Makefile src/ssl/Makefile src/store/Makefile src/store/id_rewriters/Makefile src/store/id_rewriters/file/Makefile test-suite/Makefile tools/Makefile tools/apparmor/Makefile tools/helper-mux/Makefile tools/purge/Makefile tools/squidclient/Makefile tools/systemd/Makefile tools/sysvinit/Makefile" # must configure libltdl subdir unconditionally for "make distcheck" to work @@ -43656,7 +43656,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 4.0.20, which was +This file was extended by Squid Web Proxy $as_me 4.0.21, which was generated by GNU Autoconf 2.69. Invocation command line was CONFIG_FILES = $CONFIG_FILES @@ -43722,7 +43722,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 4.0.20 +Squid Web Proxy config.status 4.0.21 configured by $0, generated by GNU Autoconf 2.69, with options \\"\$ac_cs_config\\" @@ -44345,6 +44345,7 @@ "src/store/id_rewriters/file/Makefile") CONFIG_FILES="$CONFIG_FILES src/store/id_rewriters/file/Makefile" ;; "test-suite/Makefile") CONFIG_FILES="$CONFIG_FILES test-suite/Makefile" ;; "tools/Makefile") CONFIG_FILES="$CONFIG_FILES tools/Makefile" ;; + "tools/apparmor/Makefile") CONFIG_FILES="$CONFIG_FILES tools/apparmor/Makefile" ;; "tools/helper-mux/Makefile") CONFIG_FILES="$CONFIG_FILES tools/helper-mux/Makefile" ;; "tools/purge/Makefile") CONFIG_FILES="$CONFIG_FILES tools/purge/Makefile" ;; "tools/squidclient/Makefile") CONFIG_FILES="$CONFIG_FILES tools/squidclient/Makefile" ;; diff -u -r -N squid-4.0.20/configure.ac squid-4.0.21/configure.ac --- squid-4.0.20/configure.ac 2017-06-02 01:01:44.000000000 +1200 +++ squid-4.0.21/configure.ac 2017-07-02 20:41:29.000000000 +1200 @@ -5,7 +5,7 @@ ## Please see the COPYING and CONTRIBUTORS files for details. ## -AC_INIT([Squid Web Proxy],[4.0.20],[http://bugs.squid-cache.org/],[squid]) +AC_INIT([Squid Web Proxy],[4.0.21],[http://bugs.squid-cache.org/],[squid]) AC_PREREQ(2.61) AC_CONFIG_HEADERS([include/autoconf.h]) AC_CONFIG_AUX_DIR(cfgaux) @@ -3876,6 +3876,7 @@ src/store/id_rewriters/file/Makefile test-suite/Makefile tools/Makefile + tools/apparmor/Makefile tools/helper-mux/Makefile tools/purge/Makefile tools/squidclient/Makefile diff -u -r -N squid-4.0.20/contrib/Makefile.in squid-4.0.21/contrib/Makefile.in --- squid-4.0.20/contrib/Makefile.in 2017-06-02 00:52:44.000000000 +1200 +++ squid-4.0.21/contrib/Makefile.in 2017-07-02 20:41:23.000000000 +1200 @@ -1,7 +1,7 @@ -# Makefile.in generated by automake 1.15 from Makefile.am. +# Makefile.in generated by automake 1.15.1 from Makefile.am. # @configure_input@ -# Copyright (C) 1994-2014 Free Software Foundation, Inc. +# Copyright (C) 1994-2017 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, diff -u -r -N squid-4.0.20/contrib/solaris/solaris-krb5-include.patch squid-4.0.21/contrib/solaris/solaris-krb5-include.patch --- squid-4.0.20/contrib/solaris/solaris-krb5-include.patch 2017-06-02 00:49:17.000000000 +1200 +++ squid-4.0.21/contrib/solaris/solaris-krb5-include.patch 2017-07-02 20:41:18.000000000 +1200 @@ -1,3 +1,11 @@ +/* + * Copyright (C) 1996-2017 The Squid Software Foundation and contributors + * + * Squid software is distributed under GPLv2+ license and includes + * contributions from numerous individuals and organizations. + * Please see the COPYING and CONTRIBUTORS files for details. + */ + --- /usr/include/kerberosv5/krb5.h.orig Mon Aug 23 04:09:23 2010 +++ /usr/include/kerberosv5/krb5.h Mon Aug 23 04:10:53 2010 @@ -171,6 +171,7 @@ diff -u -r -N squid-4.0.20/doc/Makefile.in squid-4.0.21/doc/Makefile.in --- squid-4.0.20/doc/Makefile.in 2017-06-02 00:52:46.000000000 +1200 +++ squid-4.0.21/doc/Makefile.in 2017-07-02 20:41:23.000000000 +1200 @@ -1,7 +1,7 @@ -# Makefile.in generated by automake 1.15 from Makefile.am. +# Makefile.in generated by automake 1.15.1 from Makefile.am. # @configure_input@ -# Copyright (C) 1994-2014 Free Software Foundation, Inc. +# Copyright (C) 1994-2017 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, diff -u -r -N squid-4.0.20/doc/manuals/Makefile.in squid-4.0.21/doc/manuals/Makefile.in --- squid-4.0.20/doc/manuals/Makefile.in 2017-06-02 00:52:48.000000000 +1200 +++ squid-4.0.21/doc/manuals/Makefile.in 2017-07-02 20:41:23.000000000 +1200 @@ -1,7 +1,7 @@ -# Makefile.in generated by automake 1.15 from Makefile.am. +# Makefile.in generated by automake 1.15.1 from Makefile.am. # @configure_input@ -# Copyright (C) 1994-2014 Free Software Foundation, Inc. +# Copyright (C) 1994-2017 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, diff -u -r -N squid-4.0.20/doc/release-notes/Makefile.in squid-4.0.21/doc/release-notes/Makefile.in --- squid-4.0.20/doc/release-notes/Makefile.in 2017-06-02 00:52:50.000000000 +1200 +++ squid-4.0.21/doc/release-notes/Makefile.in 2017-07-02 20:41:23.000000000 +1200 @@ -1,7 +1,7 @@ -# Makefile.in generated by automake 1.15 from Makefile.am. +# Makefile.in generated by automake 1.15.1 from Makefile.am. # @configure_input@ -# Copyright (C) 1994-2014 Free Software Foundation, Inc. +# Copyright (C) 1994-2017 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, diff -u -r -N squid-4.0.20/doc/release-notes/release-4.html squid-4.0.21/doc/release-notes/release-4.html --- squid-4.0.20/doc/release-notes/release-4.html 2017-06-02 09:49:09.000000000 +1200 +++ squid-4.0.21/doc/release-notes/release-4.html 2017-07-02 20:57:33.000000000 +1200 @@ -2,10 +2,10 @@ - Squid 4.0.20 release notes + Squid 4.0.21 release notes -

Squid 4.0.20 release notes

+

Squid 4.0.21 release notes

Squid Developers


@@ -62,7 +62,7 @@

1. Notice

-

The Squid Team are pleased to announce the release of Squid-4.0.20 for testing.

+

The Squid Team are pleased to announce the release of Squid-4.0.21 for testing.

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

@@ -237,10 +237,9 @@ integration with daemon managers such as Upstart or systemd which assume the process they initiated is the daemon with a PID to control.

-

The squid binary now has a new --foreground command line option -which prevents the process from exiting early while background workers -continue their processing. When run with this option Squid will now wait -for the worker(s) to finish before exiting. Unlike the old -N option +

The squid binary now has a new --foreground command line option, +which (only) prevents daemonizing the master process. +Unlike the old -N option, --foreground supports SMP workers and multi-process features. --foreground is particularly useful for use with -z (disk cache structures creation), as it allows the caller to wait until Squid has @@ -342,6 +341,11 @@ including messages received from ICAP servers.

New has type for matching whether or not Squid is able to provide certain sets of transaction state. For example HTTP reply headers.

+

New transaction_initiator type for detecting various +unusual transactions.

+

New --consensus, --client-requested and +--server-provided flags for the ssl::server_name +type to control which server name to match against.

auth_param

New parameter queue-size= to set the maximum number diff -u -r -N squid-4.0.20/errors/Makefile.in squid-4.0.21/errors/Makefile.in --- squid-4.0.20/errors/Makefile.in 2017-06-02 00:52:54.000000000 +1200 +++ squid-4.0.21/errors/Makefile.in 2017-07-02 20:41:23.000000000 +1200 @@ -1,7 +1,7 @@ -# Makefile.in generated by automake 1.15 from Makefile.am. +# Makefile.in generated by automake 1.15.1 from Makefile.am. # @configure_input@ -# Copyright (C) 1994-2014 Free Software Foundation, Inc. +# Copyright (C) 1994-2017 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, diff -u -r -N squid-4.0.20/errors/TRANSLATORS squid-4.0.21/errors/TRANSLATORS --- squid-4.0.20/errors/TRANSLATORS 2017-06-02 00:49:17.000000000 +1200 +++ squid-4.0.21/errors/TRANSLATORS 2017-07-02 20:41:18.000000000 +1200 @@ -1,3 +1,9 @@ + * Copyright (C) 1996-2017 The Squid Software Foundation and contributors + * + * Squid software is distributed under GPLv2+ license and includes + * contributions from numerous individuals and organizations. + * Please see the COPYING and CONTRIBUTORS files for details. + Special thanks go to people who have volunteered their time, effort, and ideas to make Squid available as multi-langual software. diff -u -r -N squid-4.0.20/icons/Makefile.in squid-4.0.21/icons/Makefile.in --- squid-4.0.20/icons/Makefile.in 2017-06-02 00:52:57.000000000 +1200 +++ squid-4.0.21/icons/Makefile.in 2017-07-02 20:41:23.000000000 +1200 @@ -1,7 +1,7 @@ -# Makefile.in generated by automake 1.15 from Makefile.am. +# Makefile.in generated by automake 1.15.1 from Makefile.am. # @configure_input@ -# Copyright (C) 1994-2014 Free Software Foundation, Inc. +# Copyright (C) 1994-2017 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, diff -u -r -N squid-4.0.20/include/version.h squid-4.0.21/include/version.h --- squid-4.0.20/include/version.h 2017-06-02 01:01:44.000000000 +1200 +++ squid-4.0.21/include/version.h 2017-07-02 20:41:29.000000000 +1200 @@ -7,7 +7,7 @@ */ #ifndef SQUID_RELEASE_TIME -#define SQUID_RELEASE_TIME 1496321346 +#define SQUID_RELEASE_TIME 1498984863 #endif /* diff -u -r -N squid-4.0.20/lib/libTrie/Makefile.in squid-4.0.21/lib/libTrie/Makefile.in --- squid-4.0.20/lib/libTrie/Makefile.in 2017-06-02 00:53:04.000000000 +1200 +++ squid-4.0.21/lib/libTrie/Makefile.in 2017-07-02 20:41:24.000000000 +1200 @@ -1,7 +1,7 @@ -# Makefile.in generated by automake 1.15 from Makefile.am. +# Makefile.in generated by automake 1.15.1 from Makefile.am. # @configure_input@ -# Copyright (C) 1994-2014 Free Software Foundation, Inc. +# Copyright (C) 1994-2017 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, diff -u -r -N squid-4.0.20/lib/libTrie/test/Makefile.in squid-4.0.21/lib/libTrie/test/Makefile.in --- squid-4.0.20/lib/libTrie/test/Makefile.in 2017-06-02 00:53:07.000000000 +1200 +++ squid-4.0.21/lib/libTrie/test/Makefile.in 2017-07-02 20:41:24.000000000 +1200 @@ -1,7 +1,7 @@ -# Makefile.in generated by automake 1.15 from Makefile.am. +# Makefile.in generated by automake 1.15.1 from Makefile.am. # @configure_input@ -# Copyright (C) 1994-2014 Free Software Foundation, Inc. +# Copyright (C) 1994-2017 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, diff -u -r -N squid-4.0.20/lib/Makefile.in squid-4.0.21/lib/Makefile.in --- squid-4.0.20/lib/Makefile.in 2017-06-02 00:53:01.000000000 +1200 +++ squid-4.0.21/lib/Makefile.in 2017-07-02 20:41:23.000000000 +1200 @@ -1,7 +1,7 @@ -# Makefile.in generated by automake 1.15 from Makefile.am. +# Makefile.in generated by automake 1.15.1 from Makefile.am. # @configure_input@ -# Copyright (C) 1994-2014 Free Software Foundation, Inc. +# Copyright (C) 1994-2017 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, diff -u -r -N squid-4.0.20/lib/ntlmauth/Makefile.in squid-4.0.21/lib/ntlmauth/Makefile.in --- squid-4.0.20/lib/ntlmauth/Makefile.in 2017-06-02 00:53:09.000000000 +1200 +++ squid-4.0.21/lib/ntlmauth/Makefile.in 2017-07-02 20:41:24.000000000 +1200 @@ -1,7 +1,7 @@ -# Makefile.in generated by automake 1.15 from Makefile.am. +# Makefile.in generated by automake 1.15.1 from Makefile.am. # @configure_input@ -# Copyright (C) 1994-2014 Free Software Foundation, Inc. +# Copyright (C) 1994-2017 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, diff -u -r -N squid-4.0.20/lib/profiler/Makefile.in squid-4.0.21/lib/profiler/Makefile.in --- squid-4.0.20/lib/profiler/Makefile.in 2017-06-02 00:53:16.000000000 +1200 +++ squid-4.0.21/lib/profiler/Makefile.in 2017-07-02 20:41:24.000000000 +1200 @@ -1,7 +1,7 @@ -# Makefile.in generated by automake 1.15 from Makefile.am. +# Makefile.in generated by automake 1.15.1 from Makefile.am. # @configure_input@ -# Copyright (C) 1994-2014 Free Software Foundation, Inc. +# Copyright (C) 1994-2017 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, diff -u -r -N squid-4.0.20/lib/rfcnb/Makefile.in squid-4.0.21/lib/rfcnb/Makefile.in --- squid-4.0.20/lib/rfcnb/Makefile.in 2017-06-02 00:53:19.000000000 +1200 +++ squid-4.0.21/lib/rfcnb/Makefile.in 2017-07-02 20:41:24.000000000 +1200 @@ -1,7 +1,7 @@ -# Makefile.in generated by automake 1.15 from Makefile.am. +# Makefile.in generated by automake 1.15.1 from Makefile.am. # @configure_input@ -# Copyright (C) 1994-2014 Free Software Foundation, Inc. +# Copyright (C) 1994-2017 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, diff -u -r -N squid-4.0.20/lib/smblib/Makefile.in squid-4.0.21/lib/smblib/Makefile.in --- squid-4.0.20/lib/smblib/Makefile.in 2017-06-02 00:53:20.000000000 +1200 +++ squid-4.0.21/lib/smblib/Makefile.in 2017-07-02 20:41:24.000000000 +1200 @@ -1,7 +1,7 @@ -# Makefile.in generated by automake 1.15 from Makefile.am. +# Makefile.in generated by automake 1.15.1 from Makefile.am. # @configure_input@ -# Copyright (C) 1994-2014 Free Software Foundation, Inc. +# Copyright (C) 1994-2017 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, diff -u -r -N squid-4.0.20/lib/snmplib/Makefile.in squid-4.0.21/lib/snmplib/Makefile.in --- squid-4.0.20/lib/snmplib/Makefile.in 2017-06-02 00:53:22.000000000 +1200 +++ squid-4.0.21/lib/snmplib/Makefile.in 2017-07-02 20:41:24.000000000 +1200 @@ -1,7 +1,7 @@ -# Makefile.in generated by automake 1.15 from Makefile.am. +# Makefile.in generated by automake 1.15.1 from Makefile.am. # @configure_input@ -# Copyright (C) 1994-2014 Free Software Foundation, Inc. +# Copyright (C) 1994-2017 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, diff -u -r -N squid-4.0.20/libltdl/aclocal.m4 squid-4.0.21/libltdl/aclocal.m4 --- squid-4.0.20/libltdl/aclocal.m4 2017-06-02 00:52:00.000000000 +1200 +++ squid-4.0.21/libltdl/aclocal.m4 2017-07-02 20:41:56.000000000 +1200 @@ -1,6 +1,6 @@ -# generated automatically by aclocal 1.15 -*- Autoconf -*- +# generated automatically by aclocal 1.15.1 -*- Autoconf -*- -# Copyright (C) 1996-2014 Free Software Foundation, Inc. +# Copyright (C) 1996-2017 Free Software Foundation, Inc. # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -20,7 +20,7 @@ If you have problems, you may need to regenerate the build system entirely. To do so, use the procedure documented by the package, typically 'autoreconf'.])]) -# Copyright (C) 2002-2014 Free Software Foundation, Inc. +# Copyright (C) 2002-2017 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -35,7 +35,7 @@ [am__api_version='1.15' dnl Some users find AM_AUTOMAKE_VERSION and mistake it for a way to dnl require some minimum version. Point them to the right macro. -m4_if([$1], [1.15], [], +m4_if([$1], [1.15.1], [], [AC_FATAL([Do not call $0, use AM_INIT_AUTOMAKE([$1]).])])dnl ]) @@ -51,14 +51,14 @@ # Call AM_AUTOMAKE_VERSION and AM_AUTOMAKE_VERSION so they can be traced. # This function is AC_REQUIREd by AM_INIT_AUTOMAKE. AC_DEFUN([AM_SET_CURRENT_AUTOMAKE_VERSION], -[AM_AUTOMAKE_VERSION([1.15])dnl +[AM_AUTOMAKE_VERSION([1.15.1])dnl m4_ifndef([AC_AUTOCONF_VERSION], [m4_copy([m4_PACKAGE_VERSION], [AC_AUTOCONF_VERSION])])dnl _AM_AUTOCONF_VERSION(m4_defn([AC_AUTOCONF_VERSION]))]) # AM_AUX_DIR_EXPAND -*- Autoconf -*- -# Copyright (C) 2001-2014 Free Software Foundation, Inc. +# Copyright (C) 2001-2017 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -110,7 +110,7 @@ # AM_CONDITIONAL -*- Autoconf -*- -# Copyright (C) 1997-2014 Free Software Foundation, Inc. +# Copyright (C) 1997-2017 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -141,7 +141,7 @@ Usually this means the macro was only invoked conditionally.]]) fi])]) -# Copyright (C) 1999-2014 Free Software Foundation, Inc. +# Copyright (C) 1999-2017 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -332,7 +332,7 @@ # Generate code to set up dependency tracking. -*- Autoconf -*- -# Copyright (C) 1999-2014 Free Software Foundation, Inc. +# Copyright (C) 1999-2017 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -408,7 +408,7 @@ # Do all the work for Automake. -*- Autoconf -*- -# Copyright (C) 1996-2014 Free Software Foundation, Inc. +# Copyright (C) 1996-2017 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -605,7 +605,7 @@ done echo "timestamp for $_am_arg" >`AS_DIRNAME(["$_am_arg"])`/stamp-h[]$_am_stamp_count]) -# Copyright (C) 2001-2014 Free Software Foundation, Inc. +# Copyright (C) 2001-2017 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -626,7 +626,7 @@ fi AC_SUBST([install_sh])]) -# Copyright (C) 2003-2014 Free Software Foundation, Inc. +# Copyright (C) 2003-2017 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -647,7 +647,7 @@ # Check to see how 'make' treats includes. -*- Autoconf -*- -# Copyright (C) 2001-2014 Free Software Foundation, Inc. +# Copyright (C) 2001-2017 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -697,7 +697,7 @@ # Fake the existence of programs that GNU maintainers use. -*- Autoconf -*- -# Copyright (C) 1997-2014 Free Software Foundation, Inc. +# Copyright (C) 1997-2017 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -736,7 +736,7 @@ # Helper functions for option handling. -*- Autoconf -*- -# Copyright (C) 2001-2014 Free Software Foundation, Inc. +# Copyright (C) 2001-2017 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -765,7 +765,7 @@ AC_DEFUN([_AM_IF_OPTION], [m4_ifset(_AM_MANGLE_OPTION([$1]), [$2], [$3])]) -# Copyright (C) 1999-2014 Free Software Foundation, Inc. +# Copyright (C) 1999-2017 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -812,7 +812,7 @@ # For backward compatibility. AC_DEFUN_ONCE([AM_PROG_CC_C_O], [AC_REQUIRE([AC_PROG_CC])]) -# Copyright (C) 2001-2014 Free Software Foundation, Inc. +# Copyright (C) 2001-2017 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -831,7 +831,7 @@ # Check to make sure that the build environment is sane. -*- Autoconf -*- -# Copyright (C) 1996-2014 Free Software Foundation, Inc. +# Copyright (C) 1996-2017 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -912,7 +912,7 @@ rm -f conftest.file ]) -# Copyright (C) 2009-2014 Free Software Foundation, Inc. +# Copyright (C) 2009-2017 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -972,7 +972,7 @@ _AM_SUBST_NOTMAKE([AM_BACKSLASH])dnl ]) -# Copyright (C) 2001-2014 Free Software Foundation, Inc. +# Copyright (C) 2001-2017 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -1000,7 +1000,7 @@ INSTALL_STRIP_PROGRAM="\$(install_sh) -c -s" AC_SUBST([INSTALL_STRIP_PROGRAM])]) -# Copyright (C) 2006-2014 Free Software Foundation, Inc. +# Copyright (C) 2006-2017 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -1019,7 +1019,7 @@ # Check how to create a tarball. -*- Autoconf -*- -# Copyright (C) 2004-2014 Free Software Foundation, Inc. +# Copyright (C) 2004-2017 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, diff -u -r -N squid-4.0.20/libltdl/Makefile.in squid-4.0.21/libltdl/Makefile.in --- squid-4.0.20/libltdl/Makefile.in 2017-06-02 01:18:08.000000000 +1200 +++ squid-4.0.21/libltdl/Makefile.in 2017-07-02 20:41:56.000000000 +1200 @@ -1,7 +1,7 @@ -# Makefile.in generated by automake 1.15 from Makefile.am. +# Makefile.in generated by automake 1.15.1 from Makefile.am. # @configure_input@ -# Copyright (C) 1994-2014 Free Software Foundation, Inc. +# Copyright (C) 1994-2017 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -933,7 +933,7 @@ ! -type d ! -perm -444 -exec $(install_sh) -c -m a+r {} {} \; \ || chmod -R a+r "$(distdir)" dist-gzip: distdir - tardir=$(distdir) && $(am__tar) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).tar.gz + tardir=$(distdir) && $(am__tar) | eval GZIP= gzip $(GZIP_ENV) -c >$(distdir).tar.gz $(am__post_remove_distdir) dist-bzip2: distdir @@ -959,7 +959,7 @@ @echo WARNING: "Support for shar distribution archives is" \ "deprecated." >&2 @echo WARNING: "It will be removed altogether in Automake 2.0" >&2 - shar $(distdir) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).shar.gz + shar $(distdir) | eval GZIP= gzip $(GZIP_ENV) -c >$(distdir).shar.gz $(am__post_remove_distdir) dist-zip: distdir @@ -977,7 +977,7 @@ distcheck: dist case '$(DIST_ARCHIVES)' in \ *.tar.gz*) \ - GZIP=$(GZIP_ENV) gzip -dc $(distdir).tar.gz | $(am__untar) ;;\ + eval GZIP= gzip $(GZIP_ENV) -dc $(distdir).tar.gz | $(am__untar) ;;\ *.tar.bz2*) \ bzip2 -dc $(distdir).tar.bz2 | $(am__untar) ;;\ *.tar.lz*) \ @@ -987,7 +987,7 @@ *.tar.Z*) \ uncompress -c $(distdir).tar.Z | $(am__untar) ;;\ *.shar.gz*) \ - GZIP=$(GZIP_ENV) gzip -dc $(distdir).shar.gz | unshar ;;\ + eval GZIP= gzip $(GZIP_ENV) -dc $(distdir).shar.gz | unshar ;;\ *.zip*) \ unzip $(distdir).zip ;;\ esac diff -u -r -N squid-4.0.20/Makefile.in squid-4.0.21/Makefile.in --- squid-4.0.20/Makefile.in 2017-06-02 00:52:41.000000000 +1200 +++ squid-4.0.21/Makefile.in 2017-07-02 20:41:23.000000000 +1200 @@ -1,7 +1,7 @@ -# Makefile.in generated by automake 1.15 from Makefile.am. +# Makefile.in generated by automake 1.15.1 from Makefile.am. # @configure_input@ -# Copyright (C) 1994-2014 Free Software Foundation, Inc. +# Copyright (C) 1994-2017 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -746,7 +746,7 @@ ! -type d ! -perm -444 -exec $(install_sh) -c -m a+r {} {} \; \ || chmod -R a+r "$(distdir)" dist-gzip: distdir - tardir=$(distdir) && $(am__tar) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).tar.gz + tardir=$(distdir) && $(am__tar) | eval GZIP= gzip $(GZIP_ENV) -c >$(distdir).tar.gz $(am__post_remove_distdir) dist-bzip2: distdir tardir=$(distdir) && $(am__tar) | BZIP2=$${BZIP2--9} bzip2 -c >$(distdir).tar.bz2 @@ -771,7 +771,7 @@ @echo WARNING: "Support for shar distribution archives is" \ "deprecated." >&2 @echo WARNING: "It will be removed altogether in Automake 2.0" >&2 - shar $(distdir) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).shar.gz + shar $(distdir) | eval GZIP= gzip $(GZIP_ENV) -c >$(distdir).shar.gz $(am__post_remove_distdir) dist-zip: distdir @@ -789,7 +789,7 @@ distcheck: dist case '$(DIST_ARCHIVES)' in \ *.tar.gz*) \ - GZIP=$(GZIP_ENV) gzip -dc $(distdir).tar.gz | $(am__untar) ;;\ + eval GZIP= gzip $(GZIP_ENV) -dc $(distdir).tar.gz | $(am__untar) ;;\ *.tar.bz2*) \ bzip2 -dc $(distdir).tar.bz2 | $(am__untar) ;;\ *.tar.lz*) \ @@ -799,7 +799,7 @@ *.tar.Z*) \ uncompress -c $(distdir).tar.Z | $(am__untar) ;;\ *.shar.gz*) \ - GZIP=$(GZIP_ENV) gzip -dc $(distdir).shar.gz | unshar ;;\ + eval GZIP= gzip $(GZIP_ENV) -dc $(distdir).shar.gz | unshar ;;\ *.zip*) \ unzip $(distdir).zip ;;\ esac diff -u -r -N squid-4.0.20/po4a.conf squid-4.0.21/po4a.conf --- squid-4.0.20/po4a.conf 2017-06-02 00:49:17.000000000 +1200 +++ squid-4.0.21/po4a.conf 2017-07-02 20:41:18.000000000 +1200 @@ -2,46 +2,50 @@ [po4a_paths] doc/manuals/manuals.pot $lang:doc/manuals/$lang.po -[type: man] helpers/basic_auth/getpwnam/basic_getpwnam_auth.8 $lang:doc/manuals/$lang/basic_getpwnam_auth.8 +[type: man] src/acl/external/AD_group/ext_ad_group_acl.8 $lang:doc/manuals/$lang/ext_ad_group_acl.8 -[type: man] helpers/basic_auth/LDAP/basic_ldap_auth.8 $lang:doc/manuals/$lang/basic_ldap_auth.8 +[type: man] src/acl/external/eDirectory_userip/ext_edirectory_userip_acl.8 $lang:doc/manuals/$lang/ext_edirectory_userip_acl.8 -[type: man] helpers/basic_auth/NCSA/basic_ncsa_auth.8 $lang:doc/manuals/$lang/basic_ncsa_auth.8 +[type: man] src/acl/external/file_userip/ext_file_userip_acl.8 $lang:doc/manuals/$lang/ext_file_userip_acl.8 -[type: man] helpers/basic_auth/PAM/basic_pam_auth.8 $lang:doc/manuals/$lang/basic_pam_auth.8 +[type: man] src/acl/external/kerberos_ldap_group/ext_kerberos_ldap_group_acl.8 $lang:doc/manuals/$lang/ext_kerberos_ldap_group_acl.8 -[type: man] helpers/basic_auth/RADIUS/basic_radius_auth.8 $lang:doc/manuals/$lang/basic_radius_auth.8 +[type: man] src/acl/external/LDAP_group/ext_ldap_group_acl.8 $lang:doc/manuals/$lang/ext_ldap_group_acl.8 -[type: man] helpers/basic_auth/SASL/basic_sasl_auth.8 $lang:doc/manuals/$lang/basic_sasl_auth.8 +[type: man] src/acl/external/LM_group/ext_lm_group_acl.8 $lang:doc/manuals/$lang/ext_lm_group_acl.8 -[type: man] helpers/basic_auth/SSPI/basic_sspi_auth.8 $lang:doc/manuals/$lang/basic_sspi_auth.8 +[type: man] src/acl/external/session/ext_session_acl.8 $lang:doc/manuals/$lang/ext_session_acl.8 -[type: man] helpers/digest_auth/file/digest_file_auth.8 $lang:doc/manuals/$lang/digest_file_auth.8 +[type: man] src/acl/external/time_quota/ext_time_quota_acl.8 $lang:doc/manuals/$lang/ext_time_quota_acl.8 -[type: man] helpers/external_acl/AD_group/ext_ad_group_acl.8 $lang:doc/manuals/$lang/ext_ad_group_acl.8 +[type: man] src/acl/external/unix_group/ext_unix_group_acl.8 $lang:doc/manuals/$lang/ext_unix_group_acl.8 -[type: man] helpers/external_acl/eDirectory_userip/ext_edirectory_userip_acl.8 $lang:doc/manuals/$lang/ext_edirectory_userip_acl.8 +[type: man] src/auth/basic/getpwnam/basic_getpwnam_auth.8 $lang:doc/manuals/$lang/basic_getpwnam_auth.8 -[type: man] helpers/external_acl/file_userip/ext_file_userip_acl.8 $lang:doc/manuals/$lang/ext_file_userip_acl.8 +[type: man] src/auth/basic/LDAP/basic_ldap_auth.8 $lang:doc/manuals/$lang/basic_ldap_auth.8 -[type: man] helpers/external_acl/kerberos_ldap_group/ext_kerberos_ldap_group_acl.8 $lang:doc/manuals/$lang/ext_kerberos_ldap_group_acl.8 +[type: man] src/auth/basic/NCSA/basic_ncsa_auth.8 $lang:doc/manuals/$lang/basic_ncsa_auth.8 -[type: man] helpers/external_acl/LDAP_group/ext_ldap_group_acl.8 $lang:doc/manuals/$lang/ext_ldap_group_acl.8 +[type: man] src/auth/basic/PAM/basic_pam_auth.8 $lang:doc/manuals/$lang/basic_pam_auth.8 -[type: man] helpers/external_acl/LM_group/ext_lm_group_acl.8 $lang:doc/manuals/$lang/ext_lm_group_acl.8 +[type: man] src/auth/basic/RADIUS/basic_radius_auth.8 $lang:doc/manuals/$lang/basic_radius_auth.8 -[type: man] helpers/external_acl/session/ext_session_acl.8 $lang:doc/manuals/$lang/ext_session_acl.8 +[type: man] src/auth/basic/SASL/basic_sasl_auth.8 $lang:doc/manuals/$lang/basic_sasl_auth.8 -[type: man] helpers/external_acl/time_quota/ext_time_quota_acl.8 $lang:doc/manuals/$lang/ext_time_quota_acl.8 +[type: man] src/auth/basic/SSPI/basic_sspi_auth.8 $lang:doc/manuals/$lang/basic_sspi_auth.8 -[type: man] helpers/external_acl/unix_group/ext_unix_group_acl.8 $lang:doc/manuals/$lang/ext_unix_group_acl.8 +[type: man] src/auth/digest/file/digest_file_auth.8 $lang:doc/manuals/$lang/digest_file_auth.8 -[type: man] helpers/negotiate_auth/kerberos/negotiate_kerberos_auth.8 $lang:doc/manuals/$lang/negotiate_kerberos_auth.8 +[type: man] src/auth/negotiate/kerberos/negotiate_kerberos_auth.8 $lang:doc/manuals/$lang/negotiate_kerberos_auth.8 -[type: man] helpers/ntlm_auth/SSPI/ntlm_sspi_auth.8 $lang:doc/manuals/$lang/ntlm_sspi_auth.8 +[type: man] src/auth/ntlm/SSPI/ntlm_sspi_auth.8 $lang:doc/manuals/$lang/ntlm_sspi_auth.8 + +[type: man] src/security/cert_generators/file/security_file_certgen.8.in $lang:doc/manuals/$lang/security_file_certgen.8.in [type: man] src/squid.8.in $lang:doc/manuals/$lang/squid.8.in [type: man] tools/cachemgr.cgi.8.in $lang:doc/manuals/$lang/cachemgr.cgi.8.in +[type: man] tools/purge/purge.1 $lang:doc/manuals/$lang/purge.1 + [type: man] tools/squidclient/squidclient.1 $lang:doc/manuals/$lang/squidclient.1 diff -u -r -N squid-4.0.20/RELEASENOTES.html squid-4.0.21/RELEASENOTES.html --- squid-4.0.20/RELEASENOTES.html 2017-06-02 09:49:09.000000000 +1200 +++ squid-4.0.21/RELEASENOTES.html 2017-07-02 20:57:33.000000000 +1200 @@ -2,10 +2,10 @@ - Squid 4.0.20 release notes + Squid 4.0.21 release notes -

Squid 4.0.20 release notes

+

Squid 4.0.21 release notes

Squid Developers


@@ -62,7 +62,7 @@

1. Notice

-

The Squid Team are pleased to announce the release of Squid-4.0.20 for testing.

+

The Squid Team are pleased to announce the release of Squid-4.0.21 for testing.

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

@@ -237,10 +237,9 @@ integration with daemon managers such as Upstart or systemd which assume the process they initiated is the daemon with a PID to control.

-

The squid binary now has a new --foreground command line option -which prevents the process from exiting early while background workers -continue their processing. When run with this option Squid will now wait -for the worker(s) to finish before exiting. Unlike the old -N option +

The squid binary now has a new --foreground command line option, +which (only) prevents daemonizing the master process. +Unlike the old -N option, --foreground supports SMP workers and multi-process features. --foreground is particularly useful for use with -z (disk cache structures creation), as it allows the caller to wait until Squid has @@ -342,6 +341,11 @@ including messages received from ICAP servers.

New has type for matching whether or not Squid is able to provide certain sets of transaction state. For example HTTP reply headers.

+

New transaction_initiator type for detecting various +unusual transactions.

+

New --consensus, --client-requested and +--server-provided flags for the ssl::server_name +type to control which server name to match against.

auth_param

New parameter queue-size= to set the maximum number diff -u -r -N squid-4.0.20/scripts/Makefile.in squid-4.0.21/scripts/Makefile.in --- squid-4.0.20/scripts/Makefile.in 2017-06-02 00:53:23.000000000 +1200 +++ squid-4.0.21/scripts/Makefile.in 2017-07-02 20:41:24.000000000 +1200 @@ -1,7 +1,7 @@ -# Makefile.in generated by automake 1.15 from Makefile.am. +# Makefile.in generated by automake 1.15.1 from Makefile.am. # @configure_input@ -# Copyright (C) 1994-2014 Free Software Foundation, Inc. +# Copyright (C) 1994-2017 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, diff -u -r -N squid-4.0.20/src/acl/Acl.cc squid-4.0.21/src/acl/Acl.cc --- squid-4.0.20/src/acl/Acl.cc 2017-06-02 00:49:17.000000000 +1200 +++ squid-4.0.21/src/acl/Acl.cc 2017-07-02 20:41:18.000000000 +1200 @@ -12,187 +12,68 @@ #include "acl/Acl.h" #include "acl/Checklist.h" #include "acl/Gadgets.h" +#include "acl/Options.h" #include "anyp/PortCfg.h" #include "cache_cf.h" #include "ConfigParser.h" #include "Debug.h" -#include "dlink.h" #include "fatal.h" #include "globals.h" #include "profiler/Profiler.h" +#include "sbuf/List.h" +#include "sbuf/Stream.h" #include "SquidConfig.h" -#include - -#define abortFlags(CONTENT) \ - do { \ - debugs(28, 0, CONTENT); \ - self_destruct(); \ - } while (0) - -const ACLFlag ACLFlags::NoFlags[1] = {ACL_F_END}; +#include +#include const char *AclMatchedName = NULL; -ACLFlags::FlagsTokenizer::FlagsTokenizer(): tokPos(NULL) { } +namespace Acl { -ACLFlag -ACLFlags::FlagsTokenizer::nextFlag() -{ - if (needNextToken()) { - if (!nextToken()) - return 0; - } else - ++tokPos; - return *tokPos; -} - -bool -ACLFlags::FlagsTokenizer::hasParameter() const -{ - return tokPos && tokPos[0] && tokPos[1] == '=' && tokPos[2]; -} +/// ACL type name comparison functor +class TypeNameCmp { +public: + bool operator()(TypeName a, TypeName b) const { return strcmp(a, b) < 0; } +}; -SBuf -ACLFlags::FlagsTokenizer::getParameter() const -{ - return hasParameter() ? SBuf(&tokPos[2]) : SBuf(); -} +/// ACL makers indexed by ACL type name +typedef std::map Makers; -bool -ACLFlags::FlagsTokenizer::needNextToken() const +/// registered ACL Makers +static Makers & +TheMakers() { - return !tokPos || !tokPos[0] || !tokPos[1] || tokPos[1] == '='; -} - -bool -ACLFlags::FlagsTokenizer::nextToken() -{ - char *t = ConfigParser::PeekAtToken(); - if (t == NULL || t[0] != '-' || !t[1]) - return false; - (void)ConfigParser::NextQuotedToken(); - if (strcmp(t, "--") == 0) - return false; - tokPos = t + 1; - return true; -} - -ACLFlags::~ACLFlags() -{ - delete delimiters_; -} - -ACLFlags::Status -ACLFlags::flagStatus(const ACLFlag f) const -{ - if (f == ACL_F_REGEX_CASE) - return noParameter; - if (f == ACL_F_SUBSTRING) - return parameterOptional; - if (supported_.find(f) != std::string::npos) - return noParameter; - return notSupported; -} - -bool -ACLFlags::parameterSupported(const ACLFlag f, const SBuf &val) const -{ - if (f == ACL_F_SUBSTRING) - return val.findFirstOf(CharacterSet::ALPHA + CharacterSet::DIGIT) == SBuf::npos; - return true; + static Makers Registry; + return Registry; } -void -ACLFlags::makeSet(const ACLFlag f, const SBuf ¶m) -{ - flags_ |= flagToInt(f); - if (!param.isEmpty()) - flagParameters_[f].append(param); -} - -void -ACLFlags::makeUnSet(const ACLFlag f) -{ - flags_ &= ~flagToInt(f); - flagParameters_[f].clear(); -} - -void -ACLFlags::parseFlags() +/// creates an ACL object of the named (and already registered) ACL child type +static +ACL * +Make(TypeName typeName) { - FlagsTokenizer tokenizer; - ACLFlag flag('\0'); - while ((flag = tokenizer.nextFlag())) { - switch (flagStatus(flag)) - { - case notSupported: - abortFlags("Flag '" << flag << "' not supported"); - break; - case noParameter: - makeSet(flag); - break; - case parameterRequired: - if (!tokenizer.hasParameter()) { - abortFlags("Flag '" << flag << "' must have a parameter"); - break; - } - case parameterOptional: - SBuf param; - if (tokenizer.hasParameter()) { - param = tokenizer.getParameter(); - if (!parameterSupported(flag, param)) - abortFlags("Parameter '" << param << "' for flag '" << flag << "' not supported"); - } - makeSet(flag, param); - break; - } - } - - /*Regex code needs to parse -i file*/ - if ( isSet(ACL_F_REGEX_CASE)) { - ConfigParser::TokenPutBack("-i"); - makeUnSet('i'); + const auto pos = TheMakers().find(typeName); + if (pos == TheMakers().end()) { + debugs(28, DBG_CRITICAL, "FATAL: Invalid ACL type '" << typeName << "'"); + self_destruct(); + assert(false); // not reached } -} -SBuf -ACLFlags::parameter(const ACLFlag f) const -{ - assert(static_cast(f - 'A') < FlagIndexMax); - auto p = flagParameters_.find(f); - return p == flagParameters_.end() ? SBuf() : p->second; + ACL *result = (pos->second)(pos->first); + debugs(28, 4, typeName << '=' << result); + assert(result); + return result; } -const CharacterSet * -ACLFlags::delimiters() -{ - if (isSet(ACL_F_SUBSTRING) && !delimiters_) { - static const SBuf defaultParameter(","); - SBuf rawParameter = parameter(ACL_F_SUBSTRING); - if (rawParameter.isEmpty()) - rawParameter = defaultParameter; - delimiters_ = new CharacterSet("ACLFlags::delimiters", rawParameter.c_str()); - } - return delimiters_; -} +} // namespace Acl -const char * -ACLFlags::flagsStr() const +void +Acl::RegisterMaker(TypeName typeName, Maker maker) { - static char buf[64]; - if (flags_ == 0) - return ""; - - char *s = buf; - *s++ = '-'; - for (ACLFlag f = 'A'; f <= 'z'; f++) { - // ACL_F_REGEX_CASE (-i) flag handled by ACLRegexData class, ignore - if (isSet(f) && f != ACL_F_REGEX_CASE) - *s++ = f; - } - *s = '\0'; - return buf; + assert(typeName); + assert(*typeName); + TheMakers().emplace(typeName, maker); } void * @@ -223,17 +104,6 @@ return NULL; } -ACL * -ACL::Factory (char const *type) -{ - ACL *result = Prototype::Factory (type); - - if (!result) - fatal ("Unknown acl type in ACL::Factory"); - - return result; -} - ACL::ACL() : cfgline(nullptr), next(nullptr), @@ -242,15 +112,6 @@ *name = 0; } -ACL::ACL(const ACLFlag flgs[]) : - cfgline(NULL), - next(NULL), - flags(flgs), - registered(false) -{ - *name = 0; -} - bool ACL::valid () const { return true; @@ -365,16 +226,9 @@ return; // ignore the line } - if (!Prototype::Registered(theType)) { - debugs(28, DBG_CRITICAL, "FATAL: Invalid ACL type '" << theType << "'"); - // XXX: make this an ERROR and skip the ACL creation. We *may* die later when its use is attempted. Or may not. - parser.destruct(); - return; - } - if ((A = FindByName(aclname)) == NULL) { debugs(28, 3, "aclParseAclLine: Creating ACL '" << aclname << "'"); - A = ACL::Factory(theType); + A = Acl::Make(theType); A->context(aclname, config_input_line); new_acl = 1; } else { @@ -394,7 +248,7 @@ */ AclMatchedName = A->name; /* ugly */ - A->flags.parseFlags(); + A->parseFlags(); /*split the function here */ A->parse(); @@ -431,6 +285,30 @@ return false; } +void +ACL::parseFlags() +{ + // ACL kids that carry ACLData which supports parameter flags override this + Acl::ParseFlags(options(), Acl::NoFlags()); +} + +SBufList +ACL::dumpOptions() +{ + SBufList result; + const auto &myOptions = options(); + // optimization: most ACLs do not have myOptions + // this check also works around dump_SBufList() adding ' ' after empty items + if (!myOptions.empty()) { + SBufStream stream; + stream << myOptions; + const SBuf optionsImage = stream.buf(); + if (!optionsImage.isEmpty()) + result.push_back(optionsImage); + } + return result; +} + /* ACL result caching routines */ int @@ -522,69 +400,6 @@ AclMatchedName = NULL; // in case it was pointing to our name } -ACL::Prototype::Prototype() : prototype (NULL), typeString (NULL) {} - -ACL::Prototype::Prototype (ACL const *aPrototype, char const *aType) : prototype (aPrototype), typeString (aType) -{ - registerMe (); -} - -std::vector * ACL::Prototype::Registry; -void *ACL::Prototype::Initialized; - -bool -ACL::Prototype::Registered(char const *aType) -{ - debugs(28, 7, "ACL::Prototype::Registered: invoked for type " << aType); - - for (iterator i = Registry->begin(); i != Registry->end(); ++i) - if (!strcmp (aType, (*i)->typeString)) { - debugs(28, 7, "ACL::Prototype::Registered: yes"); - return true; - } - - debugs(28, 7, "ACL::Prototype::Registered: no"); - return false; -} - -void -ACL::Prototype::registerMe () -{ - if (!Registry || (Initialized != ((char *)Registry - 5)) ) { - /* TODO: extract this */ - /* Not initialised */ - Registry = new std::vector; - Initialized = (char *)Registry - 5; - } - - if (Registered (typeString)) - fatalf ("Attempt to register %s twice", typeString); - - Registry->push_back (this); -} - -ACL::Prototype::~Prototype() -{ - // TODO: unregister me -} - -ACL * -ACL::Prototype::Factory (char const *typeToClone) -{ - debugs(28, 4, "ACL::Prototype::Factory: cloning an object for type '" << typeToClone << "'"); - - for (iterator i = Registry->begin(); i != Registry->end(); ++i) - if (!strcmp (typeToClone, (*i)->typeString)) { - ACL *A = (*i)->prototype->clone(); - A->flags = (*i)->prototype->flags; - return A; - } - - debugs(28, 4, "ACL::Prototype::Factory: cloning failed, no type '" << typeToClone << "' available"); - - return NULL; -} - void ACL::Initialize() { diff -u -r -N squid-4.0.20/src/acl/Acl.h squid-4.0.21/src/acl/Acl.h --- squid-4.0.20/src/acl/Acl.h 2017-06-02 00:49:17.000000000 +1200 +++ squid-4.0.21/src/acl/Acl.h 2017-07-02 20:41:18.000000000 +1200 @@ -10,109 +10,27 @@ #define SQUID_ACL_H #include "acl/forward.h" -#include "base/CharacterSet.h" +#include "acl/Options.h" #include "cbdata.h" #include "defines.h" #include "dlink.h" -#include "sbuf/List.h" +#include "sbuf/forward.h" -#include +#include #include -#include -#include class ConfigParser; -typedef char ACLFlag; -// ACLData Flags -#define ACL_F_REGEX_CASE 'i' -#define ACL_F_NO_LOOKUP 'n' -#define ACL_F_STRICT 's' -#define ACL_F_SUBSTRING 'm' -#define ACL_F_END '\0' - -/** - * \ingroup ACLAPI - * Used to hold a list of one-letter flags which can be passed as parameters - * to acls (eg '-i', '-n' etc) - */ -class ACLFlags -{ -public: - enum Status - { - notSupported, - noParameter, - parameterOptional, - parameterRequired - }; - - explicit ACLFlags(const ACLFlag flags[]) : supported_(flags), flags_(0), delimiters_(nullptr) {} - ACLFlags() : flags_(0), delimiters_(nullptr) {} - ~ACLFlags(); - /// \return a Status for the given ACLFlag. - Status flagStatus(const ACLFlag f) const; - /// \return true if the parameter for the given flag is acceptable. - bool parameterSupported(const ACLFlag f, const SBuf &val) const; - /// Set the given flag - void makeSet(const ACLFlag f, const SBuf ¶m = SBuf("")); - void makeUnSet(const ACLFlag f); ///< Unset the given flag - /// \return true if the given flag is set. - bool isSet(const ACLFlag f) const { return flags_ & flagToInt(f);} - /// \return the parameter value of the given flag if set. - SBuf parameter(const ACLFlag f) const; - /// \return ACL_F_SUBSTRING parameter value(if set) converted to CharacterSet. - const CharacterSet *delimiters(); - /// Parse optional flags given in the form -[A..Z|a..z] - void parseFlags(); - const char *flagsStr() const; ///< Convert the flags to a string representation - /** - * Lexical analyzer for ACL flags - * - * Support tokens in the form: - * flag := '-' [A-Z|a-z]+ ['=' parameter ] - * Each token consist by one or more single-letter flags, which may - * followed by a parameter string. - * The parameter can belongs only to the last flag in token. - */ - class FlagsTokenizer - { - public: - FlagsTokenizer(); - ACLFlag nextFlag(); ///< The next flag or '\0' if finished - /// \return true if a parameter follows the last parsed flag. - bool hasParameter() const; - /// \return the parameter of last parsed flag, if exist. - SBuf getParameter() const; - - private: - /// \return true if the current token parsing is finished. - bool needNextToken() const; - /// Peeks at the next token and return false if the next token - /// is not flag, or a '--' is read. - bool nextToken(); +namespace Acl { - char *tokPos; - }; +/// the ACL type name known to admins +typedef const char *TypeName; +/// a "factory" function for making ACL objects (of some ACL child type) +typedef ACL *(*Maker)(TypeName typeName); +/// use the given ACL Maker for all ACLs of the named type +void RegisterMaker(TypeName typeName, Maker maker); -private: - /// Convert a flag to a 64bit unsigned integer. - /// The characters from 'A' to 'z' represented by the values from 65 to 122. - /// They are 57 different characters which can be fit to the bits of an 64bit - /// integer. - uint64_t flagToInt(const ACLFlag f) const { - assert('A' <= f && f <= 'z'); - return ((uint64_t)1 << (f - 'A')); - } - - std::string supported_; ///< The supported character flags - uint64_t flags_; ///< The flags which are set - static const uint32_t FlagIndexMax = 'z' - 'A'; - std::map flagParameters_; - CharacterSet *delimiters_; -public: - static const ACLFlag NoFlags[1]; ///< An empty flags list -}; +} // namespace Acl /// A configurable condition. A node in the ACL expression tree. /// Can evaluate itself in FilledChecklist context. @@ -125,13 +43,11 @@ void *operator new(size_t); void operator delete(void *); - static ACL *Factory(char const *); static void ParseAclLine(ConfigParser &parser, ACL ** head); static void Initialize(); static ACL *FindByName(const char *name); ACL(); - explicit ACL(const ACLFlag flgs[]); virtual ~ACL(); /// sets user-specified ACL name and squid.conf context @@ -143,7 +59,11 @@ /// Updates the checklist state on match, async, and failure. bool matches(ACLChecklist *checklist) const; - virtual ACL *clone() const = 0; + /// \returns (linked) Options supported by this ACL + virtual const Acl::Options &options() { return Acl::NoOptions(); } + + /// configures ACL options, throwing on configuration errors + virtual void parseFlags(); /// parses node represenation in squid.conf; dies on failures virtual void parse() = 0; @@ -158,36 +78,13 @@ virtual void prepareForUse() {} + SBufList dumpOptions(); ///< \returns approximate options configuration + char name[ACL_NAME_SZ]; char *cfgline; ACL *next; // XXX: remove or at least use refcounting - ACLFlags flags; ///< The list of given ACL flags bool registered; ///< added to the global list of ACLs via aclRegister() -public: - - class Prototype - { - - public: - Prototype(); - Prototype(ACL const *, char const *); - ~Prototype(); - static bool Registered(char const *); - static ACL *Factory(char const *); - - private: - ACL const *prototype; - char const *typeString; - - private: - static std::vector * Registry; - static void *Initialized; - typedef std::vector::iterator iterator; - typedef std::vector::const_iterator const_iterator; - void registerMe(); - }; - private: /// Matches the actual data in checklist against this ACL. virtual int match(ACLChecklist *checklist) = 0; // XXX: missing const @@ -237,6 +134,22 @@ return code; } + /// Whether an "allow" rule matched. If in doubt, use this popular method. + /// Also use this method to treat exceptional ACCESS_DUNNO and + /// ACCESS_AUTH_REQUIRED outcomes as if a "deny" rule matched. + /// See also: denied(). + bool allowed() const { return code == ACCESS_ALLOWED; } + + /// Whether a "deny" rule matched. Avoid this rarely used method. + /// Use this method (only) to treat exceptional ACCESS_DUNNO and + /// ACCESS_AUTH_REQUIRED outcomes as if an "allow" rule matched. + /// See also: allowed(). + bool denied() const { return code == ACCESS_DENIED; } + + /// whether there was either a default rule, a rule without any ACLs, or a + /// a rule with ACLs that all matched + bool someRuleMatched() const { return allowed() || denied(); } + aclMatchCode code; ///< ACCESS_* code int kind; ///< which custom access list verb matched }; diff -u -r -N squid-4.0.20/src/acl/AdaptationService.cc squid-4.0.21/src/acl/AdaptationService.cc --- squid-4.0.20/src/acl/AdaptationService.cc 2017-06-02 00:49:17.000000000 +1200 +++ squid-4.0.21/src/acl/AdaptationService.cc 2017-07-02 20:41:18.000000000 +1200 @@ -8,14 +8,14 @@ #include "squid.h" #include "acl/AdaptationService.h" -#include "acl/Checklist.h" +#include "acl/FilledChecklist.h" #include "acl/IntRange.h" #include "adaptation/Config.h" #include "adaptation/History.h" #include "HttpRequest.h" int -ACLAdaptationServiceStrategy::match (ACLData * &data, ACLFilledChecklist *checklist, ACLFlags &) +ACLAdaptationServiceStrategy::match (ACLData * &data, ACLFilledChecklist *checklist) { HttpRequest::Pointer request = checklist->request; if (request == NULL) @@ -33,11 +33,3 @@ return 0; } -ACLAdaptationServiceStrategy * -ACLAdaptationServiceStrategy::Instance() -{ - return &Instance_; -} - -ACLAdaptationServiceStrategy ACLAdaptationServiceStrategy::Instance_; - diff -u -r -N squid-4.0.20/src/acl/AdaptationService.h squid-4.0.21/src/acl/AdaptationService.h --- squid-4.0.20/src/acl/AdaptationService.h 2017-06-02 00:49:17.000000000 +1200 +++ squid-4.0.21/src/acl/AdaptationService.h 2017-07-02 20:41:18.000000000 +1200 @@ -9,7 +9,6 @@ #ifndef SQUID_ACLADAPTATIONSERVICE_H #define SQUID_ACLADAPTATIONSERVICE_H -#include "acl/Strategised.h" #include "acl/Strategy.h" /// \ingroup ACLAPI @@ -17,27 +16,7 @@ { public: - virtual int match (ACLData * &, ACLFilledChecklist *, ACLFlags &); - static ACLAdaptationServiceStrategy *Instance(); - /** - * Not implemented to prevent copies of the instance. - */ - ACLAdaptationServiceStrategy(ACLAdaptationServiceStrategy const &); - -private: - static ACLAdaptationServiceStrategy Instance_; - ACLAdaptationServiceStrategy() {} - - ACLAdaptationServiceStrategy &operator = (ACLAdaptationServiceStrategy const &); -}; - -/// \ingroup ACLAPI -class ACLAdaptationService -{ - -private: - static ACL::Prototype RegistryProtoype; - static ACLStrategised RegistryEntry_; + virtual int match (ACLData * &, ACLFilledChecklist *) override; }; #endif /* SQUID_ACLADAPTATIONSERVICE_H */ diff -u -r -N squid-4.0.20/src/acl/AllOf.h squid-4.0.21/src/acl/AllOf.h --- squid-4.0.20/src/acl/AllOf.h 2017-06-02 00:49:17.000000000 +1200 +++ squid-4.0.21/src/acl/AllOf.h 2017-07-02 20:41:18.000000000 +1200 @@ -31,9 +31,6 @@ private: /* Acl::InnerNode API */ virtual int doMatch(ACLChecklist *checklist, Nodes::const_iterator start) const; - - static Prototype RegistryProtoype; - static AllOf RegistryEntry_; }; } // namespace Acl diff -u -r -N squid-4.0.20/src/acl/AnyOf.h squid-4.0.21/src/acl/AnyOf.h --- squid-4.0.20/src/acl/AnyOf.h 2017-06-02 00:49:17.000000000 +1200 +++ squid-4.0.21/src/acl/AnyOf.h 2017-07-02 20:41:18.000000000 +1200 @@ -24,10 +24,6 @@ virtual char const *typeString() const; virtual ACL *clone() const; virtual void parse(); - -private: - static Prototype RegistryProtoype; - static AnyOf RegistryEntry_; }; } // namespace Acl diff -u -r -N squid-4.0.20/src/acl/Arp.h squid-4.0.21/src/acl/Arp.h --- squid-4.0.20/src/acl/Arp.h 2017-06-02 00:49:17.000000000 +1200 +++ squid-4.0.21/src/acl/Arp.h 2017-07-02 20:41:18.000000000 +1200 @@ -10,7 +10,6 @@ #define SQUID_ACLARP_H #include "acl/Acl.h" -#include "acl/Checklist.h" #include @@ -38,8 +37,6 @@ virtual bool empty () const; protected: - static Prototype RegistryProtoype; - static ACLARP RegistryEntry_; char const *class_; typedef std::set AclArpData_t; AclArpData_t aclArpData; diff -u -r -N squid-4.0.20/src/acl/Asn.cc squid-4.0.21/src/acl/Asn.cc --- squid-4.0.20/src/acl/Asn.cc 2017-06-02 00:49:17.000000000 +1200 +++ squid-4.0.21/src/acl/Asn.cc 2017-07-02 20:41:18.000000000 +1200 @@ -15,10 +15,12 @@ #include "acl/DestinationAsn.h" #include "acl/DestinationIp.h" #include "acl/SourceAsn.h" +#include "acl/Strategised.h" #include "FwdState.h" #include "HttpReply.h" #include "HttpRequest.h" #include "ipcache.h" +#include "MasterXaction.h" #include "mgr/Registration.h" #include "radix.h" #include "RequestFlags.h" @@ -239,7 +241,8 @@ debugs(53, 3, "AS " << as); snprintf(asres, 4096, "whois://%s/!gAS%d", Config.as_whois_server, as); asState->as_number = as; - asState->request = HttpRequest::CreateFromUrl(asres); + const MasterXaction::Pointer mx = new MasterXaction(XactionInitiator::initAsn); + asState->request = HttpRequest::FromUrl(asres, mx); assert(asState->request != NULL); if ((e = storeGetPublic(asres, Http::METHOD_GET)) == NULL) { @@ -577,30 +580,14 @@ template class ACLStrategised; -ACL::Prototype ACLASN::SourceRegistryProtoype(&ACLASN::SourceRegistryEntry_, "src_as"); - -ACLStrategised ACLASN::SourceRegistryEntry_(new ACLASN, ACLSourceASNStrategy::Instance(), "src_as"); - -ACL::Prototype ACLASN::DestinationRegistryProtoype(&ACLASN::DestinationRegistryEntry_, "dst_as"); - -ACLStrategised ACLASN::DestinationRegistryEntry_(new ACLASN, ACLDestinationASNStrategy::Instance(), "dst_as"); - int -ACLSourceASNStrategy::match (ACLData * &data, ACLFilledChecklist *checklist, ACLFlags &) +ACLSourceASNStrategy::match (ACLData * &data, ACLFilledChecklist *checklist) { return data->match(checklist->src_addr); } -ACLSourceASNStrategy * -ACLSourceASNStrategy::Instance() -{ - return &Instance_; -} - -ACLSourceASNStrategy ACLSourceASNStrategy::Instance_; - int -ACLDestinationASNStrategy::match (ACLData * &data, ACLFilledChecklist *checklist, ACLFlags &) +ACLDestinationASNStrategy::match (ACLData * &data, ACLFilledChecklist *checklist) { const ipcache_addrs *ia = ipcache_gethostbyname(checklist->request->url.host(), IP_LOOKUP_IF_MISS); @@ -624,11 +611,3 @@ return data->match(noaddr); } -ACLDestinationASNStrategy * -ACLDestinationASNStrategy::Instance() -{ - return &Instance_; -} - -ACLDestinationASNStrategy ACLDestinationASNStrategy::Instance_; - diff -u -r -N squid-4.0.20/src/acl/Asn.h squid-4.0.21/src/acl/Asn.h --- squid-4.0.20/src/acl/Asn.h 2017-06-02 00:49:17.000000000 +1200 +++ squid-4.0.21/src/acl/Asn.h 2017-07-02 20:41:18.000000000 +1200 @@ -9,9 +9,7 @@ #ifndef SQUID_ACLASN_H #define SQUID_ACLASN_H -#include "acl/Checklist.h" #include "acl/Data.h" -#include "acl/Strategised.h" #include "base/CbDataList.h" #include "ip/Address.h" @@ -40,10 +38,6 @@ virtual void prepareForUse(); private: - static ACL::Prototype SourceRegistryProtoype; - static ACLStrategised SourceRegistryEntry_; - static ACL::Prototype DestinationRegistryProtoype; - static ACLStrategised DestinationRegistryEntry_; CbDataList *data; }; diff -u -r -N squid-4.0.20/src/acl/AtStep.cc squid-4.0.21/src/acl/AtStep.cc --- squid-4.0.20/src/acl/AtStep.cc 2017-06-02 00:49:17.000000000 +1200 +++ squid-4.0.21/src/acl/AtStep.cc 2017-07-02 20:41:18.000000000 +1200 @@ -12,13 +12,13 @@ #include "acl/AtStep.h" #include "acl/AtStepData.h" -#include "acl/Checklist.h" +#include "acl/FilledChecklist.h" #include "client_side.h" #include "http/Stream.h" #include "ssl/ServerBump.h" int -ACLAtStepStrategy::match (ACLData * &data, ACLFilledChecklist *checklist, ACLFlags &) +ACLAtStepStrategy::match (ACLData * &data, ACLFilledChecklist *checklist) { Ssl::ServerBump *bump = NULL; if (checklist->conn() != NULL && (bump = checklist->conn()->serverBump())) @@ -28,13 +28,5 @@ return 0; } -ACLAtStepStrategy * -ACLAtStepStrategy::Instance() -{ - return &Instance_; -} - -ACLAtStepStrategy ACLAtStepStrategy::Instance_; - #endif /* USE_OPENSSL */ diff -u -r -N squid-4.0.20/src/acl/AtStep.h squid-4.0.21/src/acl/AtStep.h --- squid-4.0.20/src/acl/AtStep.h 2017-06-02 00:49:17.000000000 +1200 +++ squid-4.0.21/src/acl/AtStep.h 2017-07-02 20:41:18.000000000 +1200 @@ -11,7 +11,6 @@ #if USE_OPENSSL -#include "acl/Strategised.h" #include "acl/Strategy.h" #include "ssl/support.h" @@ -20,25 +19,7 @@ { public: - virtual int match (ACLData * &, ACLFilledChecklist *, ACLFlags &); - static ACLAtStepStrategy *Instance(); - - // Not implemented to prevent copies of the instance. - ACLAtStepStrategy(ACLAtStepStrategy const &); - -private: - static ACLAtStepStrategy Instance_; - ACLAtStepStrategy() {} - - ACLAtStepStrategy&operator=(ACLAtStepStrategy const &); -}; - -class ACLAtStep -{ - -private: - static ACL::Prototype RegistryProtoype; - static ACLStrategised RegistryEntry_; + virtual int match (ACLData * &, ACLFilledChecklist *) override; }; #endif /* USE_OPENSSL */ diff -u -r -N squid-4.0.20/src/acl/BoolOps.cc squid-4.0.21/src/acl/BoolOps.cc --- squid-4.0.20/src/acl/BoolOps.cc 2017-06-02 00:49:17.000000000 +1200 +++ squid-4.0.21/src/acl/BoolOps.cc 2017-07-02 20:41:18.000000000 +1200 @@ -10,6 +10,7 @@ #include "acl/BoolOps.h" #include "acl/Checklist.h" #include "Debug.h" +#include "sbuf/SBuf.h" /* Acl::NotNode */ diff -u -r -N squid-4.0.20/src/acl/Browser.cc squid-4.0.21/src/acl/Browser.cc --- squid-4.0.20/src/acl/Browser.cc 2017-06-02 00:49:17.000000000 +1200 +++ squid-4.0.21/src/acl/Browser.cc 1970-01-01 12:00:00.000000000 +1200 @@ -1,19 +0,0 @@ -/* - * Copyright (C) 1996-2017 The Squid Software Foundation and contributors - * - * Squid software is distributed under GPLv2+ license and includes - * contributions from numerous individuals and organizations. - * Please see the COPYING and CONTRIBUTORS files for details. - */ - -/* DEBUG: section 28 Access Control */ - -#include "squid.h" -#include "acl/Browser.h" -#include "acl/Checklist.h" -#include "acl/RegexData.h" - -/* explicit template instantiation required for some systems */ - -template class ACLRequestHeaderStrategy; - diff -u -r -N squid-4.0.20/src/acl/Browser.h squid-4.0.21/src/acl/Browser.h --- squid-4.0.20/src/acl/Browser.h 2017-06-02 00:49:17.000000000 +1200 +++ squid-4.0.21/src/acl/Browser.h 1970-01-01 12:00:00.000000000 +1200 @@ -1,27 +0,0 @@ -/* - * Copyright (C) 1996-2017 The Squid Software Foundation and contributors - * - * Squid software is distributed under GPLv2+ license and includes - * contributions from numerous individuals and organizations. - * Please see the COPYING and CONTRIBUTORS files for details. - */ - -#ifndef SQUID_ACLBROWSER_H -#define SQUID_ACLBROWSER_H - -#include "acl/Acl.h" -#include "acl/Data.h" -#include "acl/RequestHeaderStrategy.h" -#include "acl/Strategised.h" - -/// \ingroup ACLAPI -class ACLBrowser -{ - -private: - static ACL::Prototype RegistryProtoype; - static ACLStrategised RegistryEntry_; -}; - -#endif /* SQUID_ACLBROWSER_H */ - diff -u -r -N squid-4.0.20/src/acl/Certificate.cc squid-4.0.21/src/acl/Certificate.cc --- squid-4.0.20/src/acl/Certificate.cc 2017-06-02 00:49:17.000000000 +1200 +++ squid-4.0.21/src/acl/Certificate.cc 2017-07-02 20:41:18.000000000 +1200 @@ -25,7 +25,7 @@ #include "HttpRequest.h" int -ACLCertificateStrategy::match (ACLData * &data, ACLFilledChecklist *checklist, ACLFlags &) +ACLCertificateStrategy::match (ACLData * &data, ACLFilledChecklist *checklist) { const int fd = checklist->fd(); const bool goodDescriptor = 0 <= fd && fd <= Biggest_FD; @@ -36,13 +36,5 @@ return res; } -ACLCertificateStrategy * -ACLCertificateStrategy::Instance() -{ - return &Instance_; -} - -ACLCertificateStrategy ACLCertificateStrategy::Instance_; - #endif /* USE_OPENSSL */ diff -u -r -N squid-4.0.20/src/acl/Certificate.h squid-4.0.21/src/acl/Certificate.h --- squid-4.0.20/src/acl/Certificate.h 2017-06-02 00:49:17.000000000 +1200 +++ squid-4.0.21/src/acl/Certificate.h 2017-07-02 20:41:18.000000000 +1200 @@ -20,29 +20,7 @@ { public: - virtual int match (ACLData * &, ACLFilledChecklist *, ACLFlags &); - static ACLCertificateStrategy *Instance(); - /* Not implemented to prevent copies of the instance. */ - /* Not private to prevent brain dead g+++ warnings about - * private constructors with no friends */ - ACLCertificateStrategy(ACLCertificateStrategy const &); - -private: - static ACLCertificateStrategy Instance_; - ACLCertificateStrategy() {} - - ACLCertificateStrategy&operator=(ACLCertificateStrategy const &); -}; - -/// \ingroup ACLAPI -class ACLCertificate -{ - -private: - static ACL::Prototype UserRegistryProtoype; - static ACLStrategised UserRegistryEntry_; - static ACL::Prototype CARegistryProtoype; - static ACLStrategised CARegistryEntry_; + virtual int match (ACLData * &, ACLFilledChecklist *); }; #endif /* SQUID_ACLCERTIFICATE_H */ diff -u -r -N squid-4.0.20/src/acl/CharacterSetOption.h squid-4.0.21/src/acl/CharacterSetOption.h --- squid-4.0.20/src/acl/CharacterSetOption.h 1970-01-01 12:00:00.000000000 +1200 +++ squid-4.0.21/src/acl/CharacterSetOption.h 2017-07-02 20:41:18.000000000 +1200 @@ -0,0 +1,50 @@ +/* + * Copyright (C) 1996-2017 The Squid Software Foundation and contributors + * + * Squid software is distributed under GPLv2+ license and includes + * contributions from numerous individuals and organizations. + * Please see the COPYING and CONTRIBUTORS files for details. + */ + +#ifndef SQUID_ACL_CHARACTER_SET_OPTION_H +#define SQUID_ACL_CHARACTER_SET_OPTION_H + +#include "acl/Options.h" +#include "base/CharacterSet.h" +#include "sbuf/SBuf.h" + +namespace Acl { + +typedef OptionValue CharacterSetOptionValue; + +/* TypedOption specializations */ + +template <> +inline +void +TypedOption::import(const SBuf &rawValue) const +{ + SBuf chars = rawValue; // because c_str() is not constant + recipient_->value = CharacterSet(__FILE__, chars.c_str()); +} + +template <> +inline +void +TypedOption::print(std::ostream &os) const +{ + recipient_->value.printChars(os); // TODO: Quote if needed. +} + +/// option value to configure one or more characters (e.g., -m=",;") +class CharacterSetOption: public TypedOption +{ +public: + typedef TypedOption Parent; + CharacterSetOption(): Parent(valueOptional) {} +}; + +} // namespace Acl + +#endif /* SQUID_ACL_CHARACTER_SET_OPTION_H */ + diff -u -r -N squid-4.0.20/src/acl/ConnectionsEncrypted.h squid-4.0.21/src/acl/ConnectionsEncrypted.h --- squid-4.0.20/src/acl/ConnectionsEncrypted.h 2017-06-02 00:49:17.000000000 +1200 +++ squid-4.0.21/src/acl/ConnectionsEncrypted.h 2017-07-02 20:41:18.000000000 +1200 @@ -33,8 +33,6 @@ virtual bool empty () const; protected: - static Prototype RegistryProtoype; - static ConnectionsEncrypted RegistryEntry_; char const *class_; }; diff -u -r -N squid-4.0.20/src/acl/Data.h squid-4.0.21/src/acl/Data.h --- squid-4.0.20/src/acl/Data.h 2017-06-02 00:49:17.000000000 +1200 +++ squid-4.0.21/src/acl/Data.h 2017-07-02 20:41:18.000000000 +1200 @@ -9,9 +9,10 @@ #ifndef SQUID_ACLDATA_H #define SQUID_ACLDATA_H +#include "acl/Options.h" #include "sbuf/List.h" -/// \ingroup ACLAPI +/// Configured ACL parameter(s) (e.g., domain names in dstdomain ACL). template class ACLData { @@ -20,6 +21,9 @@ virtual ~ACLData() {} + /// \returns the flags supported by these ACL parameters (e.g., "-i") + virtual const Acl::ParameterFlags &supportedFlags() const { return Acl::NoFlags(); } + virtual bool match(M) =0; virtual SBufList dump() const =0; virtual void parse() =0; diff -u -r -N squid-4.0.20/src/acl/DestinationAsn.h squid-4.0.21/src/acl/DestinationAsn.h --- squid-4.0.20/src/acl/DestinationAsn.h 2017-06-02 00:49:17.000000000 +1200 +++ squid-4.0.21/src/acl/DestinationAsn.h 2017-07-02 20:41:18.000000000 +1200 @@ -18,24 +18,8 @@ { public: - virtual int match (ACLData * &, ACLFilledChecklist *, ACLFlags &); + virtual int match (ACLData * &, ACLFilledChecklist *); virtual bool requiresRequest() const {return true;} - - static ACLDestinationASNStrategy *Instance(); - - /** - * Not implemented to prevent copies of the instance. - \par - * Not private to prevent brain dead g++ warnings about - * private constructors with no friends - */ - ACLDestinationASNStrategy(ACLDestinationASNStrategy const &); - -private: - static ACLDestinationASNStrategy Instance_; - ACLDestinationASNStrategy() {} - - ACLDestinationASNStrategy&operator=(ACLDestinationASNStrategy const &); }; #endif /* SQUID_ACLDESTINATIONASN_H */ diff -u -r -N squid-4.0.20/src/acl/DestinationDomain.cc squid-4.0.21/src/acl/DestinationDomain.cc --- squid-4.0.20/src/acl/DestinationDomain.cc 2017-06-02 00:49:17.000000000 +1200 +++ squid-4.0.21/src/acl/DestinationDomain.cc 2017-07-02 20:41:18.000000000 +1200 @@ -41,8 +41,19 @@ checklist->resumeNonBlockingCheck(DestinationDomainLookup::Instance()); } +/* ACLDestinationDomainStrategy */ + +const Acl::Options & +ACLDestinationDomainStrategy::options() +{ + static const Acl::BooleanOption LookupBanFlag; + static const Acl::Options MyOptions = { { "-n", &LookupBanFlag } }; + LookupBanFlag.linkWith(&lookupBanned); + return MyOptions; +} + int -ACLDestinationDomainStrategy::match (ACLData * &data, ACLFilledChecklist *checklist, ACLFlags &flags) +ACLDestinationDomainStrategy::match (ACLData * &data, ACLFilledChecklist *checklist) { assert(checklist != NULL && checklist->request != NULL); @@ -50,7 +61,7 @@ return 1; } - if (flags.isSet(ACL_F_NO_LOOKUP)) { + if (lookupBanned) { debugs(28, 3, "No-lookup DNS ACL '" << AclMatchedName << "' for " << checklist->request->url.host()); return 0; } @@ -91,11 +102,3 @@ return data->match("none"); } -ACLDestinationDomainStrategy * -ACLDestinationDomainStrategy::Instance() -{ - return &Instance_; -} - -ACLDestinationDomainStrategy ACLDestinationDomainStrategy::Instance_; - diff -u -r -N squid-4.0.20/src/acl/DestinationDomain.h squid-4.0.21/src/acl/DestinationDomain.h --- squid-4.0.20/src/acl/DestinationDomain.h 2017-06-02 00:49:17.000000000 +1200 +++ squid-4.0.21/src/acl/DestinationDomain.h 2017-07-02 20:41:18.000000000 +1200 @@ -20,23 +20,13 @@ { public: - virtual int match (ACLData * &, ACLFilledChecklist *, ACLFlags &); - static ACLDestinationDomainStrategy *Instance(); + /* ACLStrategy API */ + virtual int match (ACLData * &, ACLFilledChecklist *); virtual bool requiresRequest() const {return true;} - - /** - * Not implemented to prevent copies of the instance. - \par - * Not private to prevent brain dead g+++ warnings about - * private constructors with no friends - */ - ACLDestinationDomainStrategy(ACLDestinationDomainStrategy const &); + virtual const Acl::Options &options(); private: - static ACLDestinationDomainStrategy Instance_; - ACLDestinationDomainStrategy() {} - - ACLDestinationDomainStrategy&operator=(ACLDestinationDomainStrategy const &); + Acl::BooleanOptionValue lookupBanned; ///< Are DNS lookups allowed? }; /// \ingroup ACLAPI @@ -52,16 +42,5 @@ static void LookupDone(const char *, const Dns::LookupDetails &, void *); }; -/// \ingroup ACLAPI -class ACLDestinationDomain -{ - -private: - static ACL::Prototype LiteralRegistryProtoype; - static ACLStrategised LiteralRegistryEntry_; - static ACL::Prototype RegexRegistryProtoype; - static ACLStrategised RegexRegistryEntry_; -}; - #endif /* SQUID_ACLDESTINATIONDOMAIN_H */ diff -u -r -N squid-4.0.20/src/acl/DestinationIp.cc squid-4.0.21/src/acl/DestinationIp.cc --- squid-4.0.20/src/acl/DestinationIp.cc 2017-06-02 00:49:17.000000000 +1200 +++ squid-4.0.21/src/acl/DestinationIp.cc 2017-07-02 20:41:18.000000000 +1200 @@ -17,14 +17,21 @@ #include "HttpRequest.h" #include "SquidConfig.h" -ACLFlag ACLDestinationIP::SupportedFlags[] = {ACL_F_NO_LOOKUP, ACL_F_END}; - char const * ACLDestinationIP::typeString() const { return "dst"; } +const Acl::Options & +ACLDestinationIP::options() +{ + static const Acl::BooleanOption LookupBan; + static const Acl::Options MyOptions = { { "-n", &LookupBan } }; + LookupBan.linkWith(&lookupBanned); + return MyOptions; +} + int ACLDestinationIP::match(ACLChecklist *cl) { @@ -44,7 +51,7 @@ ACLIP::match(conn->clientConnection->local) : -1; } - if (flags.isSet(ACL_F_NO_LOOKUP)) { + if (lookupBanned) { if (!checklist->request->url.hostIsNumeric()) { debugs(28, 3, "No-lookup DNS ACL '" << AclMatchedName << "' for " << checklist->request->url.host()); return 0; diff -u -r -N squid-4.0.20/src/acl/DestinationIp.h squid-4.0.21/src/acl/DestinationIp.h --- squid-4.0.20/src/acl/DestinationIp.h 2017-06-02 00:49:17.000000000 +1200 +++ squid-4.0.21/src/acl/DestinationIp.h 2017-07-02 20:41:18.000000000 +1200 @@ -30,16 +30,14 @@ MEMPROXY_CLASS(ACLDestinationIP); public: - ACLDestinationIP(): ACLIP(ACLDestinationIP::SupportedFlags) {} virtual char const *typeString() const; + virtual const Acl::Options &options(); virtual int match(ACLChecklist *checklist); virtual ACL *clone()const; - static ACLFlag SupportedFlags[]; private: - static Prototype RegistryProtoype; - static ACLDestinationIP RegistryEntry_; + Acl::BooleanOptionValue lookupBanned; ///< are DNS lookups allowed? }; #endif /* SQUID_ACLDESTINATIONIP_H */ diff -u -r -N squid-4.0.20/src/acl/Eui64.h squid-4.0.21/src/acl/Eui64.h --- squid-4.0.20/src/acl/Eui64.h 2017-06-02 00:49:17.000000000 +1200 +++ squid-4.0.21/src/acl/Eui64.h 2017-07-02 20:41:18.000000000 +1200 @@ -10,7 +10,6 @@ #define SQUID_ACLEUI64_H #include "acl/Acl.h" -#include "acl/Checklist.h" #include @@ -37,8 +36,6 @@ virtual bool empty () const; protected: - static Prototype RegistryProtoype; - static ACLEui64 RegistryEntry_; typedef std::set Eui64Data_t; Eui64Data_t eui64Data; char const *class_; diff -u -r -N squid-4.0.20/src/acl/external/AD_group/Makefile.in squid-4.0.21/src/acl/external/AD_group/Makefile.in --- squid-4.0.20/src/acl/external/AD_group/Makefile.in 2017-06-02 00:54:32.000000000 +1200 +++ squid-4.0.21/src/acl/external/AD_group/Makefile.in 2017-07-02 20:41:24.000000000 +1200 @@ -1,7 +1,7 @@ -# Makefile.in generated by automake 1.15 from Makefile.am. +# Makefile.in generated by automake 1.15.1 from Makefile.am. # @configure_input@ -# Copyright (C) 1994-2014 Free Software Foundation, Inc. +# Copyright (C) 1994-2017 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, diff -u -r -N squid-4.0.20/src/acl/external/delayer/ext_delayer_acl.8 squid-4.0.21/src/acl/external/delayer/ext_delayer_acl.8 --- squid-4.0.20/src/acl/external/delayer/ext_delayer_acl.8 2017-06-02 09:52:23.000000000 +1200 +++ squid-4.0.21/src/acl/external/delayer/ext_delayer_acl.8 2017-07-02 20:57:34.000000000 +1200 @@ -1,4 +1,4 @@ -.\" Automatically generated by Pod::Man 4.08 (Pod::Simple 3.32) +.\" Automatically generated by Pod::Man 4.07 (Pod::Simple 3.32) .\" .\" Standard preamble: .\" ======================================================================== @@ -129,7 +129,7 @@ .\" ======================================================================== .\" .IX Title "EXT_DELAYER_ACL 8" -.TH EXT_DELAYER_ACL 8 "2017-06-01" "perl v5.24.1" "User Contributed Perl Documentation" +.TH EXT_DELAYER_ACL 8 "2017-07-02" "perl v5.24.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 @@ -221,7 +221,7 @@ Report ideas for new improvements to the \fISquid Developers mailing list .SH "SEE ALSO" .IX Header "SEE ALSO" -squid (8), \s-1GPL\s0 (7), +squid (8), \s-1GPL \\fIs0\fR\|(7), .PP The Squid \s-1FAQ\s0 wiki http://wiki.squid\-cache.org/SquidFaq .PP diff -u -r -N squid-4.0.20/src/acl/external/delayer/Makefile.in squid-4.0.21/src/acl/external/delayer/Makefile.in --- squid-4.0.20/src/acl/external/delayer/Makefile.in 2017-06-02 00:54:53.000000000 +1200 +++ squid-4.0.21/src/acl/external/delayer/Makefile.in 2017-07-02 20:41:25.000000000 +1200 @@ -1,7 +1,7 @@ -# Makefile.in generated by automake 1.15 from Makefile.am. +# Makefile.in generated by automake 1.15.1 from Makefile.am. # @configure_input@ -# Copyright (C) 1994-2014 Free Software Foundation, Inc. +# Copyright (C) 1994-2017 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, diff -u -r -N squid-4.0.20/src/acl/external/eDirectory_userip/Makefile.in squid-4.0.21/src/acl/external/eDirectory_userip/Makefile.in --- squid-4.0.20/src/acl/external/eDirectory_userip/Makefile.in 2017-06-02 00:54:57.000000000 +1200 +++ squid-4.0.21/src/acl/external/eDirectory_userip/Makefile.in 2017-07-02 20:41:25.000000000 +1200 @@ -1,7 +1,7 @@ -# Makefile.in generated by automake 1.15 from Makefile.am. +# Makefile.in generated by automake 1.15.1 from Makefile.am. # @configure_input@ -# Copyright (C) 1994-2014 Free Software Foundation, Inc. +# Copyright (C) 1994-2017 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, diff -u -r -N squid-4.0.20/src/acl/external/file_userip/example.conf squid-4.0.21/src/acl/external/file_userip/example.conf --- squid-4.0.20/src/acl/external/file_userip/example.conf 2017-06-02 00:49:17.000000000 +1200 +++ squid-4.0.21/src/acl/external/file_userip/example.conf 2017-07-02 20:41:18.000000000 +1200 @@ -43,3 +43,8 @@ # # Users of the "tol" group may authenticate from their VLAN # 10.0.0.0/255.255.0.0 @tol +# +# User "diniz" may authenticate from the LAN, but deny all others +# 192.168.1.0/255.255.255.0 diniz +# 0.0.0.0/0.0.0.0 NONE + diff -u -r -N squid-4.0.20/src/acl/external/file_userip/example-deny_all_but.conf squid-4.0.21/src/acl/external/file_userip/example-deny_all_but.conf --- squid-4.0.20/src/acl/external/file_userip/example-deny_all_but.conf 2017-06-02 00:49:17.000000000 +1200 +++ squid-4.0.21/src/acl/external/file_userip/example-deny_all_but.conf 1970-01-01 12:00:00.000000000 +1200 @@ -1,2 +0,0 @@ -192.168.1.0/255.255.255.0 diniz -0.0.0.0/0.0.0.0 NONE diff -u -r -N squid-4.0.20/src/acl/external/file_userip/Makefile.am squid-4.0.21/src/acl/external/file_userip/Makefile.am --- squid-4.0.20/src/acl/external/file_userip/Makefile.am 2017-06-02 00:49:17.000000000 +1200 +++ squid-4.0.21/src/acl/external/file_userip/Makefile.am 2017-07-02 20:41:18.000000000 +1200 @@ -19,6 +19,5 @@ EXTRA_DIST = \ example.conf \ - example-deny_all_but.conf \ ext_file_userip_acl.8 \ required.m4 diff -u -r -N squid-4.0.20/src/acl/external/file_userip/Makefile.in squid-4.0.21/src/acl/external/file_userip/Makefile.in --- squid-4.0.20/src/acl/external/file_userip/Makefile.in 2017-06-02 00:55:01.000000000 +1200 +++ squid-4.0.21/src/acl/external/file_userip/Makefile.in 2017-07-02 20:41:25.000000000 +1200 @@ -1,7 +1,7 @@ -# Makefile.in generated by automake 1.15 from Makefile.am. +# Makefile.in generated by automake 1.15.1 from Makefile.am. # @configure_input@ -# Copyright (C) 1994-2014 Free Software Foundation, Inc. +# Copyright (C) 1994-2017 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -712,7 +712,6 @@ EXTRA_DIST = \ example.conf \ - example-deny_all_but.conf \ ext_file_userip_acl.8 \ required.m4 diff -u -r -N squid-4.0.20/src/acl/external/kerberos_ldap_group/Makefile.in squid-4.0.21/src/acl/external/kerberos_ldap_group/Makefile.in --- squid-4.0.20/src/acl/external/kerberos_ldap_group/Makefile.in 2017-06-02 00:55:06.000000000 +1200 +++ squid-4.0.21/src/acl/external/kerberos_ldap_group/Makefile.in 2017-07-02 20:41:25.000000000 +1200 @@ -1,7 +1,7 @@ -# Makefile.in generated by automake 1.15 from Makefile.am. +# Makefile.in generated by automake 1.15.1 from Makefile.am. # @configure_input@ -# Copyright (C) 1994-2014 Free Software Foundation, Inc. +# Copyright (C) 1994-2017 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, diff -u -r -N squid-4.0.20/src/acl/external/LDAP_group/Makefile.in squid-4.0.21/src/acl/external/LDAP_group/Makefile.in --- squid-4.0.20/src/acl/external/LDAP_group/Makefile.in 2017-06-02 00:54:36.000000000 +1200 +++ squid-4.0.21/src/acl/external/LDAP_group/Makefile.in 2017-07-02 20:41:24.000000000 +1200 @@ -1,7 +1,7 @@ -# Makefile.in generated by automake 1.15 from Makefile.am. +# Makefile.in generated by automake 1.15.1 from Makefile.am. # @configure_input@ -# Copyright (C) 1994-2014 Free Software Foundation, Inc. +# Copyright (C) 1994-2017 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, diff -u -r -N squid-4.0.20/src/acl/external/LM_group/Makefile.in squid-4.0.21/src/acl/external/LM_group/Makefile.in --- squid-4.0.20/src/acl/external/LM_group/Makefile.in 2017-06-02 00:54:43.000000000 +1200 +++ squid-4.0.21/src/acl/external/LM_group/Makefile.in 2017-07-02 20:41:24.000000000 +1200 @@ -1,7 +1,7 @@ -# Makefile.in generated by automake 1.15 from Makefile.am. +# Makefile.in generated by automake 1.15.1 from Makefile.am. # @configure_input@ -# Copyright (C) 1994-2014 Free Software Foundation, Inc. +# Copyright (C) 1994-2017 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, diff -u -r -N squid-4.0.20/src/acl/external/Makefile.in squid-4.0.21/src/acl/external/Makefile.in --- squid-4.0.20/src/acl/external/Makefile.in 2017-06-02 00:54:46.000000000 +1200 +++ squid-4.0.21/src/acl/external/Makefile.in 2017-07-02 20:41:24.000000000 +1200 @@ -1,7 +1,7 @@ -# Makefile.in generated by automake 1.15 from Makefile.am. +# Makefile.in generated by automake 1.15.1 from Makefile.am. # @configure_input@ -# Copyright (C) 1994-2014 Free Software Foundation, Inc. +# Copyright (C) 1994-2017 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, diff -u -r -N squid-4.0.20/src/acl/external/session/Makefile.in squid-4.0.21/src/acl/external/session/Makefile.in --- squid-4.0.20/src/acl/external/session/Makefile.in 2017-06-02 00:55:13.000000000 +1200 +++ squid-4.0.21/src/acl/external/session/Makefile.in 2017-07-02 20:41:25.000000000 +1200 @@ -1,7 +1,7 @@ -# Makefile.in generated by automake 1.15 from Makefile.am. +# Makefile.in generated by automake 1.15.1 from Makefile.am. # @configure_input@ -# Copyright (C) 1994-2014 Free Software Foundation, Inc. +# Copyright (C) 1994-2017 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, diff -u -r -N squid-4.0.20/src/acl/external/SQL_session/ext_sql_session_acl.8 squid-4.0.21/src/acl/external/SQL_session/ext_sql_session_acl.8 --- squid-4.0.20/src/acl/external/SQL_session/ext_sql_session_acl.8 2017-06-02 09:52:58.000000000 +1200 +++ squid-4.0.21/src/acl/external/SQL_session/ext_sql_session_acl.8 2017-07-02 20:57:34.000000000 +1200 @@ -1,4 +1,4 @@ -.\" Automatically generated by Pod::Man 4.08 (Pod::Simple 3.32) +.\" Automatically generated by Pod::Man 4.07 (Pod::Simple 3.32) .\" .\" Standard preamble: .\" ======================================================================== @@ -129,7 +129,7 @@ .\" ======================================================================== .\" .IX Title "EXT_SQL_SESSION_ACL 8" -.TH EXT_SQL_SESSION_ACL 8 "2017-06-01" "perl v5.24.1" "User Contributed Perl Documentation" +.TH EXT_SQL_SESSION_ACL 8 "2017-07-02" "perl v5.24.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 @@ -150,7 +150,7 @@ Taking an identity token to be validated (as determined by the external_acl_type format) it returns a username or tag associated with the identity token passed in. .PP -Common forms of identifiers are \s-1IP\s0 address, \s-1EUI\s0 (\s-1MAC\s0) address, passwords, or \s-1UUID\s0 tokens. +Common forms of identifiers are \s-1IP\s0 address, \s-1EUI \s0(\s-1MAC\s0) address, passwords, or \s-1UUID\s0 tokens. .PP This program uses Squid concurrency support. .SH "OPTIONS" @@ -221,7 +221,7 @@ Report ideas for new improvements to the \fISquid Developers mailing list .SH "SEE ALSO" .IX Header "SEE ALSO" -squid (8), \s-1GPL\s0 (7), +squid (8), \s-1GPL \\fIs0\fR\|(7), .PP The Squid \s-1FAQ\s0 wiki http://wiki.squid\-cache.org/SquidFaq .PP diff -u -r -N squid-4.0.20/src/acl/external/SQL_session/Makefile.in squid-4.0.21/src/acl/external/SQL_session/Makefile.in --- squid-4.0.20/src/acl/external/SQL_session/Makefile.in 2017-06-02 00:54:49.000000000 +1200 +++ squid-4.0.21/src/acl/external/SQL_session/Makefile.in 2017-07-02 20:41:25.000000000 +1200 @@ -1,7 +1,7 @@ -# Makefile.in generated by automake 1.15 from Makefile.am. +# Makefile.in generated by automake 1.15.1 from Makefile.am. # @configure_input@ -# Copyright (C) 1994-2014 Free Software Foundation, Inc. +# Copyright (C) 1994-2017 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, diff -u -r -N squid-4.0.20/src/acl/external/time_quota/Makefile.in squid-4.0.21/src/acl/external/time_quota/Makefile.in --- squid-4.0.20/src/acl/external/time_quota/Makefile.in 2017-06-02 00:55:21.000000000 +1200 +++ squid-4.0.21/src/acl/external/time_quota/Makefile.in 2017-07-02 20:41:25.000000000 +1200 @@ -1,7 +1,7 @@ -# Makefile.in generated by automake 1.15 from Makefile.am. +# Makefile.in generated by automake 1.15.1 from Makefile.am. # @configure_input@ -# Copyright (C) 1994-2014 Free Software Foundation, Inc. +# Copyright (C) 1994-2017 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, diff -u -r -N squid-4.0.20/src/acl/external/unix_group/Makefile.in squid-4.0.21/src/acl/external/unix_group/Makefile.in --- squid-4.0.20/src/acl/external/unix_group/Makefile.in 2017-06-02 00:55:24.000000000 +1200 +++ squid-4.0.21/src/acl/external/unix_group/Makefile.in 2017-07-02 20:41:25.000000000 +1200 @@ -1,7 +1,7 @@ -# Makefile.in generated by automake 1.15 from Makefile.am. +# Makefile.in generated by automake 1.15.1 from Makefile.am. # @configure_input@ -# Copyright (C) 1994-2014 Free Software Foundation, Inc. +# Copyright (C) 1994-2017 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, diff -u -r -N squid-4.0.20/src/acl/external/wbinfo_group/ext_wbinfo_group_acl.8 squid-4.0.21/src/acl/external/wbinfo_group/ext_wbinfo_group_acl.8 --- squid-4.0.20/src/acl/external/wbinfo_group/ext_wbinfo_group_acl.8 2017-06-02 09:53:11.000000000 +1200 +++ squid-4.0.21/src/acl/external/wbinfo_group/ext_wbinfo_group_acl.8 2017-07-02 20:57:34.000000000 +1200 @@ -1,4 +1,4 @@ -.\" Automatically generated by Pod::Man 4.08 (Pod::Simple 3.32) +.\" Automatically generated by Pod::Man 4.07 (Pod::Simple 3.32) .\" .\" Standard preamble: .\" ======================================================================== @@ -129,7 +129,7 @@ .\" ======================================================================== .\" .IX Title "EXT_WBINFO_GROUP_ACL 8" -.TH EXT_WBINFO_GROUP_ACL 8 "2017-06-01" "perl v5.24.1" "User Contributed Perl Documentation" +.TH EXT_WBINFO_GROUP_ACL 8 "2017-07-02" "perl v5.24.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-4.0.20/src/acl/external/wbinfo_group/Makefile.in squid-4.0.21/src/acl/external/wbinfo_group/Makefile.in --- squid-4.0.20/src/acl/external/wbinfo_group/Makefile.in 2017-06-02 00:55:29.000000000 +1200 +++ squid-4.0.21/src/acl/external/wbinfo_group/Makefile.in 2017-07-02 20:41:25.000000000 +1200 @@ -1,7 +1,7 @@ -# Makefile.in generated by automake 1.15 from Makefile.am. +# Makefile.in generated by automake 1.15.1 from Makefile.am. # @configure_input@ -# Copyright (C) 1994-2014 Free Software Foundation, Inc. +# Copyright (C) 1994-2017 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, diff -u -r -N squid-4.0.20/src/acl/ExtUser.cc squid-4.0.21/src/acl/ExtUser.cc --- squid-4.0.20/src/acl/ExtUser.cc 2017-06-02 00:49:17.000000000 +1200 +++ squid-4.0.21/src/acl/ExtUser.cc 2017-07-02 20:41:18.000000000 +1200 @@ -44,6 +44,12 @@ } void +ACLExtUser::parseFlags() +{ + ParseFlags(Acl::NoOptions(), data->supportedFlags()); +} + +void ACLExtUser::parse() { data->parse(); diff -u -r -N squid-4.0.20/src/acl/ExtUser.h squid-4.0.21/src/acl/ExtUser.h --- squid-4.0.20/src/acl/ExtUser.h 2017-06-02 00:49:17.000000000 +1200 +++ squid-4.0.21/src/acl/ExtUser.h 2017-07-02 20:41:18.000000000 +1200 @@ -25,19 +25,16 @@ ACLExtUser & operator= (ACLExtUser const &rhs); ~ACLExtUser(); + /* ACL API */ virtual char const *typeString() const; virtual void parse(); - + virtual void parseFlags(); virtual int match(ACLChecklist *checklist); virtual SBufList dump() const; virtual bool empty () const; virtual ACL *clone()const; private: - static Prototype UserRegistryProtoype; - static ACLExtUser UserRegistryEntry_; - static Prototype RegexRegistryProtoype; - static ACLExtUser RegexRegistryEntry_; ACLData *data; char const *type_; }; diff -u -r -N squid-4.0.20/src/acl/forward.h squid-4.0.21/src/acl/forward.h --- squid-4.0.20/src/acl/forward.h 2017-06-02 00:49:17.000000000 +1200 +++ squid-4.0.21/src/acl/forward.h 2017-07-02 20:41:18.000000000 +1200 @@ -29,6 +29,9 @@ class OrNode; class Tree; +/// prepares to parse ACLs configuration +void Init(void); + } // namespace Acl class allow_t; diff -u -r -N squid-4.0.20/src/acl/HasComponent.cc squid-4.0.21/src/acl/HasComponent.cc --- squid-4.0.20/src/acl/HasComponent.cc 2017-06-02 00:49:17.000000000 +1200 +++ squid-4.0.21/src/acl/HasComponent.cc 2017-07-02 20:41:18.000000000 +1200 @@ -11,18 +11,10 @@ #include "acl/HasComponentData.h" int -ACLHasComponentStrategy::match(ACLData * &data, ACLFilledChecklist *checklist, ACLFlags &flags) +ACLHasComponentStrategy::match(ACLData * &data, ACLFilledChecklist *checklist) { ACLHasComponentData *cdata = dynamic_cast(data); assert(cdata); return cdata->match(checklist); } -ACLHasComponentStrategy * -ACLHasComponentStrategy::Instance() -{ - return &Instance_; -} - -ACLHasComponentStrategy ACLHasComponentStrategy::Instance_; - diff -u -r -N squid-4.0.20/src/acl/HasComponent.h squid-4.0.21/src/acl/HasComponent.h --- squid-4.0.20/src/acl/HasComponent.h 2017-06-02 00:49:17.000000000 +1200 +++ squid-4.0.21/src/acl/HasComponent.h 2017-07-02 20:41:18.000000000 +1200 @@ -16,22 +16,7 @@ class ACLHasComponentStrategy : public ACLStrategy { public: - static ACLHasComponentStrategy *Instance(); - ACLHasComponentStrategy(ACLHasComponentStrategy const &) = delete; - ACLHasComponentStrategy& operator=(ACLHasComponentStrategy const &) = delete; - virtual int match(ACLData * &, ACLFilledChecklist *, ACLFlags &); - -private: - static ACLHasComponentStrategy Instance_; - ACLHasComponentStrategy() { } -}; - -/// \ingroup ACLAPI -class ACLHasComponent -{ -private: - static ACL::Prototype RegistryProtoype; - static ACLStrategised RegistryEntry_; + virtual int match(ACLData * &, ACLFilledChecklist *); }; #endif diff -u -r -N squid-4.0.20/src/acl/HierCode.cc squid-4.0.21/src/acl/HierCode.cc --- squid-4.0.20/src/acl/HierCode.cc 2017-06-02 00:49:17.000000000 +1200 +++ squid-4.0.21/src/acl/HierCode.cc 2017-07-02 20:41:18.000000000 +1200 @@ -10,6 +10,7 @@ #include "acl/Checklist.h" #include "acl/HierCode.h" #include "acl/HierCodeData.h" +#include "acl/Strategised.h" #include "HttpRequest.h" /* explicit template instantiation required for some systems */ @@ -17,16 +18,8 @@ template class ACLStrategised; int -ACLHierCodeStrategy::match (ACLData * &data, ACLFilledChecklist *checklist, ACLFlags &) +ACLHierCodeStrategy::match (ACLData * &data, ACLFilledChecklist *checklist) { return data->match (checklist->request->hier.code); } -ACLHierCodeStrategy * -ACLHierCodeStrategy::Instance() -{ - return &Instance_; -} - -ACLHierCodeStrategy ACLHierCodeStrategy::Instance_; - diff -u -r -N squid-4.0.20/src/acl/HierCode.h squid-4.0.21/src/acl/HierCode.h --- squid-4.0.20/src/acl/HierCode.h 2017-06-02 00:49:17.000000000 +1200 +++ squid-4.0.21/src/acl/HierCode.h 2017-07-02 20:41:18.000000000 +1200 @@ -9,7 +9,6 @@ #ifndef SQUID_ACLHIERCODE_H #define SQUID_ACLHIERCODE_H -#include "acl/Strategised.h" #include "acl/Strategy.h" #include "hier_code.h" @@ -18,33 +17,8 @@ { public: - virtual int match (ACLData * &, ACLFilledChecklist *, ACLFlags &); + virtual int match (ACLData * &, ACLFilledChecklist *); virtual bool requiresRequest() const {return true;} - - static ACLHierCodeStrategy *Instance(); - - /** - * Not implemented to prevent copies of the instance. - \par - * Not private to prevent brain dead g+++ warnings about - * private constructors with no friends - */ - ACLHierCodeStrategy(ACLHierCodeStrategy const &); - -private: - static ACLHierCodeStrategy Instance_; - ACLHierCodeStrategy() {} - - ACLHierCodeStrategy &operator=(ACLHierCodeStrategy const &); -}; - -/// \ingroup ACLAPI -class ACLHierCode -{ - -private: - static ACL::Prototype RegistryProtoype; - static ACLStrategised RegistryEntry_; }; #endif /* SQUID_ACLHIERCODE_H */ diff -u -r -N squid-4.0.20/src/acl/HttpRepHeader.cc squid-4.0.21/src/acl/HttpRepHeader.cc --- squid-4.0.20/src/acl/HttpRepHeader.cc 2017-06-02 00:49:17.000000000 +1200 +++ squid-4.0.21/src/acl/HttpRepHeader.cc 2017-07-02 20:41:18.000000000 +1200 @@ -7,22 +7,14 @@ */ #include "squid.h" -#include "acl/Checklist.h" +#include "acl/FilledChecklist.h" #include "acl/HttpHeaderData.h" #include "acl/HttpRepHeader.h" #include "HttpReply.h" int -ACLHTTPRepHeaderStrategy::match (ACLData * &data, ACLFilledChecklist *checklist, ACLFlags &) +ACLHTTPRepHeaderStrategy::match (ACLData * &data, ACLFilledChecklist *checklist) { return data->match (&checklist->reply->header); } -ACLHTTPRepHeaderStrategy * -ACLHTTPRepHeaderStrategy::Instance() -{ - return &Instance_; -} - -ACLHTTPRepHeaderStrategy ACLHTTPRepHeaderStrategy::Instance_; - diff -u -r -N squid-4.0.20/src/acl/HttpRepHeader.h squid-4.0.21/src/acl/HttpRepHeader.h --- squid-4.0.20/src/acl/HttpRepHeader.h 2017-06-02 00:49:17.000000000 +1200 +++ squid-4.0.21/src/acl/HttpRepHeader.h 2017-07-02 20:41:18.000000000 +1200 @@ -18,32 +18,8 @@ { public: - virtual int match (ACLData * &, ACLFilledChecklist *, ACLFlags &); + virtual int match (ACLData * &, ACLFilledChecklist *); virtual bool requiresReply() const { return true; } - - static ACLHTTPRepHeaderStrategy *Instance(); - /** - * Not implemented to prevent copies of the instance. - \par - * Not private to prevent brain dead g+++ warnings about - * private constructors with no friends - */ - ACLHTTPRepHeaderStrategy(ACLHTTPRepHeaderStrategy const &); - -private: - static ACLHTTPRepHeaderStrategy Instance_; - ACLHTTPRepHeaderStrategy() { } - - ACLHTTPRepHeaderStrategy&operator = (ACLHTTPRepHeaderStrategy const &); -}; - -/// \ingroup ACLAPI -class ACLHTTPRepHeader -{ - -private: - static ACL::Prototype RegistryProtoype; - static ACLStrategised RegistryEntry_; }; #endif /* SQUID_ACLHTTPREPHEADER_H */ diff -u -r -N squid-4.0.20/src/acl/HttpReqHeader.cc squid-4.0.21/src/acl/HttpReqHeader.cc --- squid-4.0.20/src/acl/HttpReqHeader.cc 2017-06-02 00:49:17.000000000 +1200 +++ squid-4.0.21/src/acl/HttpReqHeader.cc 2017-07-02 20:41:18.000000000 +1200 @@ -7,22 +7,14 @@ */ #include "squid.h" -#include "acl/Checklist.h" +#include "acl/FilledChecklist.h" #include "acl/HttpHeaderData.h" #include "acl/HttpReqHeader.h" #include "HttpRequest.h" int -ACLHTTPReqHeaderStrategy::match (ACLData * &data, ACLFilledChecklist *checklist, ACLFlags &) +ACLHTTPReqHeaderStrategy::match (ACLData * &data, ACLFilledChecklist *checklist) { return data->match (&checklist->request->header); } -ACLHTTPReqHeaderStrategy * -ACLHTTPReqHeaderStrategy::Instance() -{ - return &Instance_; -} - -ACLHTTPReqHeaderStrategy ACLHTTPReqHeaderStrategy::Instance_; - diff -u -r -N squid-4.0.20/src/acl/HttpReqHeader.h squid-4.0.21/src/acl/HttpReqHeader.h --- squid-4.0.20/src/acl/HttpReqHeader.h 2017-06-02 00:49:17.000000000 +1200 +++ squid-4.0.21/src/acl/HttpReqHeader.h 2017-07-02 20:41:18.000000000 +1200 @@ -9,7 +9,6 @@ #ifndef SQUID_ACLHTTPREQHEADER_H #define SQUID_ACLHTTPREQHEADER_H -#include "acl/Strategised.h" #include "acl/Strategy.h" #include "HttpHeader.h" @@ -18,29 +17,8 @@ { public: - virtual int match (ACLData * &, ACLFilledChecklist *, ACLFlags &); + virtual int match (ACLData * &, ACLFilledChecklist *); virtual bool requiresRequest() const { return true; } - - static ACLHTTPReqHeaderStrategy *Instance(); - /* Not implemented to prevent copies of the instance. */ - /* Not private to prevent brain dead g+++ warnings about - * private constructors with no friends */ - ACLHTTPReqHeaderStrategy(ACLHTTPReqHeaderStrategy const &); - -private: - static ACLHTTPReqHeaderStrategy Instance_; - ACLHTTPReqHeaderStrategy() { } - - ACLHTTPReqHeaderStrategy&operator = (ACLHTTPReqHeaderStrategy const &); -}; - -/// \ingroup ACLAPI -class ACLHTTPReqHeader -{ - -private: - static ACL::Prototype RegistryProtoype; - static ACLStrategised RegistryEntry_; }; #endif /* SQUID_ACLHTTPREQHEADER_H */ diff -u -r -N squid-4.0.20/src/acl/HttpStatus.h squid-4.0.21/src/acl/HttpStatus.h --- squid-4.0.20/src/acl/HttpStatus.h 2017-06-02 00:49:17.000000000 +1200 +++ squid-4.0.21/src/acl/HttpStatus.h 2017-07-02 20:41:18.000000000 +1200 @@ -43,8 +43,6 @@ virtual bool requiresReply() const { return true; } protected: - static Prototype RegistryProtoype; - static ACLHTTPStatus RegistryEntry_; Splay *data; char const *class_; }; diff -u -r -N squid-4.0.20/src/acl/Ip.cc squid-4.0.21/src/acl/Ip.cc --- squid-4.0.20/src/acl/Ip.cc 2017-06-02 00:49:17.000000000 +1200 +++ squid-4.0.21/src/acl/Ip.cc 2017-07-02 20:41:18.000000000 +1200 @@ -477,8 +477,6 @@ if (data == NULL) data = new IPSplay(); - flags.parseFlags(); - while (char *t = ConfigParser::strtokFile()) { acl_ip_data *q = acl_ip_data::FactoryParse(t); diff -u -r -N squid-4.0.20/src/acl/Ip.h squid-4.0.21/src/acl/Ip.h --- squid-4.0.20/src/acl/Ip.h 2017-06-02 00:49:17.000000000 +1200 +++ squid-4.0.21/src/acl/Ip.h 2017-07-02 20:41:18.000000000 +1200 @@ -48,8 +48,6 @@ void operator delete(void *); ACLIP() : data(NULL) {} - explicit ACLIP(const ACLFlag flgs[]) : ACL(flgs), data(NULL) {} - ~ACLIP(); typedef Splay IPSplay; diff -u -r -N squid-4.0.20/src/acl/LocalIp.h squid-4.0.21/src/acl/LocalIp.h --- squid-4.0.20/src/acl/LocalIp.h 2017-06-02 00:49:17.000000000 +1200 +++ squid-4.0.21/src/acl/LocalIp.h 2017-07-02 20:41:18.000000000 +1200 @@ -17,15 +17,9 @@ MEMPROXY_CLASS(ACLLocalIP); public: - static ACLLocalIP const &RegistryEntry(); - virtual char const *typeString() const; virtual int match(ACLChecklist *checklist); virtual ACL *clone()const; - -private: - static Prototype RegistryProtoype; - static ACLLocalIP RegistryEntry_; }; #endif /* SQUID_ACLLOCALIP_H */ diff -u -r -N squid-4.0.20/src/acl/LocalPort.cc squid-4.0.21/src/acl/LocalPort.cc --- squid-4.0.20/src/acl/LocalPort.cc 2017-06-02 00:49:17.000000000 +1200 +++ squid-4.0.21/src/acl/LocalPort.cc 2017-07-02 20:41:18.000000000 +1200 @@ -7,21 +7,12 @@ */ #include "squid.h" -#include "acl/Checklist.h" -#include "acl/IntRange.h" +#include "acl/FilledChecklist.h" #include "acl/LocalPort.h" int -ACLLocalPortStrategy::match (ACLData * &data, ACLFilledChecklist *checklist, ACLFlags &) +ACLLocalPortStrategy::match (ACLData * &data, ACLFilledChecklist *checklist) { return data->match (checklist->my_addr.port()); } -ACLLocalPortStrategy * -ACLLocalPortStrategy::Instance() -{ - return &Instance_; -} - -ACLLocalPortStrategy ACLLocalPortStrategy::Instance_; - diff -u -r -N squid-4.0.20/src/acl/LocalPort.h squid-4.0.21/src/acl/LocalPort.h --- squid-4.0.20/src/acl/LocalPort.h 2017-06-02 00:49:17.000000000 +1200 +++ squid-4.0.21/src/acl/LocalPort.h 2017-07-02 20:41:18.000000000 +1200 @@ -9,7 +9,6 @@ #ifndef SQUID_ACLLOCALPORT_H #define SQUID_ACLLOCALPORT_H -#include "acl/Strategised.h" #include "acl/Strategy.h" /// \ingroup ACLAPI @@ -17,30 +16,7 @@ { public: - virtual int match (ACLData * &, ACLFilledChecklist *, ACLFlags &); - static ACLLocalPortStrategy *Instance(); - /** - * Not implemented to prevent copies of the instance. - \par - * Not private to prevent brain dead g+++ warnings about - * private constructors with no friends - */ - ACLLocalPortStrategy(ACLLocalPortStrategy const &); - -private: - static ACLLocalPortStrategy Instance_; - ACLLocalPortStrategy() {} - - ACLLocalPortStrategy&operator=(ACLLocalPortStrategy const &); -}; - -/// \ingroup ACLAPI -class ACLLocalPort -{ - -private: - static ACL::Prototype RegistryProtoype; - static ACLStrategised RegistryEntry_; + virtual int match (ACLData * &, ACLFilledChecklist *) override; }; #endif /* SQUID_ACLLOCALPORT_H */ diff -u -r -N squid-4.0.20/src/acl/Makefile.am squid-4.0.21/src/acl/Makefile.am --- squid-4.0.20/src/acl/Makefile.am 2017-06-02 00:49:17.000000000 +1200 +++ squid-4.0.21/src/acl/Makefile.am 2017-07-02 20:41:18.000000000 +1200 @@ -23,12 +23,15 @@ forward.h \ InnerNode.cc \ InnerNode.h \ + Options.h \ + Options.cc \ Tree.cc \ Tree.h ## Data-dependent Squid/transaction state used by specific ACLs. ## Does not refer to specific ACLs to avoid circular dependencies. libstate_la_SOURCES = \ + CharacterSetOption.h \ Data.h \ Strategy.h \ Strategised.cc \ @@ -56,8 +59,6 @@ AnyOf.h \ Asn.cc \ Asn.h \ - Browser.cc \ - Browser.h \ ConnectionsEncrypted.cc \ ConnectionsEncrypted.h \ DestinationAsn.h \ @@ -111,13 +112,9 @@ Protocol.h \ Random.cc \ Random.h \ - Referer.cc \ - Referer.h \ ReplyHeaderStrategy.h \ - ReplyMimeType.cc \ ReplyMimeType.h \ RequestHeaderStrategy.h \ - RequestMimeType.cc \ RequestMimeType.h \ SourceAsn.h \ SourceDomain.cc \ @@ -130,6 +127,8 @@ SquidErrorData.h \ Tag.cc \ Tag.h \ + TransactionInitiator.cc \ + TransactionInitiator.h \ Url.cc \ Url.h \ UrlLogin.cc \ diff -u -r -N squid-4.0.20/src/acl/Makefile.in squid-4.0.21/src/acl/Makefile.in --- squid-4.0.20/src/acl/Makefile.in 2017-06-02 00:54:27.000000000 +1200 +++ squid-4.0.21/src/acl/Makefile.in 2017-07-02 20:41:24.000000000 +1200 @@ -1,7 +1,7 @@ -# Makefile.in generated by automake 1.15 from Makefile.am. +# Makefile.in generated by automake 1.15.1 from Makefile.am. # @configure_input@ -# Copyright (C) 1994-2014 Free Software Foundation, Inc. +# Copyright (C) 1994-2017 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -169,35 +169,34 @@ am__libacls_la_SOURCES_DIST = IntRange.cc IntRange.h RegexData.cc \ RegexData.h StringData.cc StringData.h Time.cc Time.h \ TimeData.cc TimeData.h AllOf.cc AllOf.h AnyOf.cc AnyOf.h \ - Asn.cc Asn.h Browser.cc Browser.h ConnectionsEncrypted.cc \ - ConnectionsEncrypted.h DestinationAsn.h DestinationDomain.cc \ - DestinationDomain.h DestinationIp.cc DestinationIp.h \ - DomainData.cc DomainData.h ExtUser.cc ExtUser.h \ - HasComponent.cc HasComponent.h HasComponentData.cc \ - HasComponentData.h HierCodeData.cc HierCodeData.h HierCode.cc \ - HierCode.h HttpHeaderData.cc HttpHeaderData.h HttpRepHeader.cc \ - HttpRepHeader.h HttpReqHeader.cc HttpReqHeader.h HttpStatus.cc \ - HttpStatus.h Ip.cc Ip.h LocalIp.cc LocalIp.h LocalPort.cc \ - LocalPort.h MaxConnection.cc MaxConnection.h Method.cc \ - MethodData.cc MethodData.h Method.h MyPortName.cc MyPortName.h \ - Note.h Note.cc NoteData.h NoteData.cc PeerName.cc PeerName.h \ + Asn.cc Asn.h ConnectionsEncrypted.cc ConnectionsEncrypted.h \ + DestinationAsn.h DestinationDomain.cc DestinationDomain.h \ + DestinationIp.cc DestinationIp.h DomainData.cc DomainData.h \ + ExtUser.cc ExtUser.h HasComponent.cc HasComponent.h \ + HasComponentData.cc HasComponentData.h HierCodeData.cc \ + HierCodeData.h HierCode.cc HierCode.h HttpHeaderData.cc \ + HttpHeaderData.h HttpRepHeader.cc HttpRepHeader.h \ + HttpReqHeader.cc HttpReqHeader.h HttpStatus.cc HttpStatus.h \ + Ip.cc Ip.h LocalIp.cc LocalIp.h LocalPort.cc LocalPort.h \ + MaxConnection.cc MaxConnection.h Method.cc MethodData.cc \ + MethodData.h Method.h MyPortName.cc MyPortName.h Note.h \ + Note.cc NoteData.h NoteData.cc PeerName.cc PeerName.h \ Protocol.cc ProtocolData.cc ProtocolData.h Protocol.h \ - Random.cc Random.h Referer.cc Referer.h ReplyHeaderStrategy.h \ - ReplyMimeType.cc ReplyMimeType.h RequestHeaderStrategy.h \ - RequestMimeType.cc RequestMimeType.h SourceAsn.h \ + Random.cc Random.h ReplyHeaderStrategy.h ReplyMimeType.h \ + RequestHeaderStrategy.h RequestMimeType.h SourceAsn.h \ SourceDomain.cc SourceDomain.h SourceIp.cc SourceIp.h \ SquidError.h SquidError.cc SquidErrorData.cc SquidErrorData.h \ - Tag.cc Tag.h Url.cc Url.h UrlLogin.cc UrlLogin.h UrlPath.cc \ - UrlPath.h UrlPort.cc UrlPort.h UserData.cc UserData.h \ - AclNameList.h AclDenyInfoList.h Gadgets.cc Gadgets.h \ - AclSizeLimit.cc AclSizeLimit.h AtStep.cc AtStep.h \ - AtStepData.cc AtStepData.h CertificateData.cc \ - CertificateData.h Certificate.cc Certificate.h \ - ServerCertificate.cc ServerCertificate.h ServerName.cc \ - ServerName.h SslError.cc SslError.h SslErrorData.cc \ - SslErrorData.h AdaptationService.h AdaptationService.cc \ - AdaptationServiceData.h AdaptationServiceData.cc Arp.cc Arp.h \ - Eui64.cc Eui64.h + Tag.cc Tag.h TransactionInitiator.cc TransactionInitiator.h \ + Url.cc Url.h UrlLogin.cc UrlLogin.h UrlPath.cc UrlPath.h \ + UrlPort.cc UrlPort.h UserData.cc UserData.h AclNameList.h \ + AclDenyInfoList.h Gadgets.cc Gadgets.h AclSizeLimit.cc \ + AclSizeLimit.h AtStep.cc AtStep.h AtStepData.cc AtStepData.h \ + CertificateData.cc CertificateData.h Certificate.cc \ + Certificate.h ServerCertificate.cc ServerCertificate.h \ + ServerName.cc ServerName.h SslError.cc SslError.h \ + SslErrorData.cc SslErrorData.h AdaptationService.h \ + AdaptationService.cc AdaptationServiceData.h \ + AdaptationServiceData.cc Arp.cc Arp.h Eui64.cc Eui64.h am__objects_1 = AtStep.lo AtStepData.lo CertificateData.lo \ Certificate.lo ServerCertificate.lo ServerName.lo SslError.lo \ SslErrorData.lo @@ -207,18 +206,17 @@ am__objects_5 = Arp.lo Eui64.lo @ENABLE_EUI_TRUE@am__objects_6 = $(am__objects_5) am_libacls_la_OBJECTS = IntRange.lo RegexData.lo StringData.lo Time.lo \ - TimeData.lo AllOf.lo AnyOf.lo Asn.lo Browser.lo \ - ConnectionsEncrypted.lo DestinationDomain.lo DestinationIp.lo \ - DomainData.lo ExtUser.lo HasComponent.lo HasComponentData.lo \ - HierCodeData.lo HierCode.lo HttpHeaderData.lo HttpRepHeader.lo \ + TimeData.lo AllOf.lo AnyOf.lo Asn.lo ConnectionsEncrypted.lo \ + DestinationDomain.lo DestinationIp.lo DomainData.lo ExtUser.lo \ + HasComponent.lo HasComponentData.lo HierCodeData.lo \ + HierCode.lo HttpHeaderData.lo HttpRepHeader.lo \ HttpReqHeader.lo HttpStatus.lo Ip.lo LocalIp.lo LocalPort.lo \ MaxConnection.lo Method.lo MethodData.lo MyPortName.lo Note.lo \ NoteData.lo PeerName.lo Protocol.lo ProtocolData.lo Random.lo \ - Referer.lo ReplyMimeType.lo RequestMimeType.lo SourceDomain.lo \ - SourceIp.lo SquidError.lo SquidErrorData.lo Tag.lo Url.lo \ - UrlLogin.lo UrlPath.lo UrlPort.lo UserData.lo Gadgets.lo \ - AclSizeLimit.lo $(am__objects_2) $(am__objects_4) \ - $(am__objects_6) + SourceDomain.lo SourceIp.lo SquidError.lo SquidErrorData.lo \ + Tag.lo TransactionInitiator.lo Url.lo UrlLogin.lo UrlPath.lo \ + UrlPort.lo UserData.lo Gadgets.lo AclSizeLimit.lo \ + $(am__objects_2) $(am__objects_4) $(am__objects_6) libacls_la_OBJECTS = $(am_libacls_la_OBJECTS) AM_V_lt = $(am__v_lt_@AM_V@) am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) @@ -226,7 +224,7 @@ am__v_lt_1 = libapi_la_LIBADD = am_libapi_la_OBJECTS = Acl.lo BoolOps.lo Checklist.lo InnerNode.lo \ - Tree.lo + Options.lo Tree.lo libapi_la_OBJECTS = $(am_libapi_la_OBJECTS) libstate_la_LIBADD = am_libstate_la_OBJECTS = Strategised.lo FilledChecklist.lo Address.lo @@ -829,10 +827,13 @@ forward.h \ InnerNode.cc \ InnerNode.h \ + Options.h \ + Options.cc \ Tree.cc \ Tree.h libstate_la_SOURCES = \ + CharacterSetOption.h \ Data.h \ Strategy.h \ Strategised.cc \ @@ -845,29 +846,28 @@ libacls_la_SOURCES = IntRange.cc IntRange.h RegexData.cc RegexData.h \ StringData.cc StringData.h Time.cc Time.h TimeData.cc \ TimeData.h AllOf.cc AllOf.h AnyOf.cc AnyOf.h Asn.cc Asn.h \ - Browser.cc Browser.h ConnectionsEncrypted.cc \ - ConnectionsEncrypted.h DestinationAsn.h DestinationDomain.cc \ - DestinationDomain.h DestinationIp.cc DestinationIp.h \ - DomainData.cc DomainData.h ExtUser.cc ExtUser.h \ - HasComponent.cc HasComponent.h HasComponentData.cc \ - HasComponentData.h HierCodeData.cc HierCodeData.h HierCode.cc \ - HierCode.h HttpHeaderData.cc HttpHeaderData.h HttpRepHeader.cc \ - HttpRepHeader.h HttpReqHeader.cc HttpReqHeader.h HttpStatus.cc \ - HttpStatus.h Ip.cc Ip.h LocalIp.cc LocalIp.h LocalPort.cc \ - LocalPort.h MaxConnection.cc MaxConnection.h Method.cc \ - MethodData.cc MethodData.h Method.h MyPortName.cc MyPortName.h \ - Note.h Note.cc NoteData.h NoteData.cc PeerName.cc PeerName.h \ + ConnectionsEncrypted.cc ConnectionsEncrypted.h \ + DestinationAsn.h DestinationDomain.cc DestinationDomain.h \ + DestinationIp.cc DestinationIp.h DomainData.cc DomainData.h \ + ExtUser.cc ExtUser.h HasComponent.cc HasComponent.h \ + HasComponentData.cc HasComponentData.h HierCodeData.cc \ + HierCodeData.h HierCode.cc HierCode.h HttpHeaderData.cc \ + HttpHeaderData.h HttpRepHeader.cc HttpRepHeader.h \ + HttpReqHeader.cc HttpReqHeader.h HttpStatus.cc HttpStatus.h \ + Ip.cc Ip.h LocalIp.cc LocalIp.h LocalPort.cc LocalPort.h \ + MaxConnection.cc MaxConnection.h Method.cc MethodData.cc \ + MethodData.h Method.h MyPortName.cc MyPortName.h Note.h \ + Note.cc NoteData.h NoteData.cc PeerName.cc PeerName.h \ Protocol.cc ProtocolData.cc ProtocolData.h Protocol.h \ - Random.cc Random.h Referer.cc Referer.h ReplyHeaderStrategy.h \ - ReplyMimeType.cc ReplyMimeType.h RequestHeaderStrategy.h \ - RequestMimeType.cc RequestMimeType.h SourceAsn.h \ + Random.cc Random.h ReplyHeaderStrategy.h ReplyMimeType.h \ + RequestHeaderStrategy.h RequestMimeType.h SourceAsn.h \ SourceDomain.cc SourceDomain.h SourceIp.cc SourceIp.h \ SquidError.h SquidError.cc SquidErrorData.cc SquidErrorData.h \ - Tag.cc Tag.h Url.cc Url.h UrlLogin.cc UrlLogin.h UrlPath.cc \ - UrlPath.h UrlPort.cc UrlPort.h UserData.cc UserData.h \ - AclNameList.h AclDenyInfoList.h Gadgets.cc Gadgets.h \ - AclSizeLimit.cc AclSizeLimit.h $(am__append_2) $(am__append_3) \ - $(am__append_4) + Tag.cc Tag.h TransactionInitiator.cc TransactionInitiator.h \ + Url.cc Url.h UrlLogin.cc UrlLogin.h UrlPath.cc UrlPath.h \ + UrlPort.cc UrlPort.h UserData.cc UserData.h AclNameList.h \ + AclDenyInfoList.h Gadgets.cc Gadgets.h AclSizeLimit.cc \ + AclSizeLimit.h $(am__append_2) $(am__append_3) $(am__append_4) EXTRA_libacls_la_SOURCES = $(SSL_ACLS) $(ADAPT_ACLS) $(ARP_ACLS) SSL_ACLS = \ AtStep.cc \ @@ -976,7 +976,6 @@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/AtStep.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/AtStepData.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/BoolOps.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/Browser.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/Certificate.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/CertificateData.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/Checklist.Plo@am__quote@ @@ -1007,14 +1006,12 @@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/MyPortName.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/Note.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/NoteData.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/Options.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/PeerName.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/Protocol.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ProtocolData.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/Random.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/Referer.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/RegexData.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ReplyMimeType.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/RequestMimeType.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ServerCertificate.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ServerName.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/SourceDomain.Plo@am__quote@ @@ -1028,6 +1025,7 @@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/Tag.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/Time.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/TimeData.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/TransactionInitiator.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/Tree.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/Url.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/UrlLogin.Plo@am__quote@ diff -u -r -N squid-4.0.20/src/acl/MaxConnection.h squid-4.0.21/src/acl/MaxConnection.h --- squid-4.0.20/src/acl/MaxConnection.h 2017-06-02 00:49:17.000000000 +1200 +++ squid-4.0.21/src/acl/MaxConnection.h 2017-07-02 20:41:18.000000000 +1200 @@ -10,7 +10,6 @@ #define SQUID_ACLMAXCONNECTION_H #include "acl/Acl.h" -#include "acl/Checklist.h" /// \ingroup ACLAPI class ACLMaxConnection : public ACL @@ -33,8 +32,6 @@ virtual void prepareForUse(); protected: - static Prototype RegistryProtoype; - static ACLMaxConnection RegistryEntry_; char const *class_; int limit; }; diff -u -r -N squid-4.0.20/src/acl/Method.cc squid-4.0.21/src/acl/Method.cc --- squid-4.0.20/src/acl/Method.cc 2017-06-02 00:49:17.000000000 +1200 +++ squid-4.0.21/src/acl/Method.cc 2017-07-02 20:41:18.000000000 +1200 @@ -7,9 +7,10 @@ */ #include "squid.h" -#include "acl/Checklist.h" +#include "acl/FilledChecklist.h" #include "acl/Method.h" #include "acl/MethodData.h" +#include "acl/Strategised.h" #include "HttpRequest.h" /* explicit template instantiation required for some systems */ @@ -17,16 +18,8 @@ template class ACLStrategised; int -ACLMethodStrategy::match (ACLData * &data, ACLFilledChecklist *checklist, ACLFlags &) +ACLMethodStrategy::match (ACLData * &data, ACLFilledChecklist *checklist) { return data->match (checklist->request->method); } -ACLMethodStrategy * -ACLMethodStrategy::Instance() -{ - return &Instance_; -} - -ACLMethodStrategy ACLMethodStrategy::Instance_; - diff -u -r -N squid-4.0.20/src/acl/Method.h squid-4.0.21/src/acl/Method.h --- squid-4.0.20/src/acl/Method.h 2017-06-02 00:49:17.000000000 +1200 +++ squid-4.0.21/src/acl/Method.h 2017-07-02 20:41:18.000000000 +1200 @@ -9,7 +9,6 @@ #ifndef SQUID_ACLMETHOD_H #define SQUID_ACLMETHOD_H -#include "acl/Strategised.h" #include "acl/Strategy.h" #include "http/RequestMethod.h" @@ -18,33 +17,8 @@ { public: - virtual int match (ACLData * &, ACLFilledChecklist *, ACLFlags &); + virtual int match (ACLData * &, ACLFilledChecklist *); virtual bool requiresRequest() const {return true;} - - static ACLMethodStrategy *Instance(); - - /** - * Not implemented to prevent copies of the instance. - \par - * Not private to prevent brain dead g+++ warnings about - * private constructors with no friends - */ - ACLMethodStrategy(ACLMethodStrategy const &); - -private: - static ACLMethodStrategy Instance_; - ACLMethodStrategy() {} - - ACLMethodStrategy&operator=(ACLMethodStrategy const &); -}; - -/// \ingroup ACLAPI -class ACLMethod -{ - -private: - static ACL::Prototype RegistryProtoype; - static ACLStrategised RegistryEntry_; }; #endif /* SQUID_ACLMETHOD_H */ diff -u -r -N squid-4.0.20/src/acl/MyPortName.cc squid-4.0.21/src/acl/MyPortName.cc --- squid-4.0.20/src/acl/MyPortName.cc 2017-06-02 00:49:17.000000000 +1200 +++ squid-4.0.21/src/acl/MyPortName.cc 2017-07-02 20:41:18.000000000 +1200 @@ -7,7 +7,7 @@ */ #include "squid.h" -#include "acl/Checklist.h" +#include "acl/FilledChecklist.h" #include "acl/MyPortName.h" #include "acl/StringData.h" #include "anyp/PortCfg.h" @@ -16,7 +16,7 @@ #include "HttpRequest.h" int -ACLMyPortNameStrategy::match(ACLData * &data, ACLFilledChecklist *checklist, ACLFlags &) +ACLMyPortNameStrategy::match(ACLData * &data, ACLFilledChecklist *checklist) { if (checklist->conn() != NULL && checklist->conn()->port != NULL) return data->match(checklist->conn()->port->name); @@ -25,11 +25,3 @@ return 0; } -ACLMyPortNameStrategy * -ACLMyPortNameStrategy::Instance() -{ - return &Instance_; -} - -ACLMyPortNameStrategy ACLMyPortNameStrategy::Instance_; - diff -u -r -N squid-4.0.20/src/acl/MyPortName.h squid-4.0.21/src/acl/MyPortName.h --- squid-4.0.20/src/acl/MyPortName.h 2017-06-02 00:49:17.000000000 +1200 +++ squid-4.0.21/src/acl/MyPortName.h 2017-07-02 20:41:18.000000000 +1200 @@ -8,33 +8,13 @@ #ifndef SQUID_ACLMYPORTNAME_H #define SQUID_ACLMYPORTNAME_H -#include "acl/Strategised.h" #include "acl/Strategy.h" class ACLMyPortNameStrategy : public ACLStrategy { public: - virtual int match (ACLData * &, ACLFilledChecklist *, ACLFlags &); - static ACLMyPortNameStrategy *Instance(); - /* Not implemented to prevent copies of the instance. */ - /* Not private to prevent brain dead g+++ warnings about - * private constructors with no friends */ - ACLMyPortNameStrategy(ACLMyPortNameStrategy const &); - -private: - static ACLMyPortNameStrategy Instance_; - ACLMyPortNameStrategy() {} - - ACLMyPortNameStrategy&operator=(ACLMyPortNameStrategy const &); -}; - -class ACLMyPortName -{ - -private: - static ACL::Prototype RegistryProtoype; - static ACLStrategised RegistryEntry_; + virtual int match (ACLData * &, ACLFilledChecklist *) override; }; #endif /* SQUID_ACLMYPORTNAME_H */ diff -u -r -N squid-4.0.20/src/acl/Note.cc squid-4.0.21/src/acl/Note.cc --- squid-4.0.20/src/acl/Note.cc 2017-06-02 00:49:17.000000000 +1200 +++ squid-4.0.21/src/acl/Note.cc 2017-07-02 20:41:18.000000000 +1200 @@ -7,24 +7,38 @@ */ #include "squid.h" -#include "acl/Checklist.h" +#include "acl/FilledChecklist.h" #include "acl/HttpHeaderData.h" #include "acl/Note.h" #include "acl/NoteData.h" #include "HttpRequest.h" -#include "Notes.h" #include "parser/Tokenizer.h" #include "sbuf/StringConvert.h" +/* Acl::AnnotationStrategy */ + +const Acl::Options & +Acl::AnnotationStrategy::options() +{ + static const Acl::CharacterSetOption Delimiters; + static const Acl::Options MyOptions = { + { "-m", &Delimiters } + }; + Delimiters.linkWith(&delimiters); + return MyOptions; +} + +/* ACLNoteStrategy */ + int -ACLNoteStrategy::match(ACLData * &data, ACLFilledChecklist *checklist, ACLFlags &flags) +ACLNoteStrategy::match(ACLData * &data, ACLFilledChecklist *checklist) { if (const auto request = checklist->request) { - if (request->notes != NULL && matchNotes(data, request->notes.getRaw(), flags.delimiters())) + if (request->notes != NULL && matchNotes(data, request->notes.getRaw())) return 1; #if USE_ADAPTATION const Adaptation::History::Pointer ah = request->adaptLogHistory(); - if (ah != NULL && ah->metaHeaders != NULL && matchNotes(data, ah->metaHeaders.getRaw(), flags.delimiters())) + if (ah != NULL && ah->metaHeaders != NULL && matchNotes(data, ah->metaHeaders.getRaw())) return 1; #endif } @@ -32,14 +46,14 @@ } bool -ACLNoteStrategy::matchNotes(ACLData *noteData, const NotePairs *note, const CharacterSet *delimiters) const +ACLNoteStrategy::matchNotes(ACLData *noteData, const NotePairs *note) const { for (auto &entry: note->entries) { - if (delimiters) { + if (!delimiters.value.isEmpty()) { NotePairs::Entry e(entry->name.termedBuf(), ""); Parser::Tokenizer t(StringToSBuf(entry->value)); SBuf s; - while (t.token(s, *delimiters)) { + while (t.token(s, delimiters.value)) { e.value = s.c_str(); if (noteData->match(&e)) return true; @@ -55,11 +69,3 @@ return false; } -ACLNoteStrategy * -ACLNoteStrategy::Instance() -{ - return &Instance_; -} - -ACLNoteStrategy ACLNoteStrategy::Instance_; - diff -u -r -N squid-4.0.20/src/acl/Note.h squid-4.0.21/src/acl/Note.h --- squid-4.0.20/src/acl/Note.h 2017-06-02 00:49:17.000000000 +1200 +++ squid-4.0.21/src/acl/Note.h 2017-07-02 20:41:18.000000000 +1200 @@ -9,42 +9,36 @@ #ifndef SQUID_ACLNOTE_H #define SQUID_ACLNOTE_H -#include "acl/Strategised.h" +#include "acl/CharacterSetOption.h" +#include "acl/Data.h" #include "acl/Strategy.h" +#include "Notes.h" -class ACLNoteData; -class CharacterSet; -class HttpRequest; +namespace Acl { -/// \ingroup ACLAPI -class ACLNoteStrategy : public ACLStrategy +/// common parent of several ACLs dealing with transaction annotations +class AnnotationStrategy: public ACLStrategy { - public: - virtual int match (ACLData * &, ACLFilledChecklist *, ACLFlags &); - virtual bool requiresRequest() const { return true; } + AnnotationStrategy(): delimiters(CharacterSet(__FILE__, ",")) {} - static ACLNoteStrategy *Instance(); - /* Not implemented to prevent copies of the instance. */ - /* Not private to prevent brain dead g+++ warnings about - * private constructors with no friends */ - ACLNoteStrategy(ACLNoteStrategy const &); - -private: - static ACLNoteStrategy Instance_; - ACLNoteStrategy() { } + virtual const Acl::Options &options() override; - ACLNoteStrategy& operator = (ACLNoteStrategy const &); - bool matchNotes(ACLData *, const NotePairs *, const CharacterSet *) const; + Acl::CharacterSetOptionValue delimiters; ///< annotation separators }; +} // namespace Acl + /// \ingroup ACLAPI -class ACLNote +class ACLNoteStrategy: public Acl::AnnotationStrategy { +public: + virtual int match (ACLData * &, ACLFilledChecklist *); + virtual bool requiresRequest() const { return true; } + private: - static ACL::Prototype RegistryProtoype; - static ACLStrategised RegistryEntry_; + bool matchNotes(ACLData *, const NotePairs *) const; }; #endif /* SQUID_ACLNOTE_H */ diff -u -r -N squid-4.0.20/src/acl/Options.cc squid-4.0.21/src/acl/Options.cc --- squid-4.0.20/src/acl/Options.cc 1970-01-01 12:00:00.000000000 +1200 +++ squid-4.0.21/src/acl/Options.cc 2017-07-02 20:41:18.000000000 +1200 @@ -0,0 +1,283 @@ +/* + * Copyright (C) 1996-2017 The Squid Software Foundation and contributors + * + * Squid software is distributed under GPLv2+ license and includes + * contributions from numerous individuals and organizations. + * Please see the COPYING and CONTRIBUTORS files for details. + */ + +#include "squid.h" +#include "acl/Options.h" +#include "ConfigParser.h" +#include "Debug.h" +#include "sbuf/Stream.h" + +#include +#include + +namespace Acl { + +/// low-level parser that extracts but does not interpret ACL options +class OptionExtractor +{ +public: + /// parses the next option and fills public members with its details + /// \returns whether option extraction was successful + bool extractOne(); + + /* extracted option details (after successful extraction */ + SBuf name; ///< extracted option name, including dash(es) + bool hasValue = false; ///< whether the option has a value (-x=value) + const SBuf &value() const; ///< extracted option value (requires hasValue) + +protected: + bool advance(); + void extractWhole(); + void extractShort(); + +private: + SBuf prefix_; ///< option name(s), including leading dash(es) + SBuf value_; ///< the last seen value of some option + SBuf::size_type letterPos_ = 0; ///< letter position inside an -xyz sequence + bool sawValue_ = false; ///< the current option sequence had a value +}; + +/// parses/validates/stores ACL options; skips/preserves parameter flags +class OptionsParser +{ +public: + OptionsParser(const Options &options, const ParameterFlags &flags); + + // fill previously supplied options container, throwing on errors + void parse(); + +private: + const Option *findOption(/* const */ SBuf &rawName); + + /// ACL parameter flags in parsing order + typedef std::vector Names; + /// parsed ACL parameter flags that must be preserved for ACLData::parse() + static Names flagsToSkip; + + const Options &options_; ///< caller-supported, linked options + const ParameterFlags ¶meterFlags_; ///< caller-supported parameter flags +}; + +} // namespace Acl + +/* Acl::OptionNameCmp */ + +bool +Acl::OptionNameCmp::operator()(const OptionName a, const OptionName b) const +{ + return strcmp(a, b) < 0; +} + +/* Acl::OptionExtractor */ + +const SBuf & +Acl::OptionExtractor::value() const +{ + Must(hasValue); + return value_; +} + +bool +Acl::OptionExtractor::extractOne() +{ + if (!prefix_.isEmpty()) { + extractShort(); // continue with the previously extracted flags + return true; + } + + if (!advance()) + return false; // end of options (and, possibly, the whole "acl" directive) + + if (prefix_.length() < 2) + throw TexcHere(ToSBuf("truncated(?) ACL flag: ", prefix_)); // single - or + + + if (prefix_[0] == '-' && prefix_[1] == '-') { + if (prefix_.length() == 2) + return false; // skipped "--", an explicit end-of-options marker + extractWhole(); + return true; + } + + if (prefix_.length() == 2) { // common trivial case: -x or +y + extractWhole(); + return true; + } + + // -xyz or +xyz + letterPos_ = 1; + extractShort(); + return true; +} + +/// extracts a token with the next option/flag(s) or returns false +bool +Acl::OptionExtractor::advance() +{ + const char *next = ConfigParser::PeekAtToken(); + if (!next) + return false; // end of the "acl" line + + const char nextChar = *next; + if (!(nextChar == '-' || nextChar == '+')) + return false; // start of ACL parameters + + sawValue_ = strchr(next, '='); // TODO: Make ConfigParser reject '^=.*' tokens + if (sawValue_) { + char *rawPrefix = nullptr; + char *rawValue = nullptr; + if (!ConfigParser::NextKvPair(rawPrefix, rawValue)) + throw TexcHere(ToSBuf("Malformed acl option=value: ", next)); + prefix_.assign(rawPrefix); + value_.assign(rawValue); + } else { + prefix_.assign(next); + ConfigParser::NextToken(); // consume what we have peeked at + } + return true; +} + +/// handles -x[=option] or --foo[=option] +void +Acl::OptionExtractor::extractWhole() +{ + debugs(28, 8, "from " << prefix_ << " value: " << sawValue_); + hasValue = sawValue_; + name = prefix_; + prefix_.clear(); +} + +/// handles one flag letter inside an -xyx[=option] or +xyz[=option] sequence +void +Acl::OptionExtractor::extractShort() +{ + debugs(28, 8, "from " << prefix_ << " at " << letterPos_ << " value: " << sawValue_); + name.assign(prefix_.rawContent(), 1); // leading - or + + name.append(prefix_.at(letterPos_++)); + if (letterPos_ >= prefix_.length()) { // got last flag in the sequence + hasValue = sawValue_; + prefix_.clear(); + } else { + hasValue = false; + } +} + +/* Acl::OptionsParser */ + +// being "static" is an optimization to avoid paying for vector creation/growth +Acl::OptionsParser::Names Acl::OptionsParser::flagsToSkip; + +Acl::OptionsParser::OptionsParser(const Options &options, const ParameterFlags &flags): + options_(options), + parameterFlags_(flags) +{ +} + +const Acl::Option * +Acl::OptionsParser::findOption(/* const */ SBuf &rawNameBuf) +{ + // TODO: new std::map::find() in C++14 does not require this conversion + const auto rawName = rawNameBuf.c_str(); + + const auto optionPos = options_.find(rawName); + if (optionPos != options_.end()) + return optionPos->second; + + const auto flagPos = parameterFlags_.find(rawName); + if (flagPos != parameterFlags_.end()) { + flagsToSkip.push_back(*flagPos); // *flagPos is permanent unlike rawName + return nullptr; + } + + throw TexcHere(ToSBuf("unsupported ACL option: ", rawNameBuf)); +} + +void +Acl::OptionsParser::parse() +{ + flagsToSkip.clear(); + + OptionExtractor oex; + while (oex.extractOne()) { + /* const */ auto rawName = oex.name; + if (const Option *optionPtr = findOption(rawName)) { + const Option &option = *optionPtr; + if (option.configured()) + debugs(28, 7, "acl uses multiple " << rawName << " options"); + switch (option.valueExpectation) + { + case Option::valueNone: + if (oex.hasValue) + throw TexcHere(ToSBuf("unexpected value for an ACL option: ", rawName, '=', oex.value())); + option.configureDefault(); + break; + case Option::valueRequired: + if (!oex.hasValue) + throw TexcHere(ToSBuf("missing required value for ACL option ", rawName)); + option.configureWith(oex.value()); + break; + case Option::valueOptional: + if (oex.hasValue) + option.configureWith(oex.value()); + else + option.configureDefault(); + break; + } + } + // else skip supported parameter flag + } + + /* hack: regex code wants to parse all -i and +i flags itself */ + for (const auto name: flagsToSkip) + ConfigParser::TokenPutBack(name); +} + +void +Acl::ParseFlags(const Options &options, const ParameterFlags &flags) +{ + OptionsParser parser(options, flags); + parser.parse(); +} + +const Acl::Options & +Acl::NoOptions() +{ + static const Options none; + return none; +} + +const Acl::ParameterFlags & +Acl::NoFlags() +{ + static const ParameterFlags none; + return none; +} + +std::ostream & +operator <<(std::ostream &os, const Acl::Option &option) +{ + if (option.valued()) { + os << '='; + option.print(os); + } + return os; +} + +std::ostream & +operator <<(std::ostream &os, const Acl::Options &options) +{ + for (const auto pos: options) { + assert(pos.second); + const auto &option = *pos.second; + if (option.configured()) + os << pos.first << option; + } + // TODO: Remember "--" presence and print that delimiter when present. + // Detecting its need is difficult because parameter flags start with "-". + return os; +} + diff -u -r -N squid-4.0.20/src/acl/Options.h squid-4.0.21/src/acl/Options.h --- squid-4.0.20/src/acl/Options.h 1970-01-01 12:00:00.000000000 +1200 +++ squid-4.0.21/src/acl/Options.h 2017-07-02 20:41:18.000000000 +1200 @@ -0,0 +1,179 @@ +/* + * Copyright (C) 1996-2017 The Squid Software Foundation and contributors + * + * Squid software is distributed under GPLv2+ license and includes + * contributions from numerous individuals and organizations. + * Please see the COPYING and CONTRIBUTORS files for details. + */ + +#ifndef SQUID_ACL_OPTIONS_H +#define SQUID_ACL_OPTIONS_H + +#include "acl/forward.h" +#include "sbuf/forward.h" + +#include +#include +#include + +// After all same-name acl configuration lines are merged into one ACL: +// configuration = acl name type [option...] [[flag...] parameter...] +// option = -x[=value] | --name[=value] +// flag = option +// +// Options and flags use the same syntax, but differ in scope and handling code: +// * ACL options appear before all parameters and apply to all parameters. +// They are handled by ACL kids (or equivalent). +// * Parameter flags may appear after some other parameters and apply only to +// the subsequent parameters (until they are overwritten by later flags). +// They are handled by ACLData kids. +// ACL options parsing code skips and leaves leading parameter flags (if any) +// for ACLData code to process. + +namespace Acl { + +typedef const char *OptionName; + +/// A single option supported by an ACL: -x[=value] or --name[=value] +/// Unlike a parameter flag, this option applies to all ACL parameters. +class Option +{ +public: + typedef enum { valueNone, valueOptional, valueRequired } ValueExpectation; + explicit Option(ValueExpectation vex = valueNone): valueExpectation(vex) {} + virtual ~Option() {} + + /// whether the admin explicitly specified this option + /// (i.e., whether configureWith() or configureDefault() has been called) + virtual bool configured() const = 0; + + /// called after parsing -x or --name + virtual void configureDefault() const = 0; + + /// called after parsing -x=value or --name=value + virtual void configureWith(const SBuf &rawValue) const = 0; + + virtual bool valued() const = 0; + + /// prints a configuration snippet (as an admin could have typed) + virtual void print(std::ostream &os) const = 0; + + ValueExpectation valueExpectation = valueNone; ///< expect "=value" part? +}; + +/// Stores configuration of a typical boolean flag or a single-value Option. +template +class OptionValue +{ +public: + typedef Value value_type; + + OptionValue(): value {} {} + explicit OptionValue(const Value &aValue): value(aValue) {} + + explicit operator bool() const { return configured; } + + Value value; ///< final value storage, possibly after conversions + bool configured = false; ///< whether the option was present in squid.conf + bool valued = false; ///< whether a configured option had a value +}; + +/// a type-specific Option (e.g., a boolean --toggle or -m=SBuf) +template +class TypedOption: public Option +{ +public: + //typedef typename Recipient::value_type value_type; + explicit TypedOption(ValueExpectation vex = valueNone): Option(vex) {} + + /// who to tell when this option is enabled + void linkWith(Recipient *recipient) const + { + assert(recipient); + recipient_ = recipient; + } + + /* Option API */ + + virtual bool configured() const override { return recipient_ && recipient_->configured; } + virtual bool valued() const override { return recipient_ && recipient_->valued; } + + /// sets the default value when option is used without a value + virtual void configureDefault() const override + { + assert(recipient_); + recipient_->configured = true; + recipient_->valued = false; + // sets recipient_->value to default + setDefault(); + } + + /// sets the option value from rawValue + virtual void configureWith(const SBuf &rawValue) const override + { + assert(recipient_); + recipient_->configured = true; + recipient_->valued = true; + import(rawValue); + } + + virtual void print(std::ostream &os) const override { if (valued()) os << recipient_->value; } + +private: + void import(const SBuf &rawValue) const { recipient_->value = rawValue; } + void setDefault() const { /*leave recipient_->value as is*/} + + // The "mutable" specifier demarcates set-once Option kind/behavior from the + // ever-changing recipient of the actual admin-configured option value. + mutable Recipient *recipient_ = nullptr; ///< parsing results storage +}; + +/* two typical option kinds: --foo and --bar=text */ +typedef OptionValue BooleanOptionValue; +typedef OptionValue TextOptionValue; +typedef TypedOption BooleanOption; +typedef TypedOption TextOption; + +// this specialization should never be called until we start supporting +// boolean option values like --name=enable or --name=false +template <> +inline void +BooleanOption::import(const SBuf &) const +{ + assert(!"boolean options do not have ...=values (for now)"); +} + +template <> +inline void +BooleanOption::setDefault() const +{ + recipient_->value = true; +} + +/// option name comparison functor +class OptionNameCmp { +public: + bool operator()(const OptionName a, const OptionName b) const; +}; +/// name:option map +typedef std::map Options; + +/// a set of parameter flag names +typedef std::set ParameterFlags; + +/// parses the flags part of the being-parsed ACL, filling Option values +/// \param options options supported by the ACL as a whole (e.g., -n) +/// \param flags options supported by ACL parameter(s) (e.g., -i) +void ParseFlags(const Options &options, const ParameterFlags &flags); + +/* handy for Class::options() and Class::supportedFlags() defaults */ +const Options &NoOptions(); ///< \returns an empty Options container +const ParameterFlags &NoFlags(); ///< \returns an empty ParameterFlags container + +} // namespace Acl + +std::ostream &operator <<(std::ostream &os, const Acl::Option &option); +std::ostream &operator <<(std::ostream &os, const Acl::Options &options); + +#endif /* SQUID_ACL_OPTIONS_H */ + diff -u -r -N squid-4.0.20/src/acl/PeerName.cc squid-4.0.21/src/acl/PeerName.cc --- squid-4.0.20/src/acl/PeerName.cc 2017-06-02 00:49:17.000000000 +1200 +++ squid-4.0.21/src/acl/PeerName.cc 2017-07-02 20:41:18.000000000 +1200 @@ -7,25 +7,16 @@ */ #include "squid.h" -#include "acl/Checklist.h" +#include "acl/FilledChecklist.h" #include "acl/PeerName.h" #include "acl/RegexData.h" #include "acl/StringData.h" -#include "CachePeer.h" int -ACLPeerNameStrategy::match (ACLData * &data, ACLFilledChecklist *checklist, ACLFlags &) +ACLPeerNameStrategy::match (ACLData * &data, ACLFilledChecklist *checklist) { if (!checklist->dst_peer_name.isEmpty()) return data->match(checklist->dst_peer_name.c_str()); return 0; } -ACLPeerNameStrategy * -ACLPeerNameStrategy::Instance() -{ - return &Instance_; -} - -ACLPeerNameStrategy ACLPeerNameStrategy::Instance_; - diff -u -r -N squid-4.0.20/src/acl/PeerName.h squid-4.0.21/src/acl/PeerName.h --- squid-4.0.20/src/acl/PeerName.h 2017-06-02 00:49:17.000000000 +1200 +++ squid-4.0.21/src/acl/PeerName.h 2017-07-02 20:41:18.000000000 +1200 @@ -9,35 +9,13 @@ #ifndef SQUID_ACLPEERNAME_H #define SQUID_ACLPEERNAME_H -#include "acl/Strategised.h" #include "acl/Strategy.h" class ACLPeerNameStrategy : public ACLStrategy { public: - virtual int match (ACLData * &, ACLFilledChecklist *, ACLFlags &); - static ACLPeerNameStrategy *Instance(); - /* Not implemented to prevent copies of the instance. */ - /* Not private to prevent brain dead g+++ warnings about - * private constructors with no friends */ - ACLPeerNameStrategy(ACLPeerNameStrategy const &); - -private: - static ACLPeerNameStrategy Instance_; - ACLPeerNameStrategy() {} - - ACLPeerNameStrategy&operator=(ACLPeerNameStrategy const &); -}; - -class ACLPeerName -{ - -private: - static ACL::Prototype RegistryProtoype; - static ACLStrategised RegistryEntry_; - static ACL::Prototype RegexRegistryProtoype; - static ACLStrategised RegexRegistryEntry_; + virtual int match (ACLData * &, ACLFilledChecklist *) override; }; #endif /* SQUID_ACLPEERNAME_H */ diff -u -r -N squid-4.0.20/src/acl/Protocol.cc squid-4.0.21/src/acl/Protocol.cc --- squid-4.0.20/src/acl/Protocol.cc 2017-06-02 00:49:17.000000000 +1200 +++ squid-4.0.21/src/acl/Protocol.cc 2017-07-02 20:41:18.000000000 +1200 @@ -7,9 +7,10 @@ */ #include "squid.h" -#include "acl/Checklist.h" +#include "acl/FilledChecklist.h" #include "acl/Protocol.h" #include "acl/ProtocolData.h" +#include "acl/Strategised.h" #include "HttpRequest.h" /* explicit template instantiation required for some systems */ @@ -17,16 +18,8 @@ template class ACLStrategised; int -ACLProtocolStrategy::match(ACLData * &data, ACLFilledChecklist *checklist, ACLFlags &) +ACLProtocolStrategy::match(ACLData * &data, ACLFilledChecklist *checklist) { return data->match(checklist->request->url.getScheme()); } -ACLProtocolStrategy * -ACLProtocolStrategy::Instance() -{ - return &Instance_; -} - -ACLProtocolStrategy ACLProtocolStrategy::Instance_; - diff -u -r -N squid-4.0.20/src/acl/Protocol.h squid-4.0.21/src/acl/Protocol.h --- squid-4.0.20/src/acl/Protocol.h 2017-06-02 00:49:17.000000000 +1200 +++ squid-4.0.21/src/acl/Protocol.h 2017-07-02 20:41:18.000000000 +1200 @@ -9,7 +9,6 @@ #ifndef SQUID_ACLPROTOCOL_H #define SQUID_ACLPROTOCOL_H -#include "acl/Strategised.h" #include "acl/Strategy.h" #include "anyp/ProtocolType.h" @@ -17,28 +16,8 @@ { public: - virtual int match (ACLData * &, ACLFilledChecklist *, ACLFlags &); + virtual int match (ACLData * &, ACLFilledChecklist *); virtual bool requiresRequest() const {return true;} - - static ACLProtocolStrategy *Instance(); - /* Not implemented to prevent copies of the instance. */ - /* Not private to prevent brain dead g+++ warnings about - * private constructors with no friends */ - ACLProtocolStrategy(ACLProtocolStrategy const &); - -private: - static ACLProtocolStrategy Instance_; - ACLProtocolStrategy() {} - - ACLProtocolStrategy&operator=(ACLProtocolStrategy const &); -}; - -class ACLProtocol -{ - -private: - static ACL::Prototype RegistryProtoype; - static ACLStrategised RegistryEntry_; }; #endif /* SQUID_ACLPROTOCOL_H */ diff -u -r -N squid-4.0.20/src/acl/Random.h squid-4.0.21/src/acl/Random.h --- squid-4.0.20/src/acl/Random.h 2017-06-02 00:49:17.000000000 +1200 +++ squid-4.0.21/src/acl/Random.h 2017-07-02 20:41:18.000000000 +1200 @@ -10,7 +10,6 @@ #define SQUID_ACL_RANDOM_H #include "acl/Acl.h" -#include "acl/Checklist.h" class ACLRandom : public ACL { @@ -31,8 +30,6 @@ virtual bool valid() const; protected: - static Prototype RegistryProtoype; - static ACLRandom RegistryEntry_; double data; // value to be exceeded before this ACL will match char pattern[256]; // pattern from config file. Used to generate 'data' char const *class_; diff -u -r -N squid-4.0.20/src/acl/Referer.cc squid-4.0.21/src/acl/Referer.cc --- squid-4.0.20/src/acl/Referer.cc 2017-06-02 00:49:17.000000000 +1200 +++ squid-4.0.21/src/acl/Referer.cc 1970-01-01 12:00:00.000000000 +1200 @@ -1,19 +0,0 @@ -/* - * Copyright (C) 1996-2017 The Squid Software Foundation and contributors - * - * Squid software is distributed under GPLv2+ license and includes - * contributions from numerous individuals and organizations. - * Please see the COPYING and CONTRIBUTORS files for details. - */ - -/* DEBUG: section 28 Access Control */ - -#include "squid.h" -#include "acl/Checklist.h" -#include "acl/Referer.h" -#include "acl/RegexData.h" - -/* explicit template instantiation required for some systems */ - -template class ACLRequestHeaderStrategy; - diff -u -r -N squid-4.0.20/src/acl/Referer.h squid-4.0.21/src/acl/Referer.h --- squid-4.0.20/src/acl/Referer.h 2017-06-02 00:49:17.000000000 +1200 +++ squid-4.0.21/src/acl/Referer.h 1970-01-01 12:00:00.000000000 +1200 @@ -1,25 +0,0 @@ -/* - * Copyright (C) 1996-2017 The Squid Software Foundation and contributors - * - * Squid software is distributed under GPLv2+ license and includes - * contributions from numerous individuals and organizations. - * Please see the COPYING and CONTRIBUTORS files for details. - */ - -#ifndef SQUID_ACLREFERER_H -#define SQUID_ACLREFERER_H -#include "acl/Acl.h" -#include "acl/Data.h" -#include "acl/RequestHeaderStrategy.h" -#include "acl/Strategised.h" - -class ACLReferer -{ - -private: - static ACL::Prototype RegistryProtoype; - static ACLStrategised RegistryEntry_; -}; - -#endif /* SQUID_ACLREFERER_H */ - diff -u -r -N squid-4.0.20/src/acl/RegexData.cc squid-4.0.21/src/acl/RegexData.cc --- squid-4.0.20/src/acl/RegexData.cc 2017-06-02 00:49:17.000000000 +1200 +++ squid-4.0.21/src/acl/RegexData.cc 2017-07-02 20:41:18.000000000 +1200 @@ -27,6 +27,13 @@ { } +const Acl::ParameterFlags & +ACLRegexData::supportedFlags() const +{ + static const Acl::ParameterFlags flags = { "-i", "+i" }; + return flags; +} + bool ACLRegexData::match(char const *word) { diff -u -r -N squid-4.0.20/src/acl/RegexData.h squid-4.0.21/src/acl/RegexData.h --- squid-4.0.20/src/acl/RegexData.h 2017-06-02 00:49:17.000000000 +1200 +++ squid-4.0.21/src/acl/RegexData.h 2017-07-02 20:41:18.000000000 +1200 @@ -24,6 +24,7 @@ virtual bool match(char const *user); virtual SBufList dump() const; virtual void parse(); + virtual const Acl::ParameterFlags &supportedFlags() const; virtual bool empty() const; virtual ACLData *clone() const; diff -u -r -N squid-4.0.20/src/acl/ReplyHeaderStrategy.h squid-4.0.21/src/acl/ReplyHeaderStrategy.h --- squid-4.0.20/src/acl/ReplyHeaderStrategy.h 2017-06-02 00:49:17.000000000 +1200 +++ squid-4.0.21/src/acl/ReplyHeaderStrategy.h 2017-07-02 20:41:18.000000000 +1200 @@ -9,8 +9,6 @@ #ifndef SQUID_ACLREPLYHEADERSTRATEGY_H #define SQUID_ACLREPLYHEADERSTRATEGY_H -class ACLChecklist; - #include "acl/Acl.h" #include "acl/Data.h" #include "acl/FilledChecklist.h" @@ -22,25 +20,13 @@ { public: - virtual int match (ACLData * &, ACLFilledChecklist *, ACLFlags &); + virtual int match (ACLData * &, ACLFilledChecklist *); virtual bool requiresReply() const {return true;} - - static ACLReplyHeaderStrategy *Instance(); - /* Not implemented to prevent copies of the instance. */ - /* Not private to prevent brain dead g+++ warnings about - * private constructors with no friends */ - ACLReplyHeaderStrategy(ACLReplyHeaderStrategy const &); - -private: - static ACLReplyHeaderStrategy *Instance_; - ACLReplyHeaderStrategy() {} - - ACLReplyHeaderStrategy&operator=(ACLReplyHeaderStrategy const &); }; template int -ACLReplyHeaderStrategy

::match (ACLData * &data, ACLFilledChecklist *checklist, ACLFlags &) +ACLReplyHeaderStrategy
::match (ACLData * &data, ACLFilledChecklist *checklist) { char const *theHeader = checklist->reply->header.getStr(header); @@ -50,18 +36,5 @@ return data->match(theHeader); } -template -ACLReplyHeaderStrategy
* -ACLReplyHeaderStrategy
::Instance() -{ - if (!Instance_) - Instance_ = new ACLReplyHeaderStrategy
; - - return Instance_; -} - -template -ACLReplyHeaderStrategy
* ACLReplyHeaderStrategy
::Instance_ = NULL; - #endif /* SQUID_REPLYHEADERSTRATEGY_H */ diff -u -r -N squid-4.0.20/src/acl/ReplyMimeType.cc squid-4.0.21/src/acl/ReplyMimeType.cc --- squid-4.0.20/src/acl/ReplyMimeType.cc 2017-06-02 00:49:17.000000000 +1200 +++ squid-4.0.21/src/acl/ReplyMimeType.cc 1970-01-01 12:00:00.000000000 +1200 @@ -1,19 +0,0 @@ -/* - * Copyright (C) 1996-2017 The Squid Software Foundation and contributors - * - * Squid software is distributed under GPLv2+ license and includes - * contributions from numerous individuals and organizations. - * Please see the COPYING and CONTRIBUTORS files for details. - */ - -/* DEBUG: section 28 Access Control */ - -#include "squid.h" -#include "acl/Checklist.h" -#include "acl/RegexData.h" -#include "acl/ReplyMimeType.h" - -/* explicit template instantiation required for some systems */ - -template class ACLReplyHeaderStrategy; - diff -u -r -N squid-4.0.20/src/acl/ReplyMimeType.h squid-4.0.21/src/acl/ReplyMimeType.h --- squid-4.0.20/src/acl/ReplyMimeType.h 2017-06-02 00:49:17.000000000 +1200 +++ squid-4.0.21/src/acl/ReplyMimeType.h 2017-07-02 20:41:18.000000000 +1200 @@ -9,26 +9,15 @@ #ifndef SQUID_ACLREPLYMIMETYPE_H #define SQUID_ACLREPLYMIMETYPE_H -#include "acl/Acl.h" -#include "acl/Strategised.h" - -class ACLReplyMIMEType -{ - -private: - static ACL::Prototype RegistryProtoype; - static ACLStrategised RegistryEntry_; -}; - -/* partial specialisation */ - -#include "acl/Checklist.h" #include "acl/Data.h" +#include "acl/FilledChecklist.h" #include "acl/ReplyHeaderStrategy.h" +/* partial specialisation */ + template <> inline int -ACLReplyHeaderStrategy::match(ACLData * &data, ACLFilledChecklist *checklist, ACLFlags &) +ACLReplyHeaderStrategy::match(ACLData * &data, ACLFilledChecklist *checklist) { char const *theHeader = checklist->reply->header.getStr(Http::HdrType::CONTENT_TYPE); diff -u -r -N squid-4.0.20/src/acl/RequestHeaderStrategy.h squid-4.0.21/src/acl/RequestHeaderStrategy.h --- squid-4.0.20/src/acl/RequestHeaderStrategy.h 2017-06-02 00:49:17.000000000 +1200 +++ squid-4.0.21/src/acl/RequestHeaderStrategy.h 2017-07-02 20:41:18.000000000 +1200 @@ -19,25 +19,13 @@ { public: - virtual int match (ACLData * &, ACLFilledChecklist *, ACLFlags &); + virtual int match (ACLData * &, ACLFilledChecklist *); virtual bool requiresRequest() const {return true;} - - static ACLRequestHeaderStrategy *Instance(); - /* Not implemented to prevent copies of the instance. */ - /* Not private to prevent brain dead g+++ warnings about - * private constructors with no friends */ - ACLRequestHeaderStrategy(ACLRequestHeaderStrategy const &); - -private: - static ACLRequestHeaderStrategy *Instance_; - ACLRequestHeaderStrategy() {} - - ACLRequestHeaderStrategy&operator=(ACLRequestHeaderStrategy const &); }; template int -ACLRequestHeaderStrategy
::match (ACLData * &data, ACLFilledChecklist *checklist, ACLFlags &) +ACLRequestHeaderStrategy
::match (ACLData * &data, ACLFilledChecklist *checklist) { char const *theHeader = checklist->request->header.getStr(header); @@ -47,18 +35,5 @@ return data->match(theHeader); } -template -ACLRequestHeaderStrategy
* -ACLRequestHeaderStrategy
::Instance() -{ - if (!Instance_) - Instance_ = new ACLRequestHeaderStrategy
; - - return Instance_; -} - -template -ACLRequestHeaderStrategy
* ACLRequestHeaderStrategy
::Instance_ = NULL; - #endif /* SQUID_REQUESTHEADERSTRATEGY_H */ diff -u -r -N squid-4.0.20/src/acl/RequestMimeType.cc squid-4.0.21/src/acl/RequestMimeType.cc --- squid-4.0.20/src/acl/RequestMimeType.cc 2017-06-02 00:49:17.000000000 +1200 +++ squid-4.0.21/src/acl/RequestMimeType.cc 1970-01-01 12:00:00.000000000 +1200 @@ -1,19 +0,0 @@ -/* - * Copyright (C) 1996-2017 The Squid Software Foundation and contributors - * - * Squid software is distributed under GPLv2+ license and includes - * contributions from numerous individuals and organizations. - * Please see the COPYING and CONTRIBUTORS files for details. - */ - -/* DEBUG: section 28 Access Control */ - -#include "squid.h" -#include "acl/Checklist.h" -#include "acl/RegexData.h" -#include "acl/RequestMimeType.h" - -/* explicit template instantiation required for some systems */ - -template class ACLRequestHeaderStrategy; - diff -u -r -N squid-4.0.20/src/acl/RequestMimeType.h squid-4.0.21/src/acl/RequestMimeType.h --- squid-4.0.20/src/acl/RequestMimeType.h 2017-06-02 00:49:17.000000000 +1200 +++ squid-4.0.21/src/acl/RequestMimeType.h 2017-07-02 20:41:18.000000000 +1200 @@ -9,26 +9,15 @@ #ifndef SQUID_ACLREQUESTMIMETYPE_H #define SQUID_ACLREQUESTMIMETYPE_H -#include "acl/Acl.h" -#include "acl/Strategised.h" - -class ACLRequestMIMEType -{ - -private: - static ACL::Prototype RegistryProtoype; - static ACLStrategised RegistryEntry_; -}; - -/* partial specialisation */ - -#include "acl/Checklist.h" #include "acl/Data.h" +#include "acl/FilledChecklist.h" #include "acl/RequestHeaderStrategy.h" +/* partial specialisation */ + template <> inline int -ACLRequestHeaderStrategy::match (ACLData * &data, ACLFilledChecklist *checklist, ACLFlags &) +ACLRequestHeaderStrategy::match (ACLData * &data, ACLFilledChecklist *checklist) { char const *theHeader = checklist->request->header.getStr(Http::HdrType::CONTENT_TYPE); diff -u -r -N squid-4.0.20/src/acl/ServerCertificate.cc squid-4.0.21/src/acl/ServerCertificate.cc --- squid-4.0.20/src/acl/ServerCertificate.cc 2017-06-02 00:49:17.000000000 +1200 +++ squid-4.0.21/src/acl/ServerCertificate.cc 2017-07-02 20:41:18.000000000 +1200 @@ -19,7 +19,7 @@ #include "ssl/ServerBump.h" int -ACLServerCertificateStrategy::match(ACLData * &data, ACLFilledChecklist *checklist, ACLFlags &) +ACLServerCertificateStrategy::match(ACLData * &data, ACLFilledChecklist *checklist) { Security::CertPointer cert; if (checklist->serverCert) @@ -33,13 +33,5 @@ return data->match(cert.get()); } -ACLServerCertificateStrategy * -ACLServerCertificateStrategy::Instance() -{ - return &Instance_; -} - -ACLServerCertificateStrategy ACLServerCertificateStrategy::Instance_; - #endif /* USE_OPENSSL */ diff -u -r -N squid-4.0.20/src/acl/ServerCertificate.h squid-4.0.21/src/acl/ServerCertificate.h --- squid-4.0.20/src/acl/ServerCertificate.h 2017-06-02 00:49:17.000000000 +1200 +++ squid-4.0.21/src/acl/ServerCertificate.h 2017-07-02 20:41:18.000000000 +1200 @@ -19,26 +19,7 @@ class ACLServerCertificateStrategy : public ACLStrategy { public: - virtual int match (ACLData * &, ACLFilledChecklist *, ACLFlags &); - static ACLServerCertificateStrategy *Instance(); - /* Not implemented to prevent copies of the instance. */ - /* Not private to prevent brain dead g+++ warnings about - * private constructors with no friends */ - ACLServerCertificateStrategy(ACLServerCertificateStrategy const &); - -private: - static ACLServerCertificateStrategy Instance_; - ACLServerCertificateStrategy() {} - - ACLServerCertificateStrategy&operator=(ACLServerCertificateStrategy const &); -}; - -/// \ingroup ACLAPI -class ACLServerCertificate -{ -private: - static ACL::Prototype X509FingerprintRegistryProtoype; - static ACLStrategised X509FingerprintRegistryEntry_; + virtual int match (ACLData * &, ACLFilledChecklist *) override; }; #endif /* SQUID_ACLSERVERCERTIFICATE_H */ diff -u -r -N squid-4.0.20/src/acl/ServerName.cc squid-4.0.21/src/acl/ServerName.cc --- squid-4.0.20/src/acl/ServerName.cc 2017-06-02 00:49:17.000000000 +1200 +++ squid-4.0.21/src/acl/ServerName.cc 2017-07-02 20:41:18.000000000 +1200 @@ -9,8 +9,8 @@ /* DEBUG: section 28 Access Control */ #include "squid.h" -#include "acl/Checklist.h" #include "acl/DomainData.h" +#include "acl/FilledChecklist.h" #include "acl/RegexData.h" #include "acl/ServerName.h" #include "client_side.h" @@ -87,26 +87,35 @@ } int -ACLServerNameStrategy::match (ACLData * &data, ACLFilledChecklist *checklist, ACLFlags &flags) +ACLServerNameStrategy::match (ACLData * &data, ACLFilledChecklist *checklist) { assert(checklist != NULL && checklist->request != NULL); const char *serverName = nullptr; - SBuf serverNameKeeper; // because c_str() is not constant + SBuf clientSniKeeper; // because c_str() is not constant if (ConnStateData *conn = checklist->conn()) { - - if (conn->serverBump()) { - if (X509 *peer_cert = conn->serverBump()->serverCert.get()) - return Ssl::matchX509CommonNames(peer_cert, (void *)data, check_cert_domain); - } - - if (conn->sslCommonName().isEmpty()) { + const char *clientRequestedServerName = nullptr; + clientSniKeeper = conn->tlsClientSni(); + if (clientSniKeeper.isEmpty()) { const char *host = checklist->request->url.host(); if (host && *host) // paranoid first condition: host() is never nil - serverName = host; - } else { - serverNameKeeper = conn->sslCommonName(); - serverName = serverNameKeeper.c_str(); + clientRequestedServerName = host; + } else + clientRequestedServerName = clientSniKeeper.c_str(); + + if (useConsensus) { + X509 *peer_cert = conn->serverBump() ? conn->serverBump()->serverCert.get() : nullptr; + // use the client requested name if it matches the server + // certificate or if the certificate is not available + if (!peer_cert || Ssl::checkX509ServerValidity(peer_cert, clientRequestedServerName)) + serverName = clientRequestedServerName; + } else if (useClientRequested) + serverName = clientRequestedServerName; + else { // either no options or useServerProvided + if (X509 *peer_cert = (conn->serverBump() ? conn->serverBump()->serverCert.get() : nullptr)) + return Ssl::matchX509CommonNames(peer_cert, (void *)data, check_cert_domain); + if (!useServerProvided) + serverName = clientRequestedServerName; } } @@ -116,11 +125,40 @@ return data->match(serverName); } -ACLServerNameStrategy * -ACLServerNameStrategy::Instance() +const Acl::Options & +ACLServerNameStrategy::options() { - return &Instance_; + static const Acl::BooleanOption ClientRequested; + static const Acl::BooleanOption ServerProvided; + static const Acl::BooleanOption Consensus; + static const Acl::Options MyOptions = { + {"--client-requested", &ClientRequested}, + {"--server-provided", &ServerProvided}, + {"--consensus", &Consensus} + }; + + ClientRequested.linkWith(&useClientRequested); + ServerProvided.linkWith(&useServerProvided); + Consensus.linkWith(&useConsensus); + return MyOptions; } -ACLServerNameStrategy ACLServerNameStrategy::Instance_; +bool +ACLServerNameStrategy::valid() const +{ + int optionCount = 0; + + if (useClientRequested) + optionCount++; + if (useServerProvided) + optionCount++; + if (useConsensus) + optionCount++; + + if (optionCount > 1) { + debugs(28, DBG_CRITICAL, "ERROR: Multiple options given for the server_name ACL"); + return false; + } + return true; +} diff -u -r -N squid-4.0.20/src/acl/ServerName.h squid-4.0.21/src/acl/ServerName.h --- squid-4.0.20/src/acl/ServerName.h 2017-06-02 00:49:17.000000000 +1200 +++ squid-4.0.21/src/acl/ServerName.h 2017-07-02 20:41:18.000000000 +1200 @@ -10,10 +10,8 @@ #define SQUID_ACLSERVERNAME_H #include "acl/Acl.h" -#include "acl/Checklist.h" -#include "acl/Data.h" #include "acl/DomainData.h" -#include "acl/Strategised.h" +#include "acl/Strategy.h" class ACLServerNameData : public ACLDomainData { MEMPROXY_CLASS(ACLServerNameData); @@ -27,33 +25,16 @@ { public: - virtual int match (ACLData * &, ACLFilledChecklist *, ACLFlags &); - static ACLServerNameStrategy *Instance(); + /* ACLStrategy API */ + virtual int match (ACLData * &, ACLFilledChecklist *); virtual bool requiresRequest() const {return true;} - - /** - * Not implemented to prevent copies of the instance. - \par - * Not private to prevent brain dead g+++ warnings about - * private constructors with no friends - */ - ACLServerNameStrategy(ACLServerNameStrategy const &); - -private: - static ACLServerNameStrategy Instance_; - ACLServerNameStrategy() {} - - ACLServerNameStrategy&operator=(ACLServerNameStrategy const &); -}; - -class ACLServerName -{ + virtual const Acl::Options &options(); + virtual bool valid() const; private: - static ACL::Prototype LiteralRegistryProtoype; - static ACLStrategised LiteralRegistryEntry_; - static ACL::Prototype RegexRegistryProtoype; - static ACLStrategised RegexRegistryEntry_; + Acl::BooleanOptionValue useClientRequested; ///< Ignore server-supplied names + Acl::BooleanOptionValue useServerProvided; ///< Ignore client-supplied names + Acl::BooleanOptionValue useConsensus; ///< Ignore mismatching names }; #endif /* SQUID_ACLSERVERNAME_H */ diff -u -r -N squid-4.0.20/src/acl/SourceAsn.h squid-4.0.21/src/acl/SourceAsn.h --- squid-4.0.20/src/acl/SourceAsn.h 2017-06-02 00:49:17.000000000 +1200 +++ squid-4.0.21/src/acl/SourceAsn.h 2017-07-02 20:41:18.000000000 +1200 @@ -18,18 +18,7 @@ { public: - virtual int match (ACLData * &, ACLFilledChecklist *, ACLFlags &); - static ACLSourceASNStrategy *Instance(); - /* Not implemented to prevent copies of the instance. */ - /* Not private to prevent brain dead g+++ warnings about - * private constructors with no friends */ - ACLSourceASNStrategy(ACLSourceASNStrategy const &); - -private: - static ACLSourceASNStrategy Instance_; - ACLSourceASNStrategy() {} - - ACLSourceASNStrategy&operator=(ACLSourceASNStrategy const &); + virtual int match (ACLData * &, ACLFilledChecklist *) override; }; #endif /* SQUID_ACL_SOURCEASN_H */ diff -u -r -N squid-4.0.20/src/acl/SourceDomain.cc squid-4.0.21/src/acl/SourceDomain.cc --- squid-4.0.20/src/acl/SourceDomain.cc 2017-06-02 00:49:17.000000000 +1200 +++ squid-4.0.21/src/acl/SourceDomain.cc 2017-07-02 20:41:18.000000000 +1200 @@ -11,6 +11,7 @@ #include "squid.h" #include "acl/Checklist.h" #include "acl/DomainData.h" +#include "acl/FilledChecklist.h" #include "acl/RegexData.h" #include "acl/SourceDomain.h" #include "fqdncache.h" @@ -40,7 +41,7 @@ } int -ACLSourceDomainStrategy::match (ACLData * &data, ACLFilledChecklist *checklist, ACLFlags &) +ACLSourceDomainStrategy::match (ACLData * &data, ACLFilledChecklist *checklist) { const char *fqdn = NULL; fqdn = fqdncache_gethostbyaddr(checklist->src_addr, FQDN_LOOKUP_IF_MISS); @@ -58,11 +59,3 @@ return data->match("none"); } -ACLSourceDomainStrategy * -ACLSourceDomainStrategy::Instance() -{ - return &Instance_; -} - -ACLSourceDomainStrategy ACLSourceDomainStrategy::Instance_; - diff -u -r -N squid-4.0.20/src/acl/SourceDomain.h squid-4.0.21/src/acl/SourceDomain.h --- squid-4.0.20/src/acl/SourceDomain.h 2017-06-02 00:49:17.000000000 +1200 +++ squid-4.0.21/src/acl/SourceDomain.h 2017-07-02 20:41:18.000000000 +1200 @@ -11,25 +11,14 @@ #include "acl/Acl.h" #include "acl/Checklist.h" #include "acl/Data.h" -#include "acl/Strategised.h" +#include "acl/Strategy.h" #include "dns/forward.h" class ACLSourceDomainStrategy : public ACLStrategy { public: - virtual int match (ACLData * &, ACLFilledChecklist *, ACLFlags &); - static ACLSourceDomainStrategy *Instance(); - /* Not implemented to prevent copies of the instance. */ - /* Not private to prevent brain dead g+++ warnings about - * private constructors with no friends */ - ACLSourceDomainStrategy(ACLSourceDomainStrategy const &); - -private: - static ACLSourceDomainStrategy Instance_; - ACLSourceDomainStrategy() {} - - ACLSourceDomainStrategy&operator=(ACLSourceDomainStrategy const &); + virtual int match (ACLData * &, ACLFilledChecklist *) override; }; class SourceDomainLookup : public ACLChecklist::AsyncState @@ -44,15 +33,5 @@ static void LookupDone(const char *, const Dns::LookupDetails &, void *); }; -class ACLSourceDomain -{ - -private: - static ACL::Prototype LiteralRegistryProtoype; - static ACLStrategised LiteralRegistryEntry_; - static ACL::Prototype RegexRegistryProtoype; - static ACLStrategised RegexRegistryEntry_; -}; - #endif /* SQUID_ACLSOURCEDOMAIN_H */ diff -u -r -N squid-4.0.20/src/acl/SourceIp.h squid-4.0.21/src/acl/SourceIp.h --- squid-4.0.20/src/acl/SourceIp.h 2017-06-02 00:49:17.000000000 +1200 +++ squid-4.0.21/src/acl/SourceIp.h 2017-07-02 20:41:18.000000000 +1200 @@ -19,10 +19,6 @@ virtual char const *typeString() const; virtual int match(ACLChecklist *checklist); virtual ACL *clone()const; - -private: - static Prototype RegistryProtoype; - static ACLSourceIP RegistryEntry_; }; #endif /* SQUID_ACLSOURCEIP_H */ diff -u -r -N squid-4.0.20/src/acl/SquidError.cc squid-4.0.21/src/acl/SquidError.cc --- squid-4.0.20/src/acl/SquidError.cc 2017-06-02 00:49:17.000000000 +1200 +++ squid-4.0.21/src/acl/SquidError.cc 2017-07-02 20:41:18.000000000 +1200 @@ -7,12 +7,12 @@ */ #include "squid.h" -#include "acl/Checklist.h" +#include "acl/FilledChecklist.h" #include "acl/SquidError.h" #include "HttpRequest.h" int -ACLSquidErrorStrategy::match (ACLData * &data, ACLFilledChecklist *checklist, ACLFlags &) +ACLSquidErrorStrategy::match (ACLData * &data, ACLFilledChecklist *checklist) { if (checklist->requestErrorType != ERR_MAX) return data->match(checklist->requestErrorType); @@ -21,11 +21,3 @@ return 0; } -ACLSquidErrorStrategy * -ACLSquidErrorStrategy::Instance() -{ - return &Instance_; -} - -ACLSquidErrorStrategy ACLSquidErrorStrategy::Instance_; - diff -u -r -N squid-4.0.20/src/acl/SquidError.h squid-4.0.21/src/acl/SquidError.h --- squid-4.0.20/src/acl/SquidError.h 2017-06-02 00:49:17.000000000 +1200 +++ squid-4.0.21/src/acl/SquidError.h 2017-07-02 20:41:18.000000000 +1200 @@ -9,7 +9,6 @@ #ifndef SQUID_ACLSQUIDERROR_H #define SQUID_ACLSQUIDERROR_H -#include "acl/Strategised.h" #include "acl/Strategy.h" #include "err_type.h" @@ -17,27 +16,7 @@ { public: - virtual int match (ACLData * &, ACLFilledChecklist *, ACLFlags &); - - static ACLSquidErrorStrategy *Instance(); - /* Not implemented to prevent copies of the instance. */ - /* Not private to prevent brain dead g+++ warnings about - * private constructors with no friends */ - ACLSquidErrorStrategy(ACLSquidErrorStrategy const &); - -private: - static ACLSquidErrorStrategy Instance_; - ACLSquidErrorStrategy() {} - - ACLSquidErrorStrategy&operator=(ACLSquidErrorStrategy const &); -}; - -class ACLSquidError -{ - -private: - static ACL::Prototype RegistryProtoype; - static ACLStrategised RegistryEntry_; + virtual int match (ACLData * &, ACLFilledChecklist *) override; }; #endif /* SQUID_ACLSQUIDERROR_H */ diff -u -r -N squid-4.0.20/src/acl/SslError.cc squid-4.0.21/src/acl/SslError.cc --- squid-4.0.20/src/acl/SslError.cc 2017-06-02 00:49:17.000000000 +1200 +++ squid-4.0.21/src/acl/SslError.cc 2017-07-02 20:41:18.000000000 +1200 @@ -7,21 +7,13 @@ */ #include "squid.h" -#include "acl/Checklist.h" +#include "acl/FilledChecklist.h" #include "acl/SslError.h" #include "acl/SslErrorData.h" int -ACLSslErrorStrategy::match (ACLData * &data, ACLFilledChecklist *checklist, ACLFlags &) +ACLSslErrorStrategy::match (ACLData * &data, ACLFilledChecklist *checklist) { return data->match (checklist->sslErrors); } -ACLSslErrorStrategy * -ACLSslErrorStrategy::Instance() -{ - return &Instance_; -} - -ACLSslErrorStrategy ACLSslErrorStrategy::Instance_; - diff -u -r -N squid-4.0.20/src/acl/SslError.h squid-4.0.21/src/acl/SslError.h --- squid-4.0.20/src/acl/SslError.h 2017-06-02 00:49:17.000000000 +1200 +++ squid-4.0.21/src/acl/SslError.h 2017-07-02 20:41:18.000000000 +1200 @@ -9,33 +9,14 @@ #ifndef SQUID_ACLSSL_ERROR_H #define SQUID_ACLSSL_ERROR_H -#include "acl/Strategised.h" #include "acl/Strategy.h" +#include "security/forward.h" class ACLSslErrorStrategy : public ACLStrategy { public: - virtual int match (ACLData * &, ACLFilledChecklist *, ACLFlags &); - static ACLSslErrorStrategy *Instance(); - /* Not implemented to prevent copies of the instance. */ - /* Not private to prevent brain dead g+++ warnings about - * private constructors with no friends */ - ACLSslErrorStrategy(ACLSslErrorStrategy const &); - -private: - static ACLSslErrorStrategy Instance_; - ACLSslErrorStrategy() {} - - ACLSslErrorStrategy&operator=(ACLSslErrorStrategy const &); -}; - -class ACLSslError -{ - -private: - static ACL::Prototype RegistryProtoype; - static ACLStrategised RegistryEntry_; + virtual int match (ACLData * &, ACLFilledChecklist *) override; }; #endif /* SQUID_ACLSSL_ERROR_H */ diff -u -r -N squid-4.0.20/src/acl/Strategised.h squid-4.0.21/src/acl/Strategised.h --- squid-4.0.20/src/acl/Strategised.h 2017-06-02 00:49:17.000000000 +1200 +++ squid-4.0.21/src/acl/Strategised.h 2017-07-02 20:41:18.000000000 +1200 @@ -14,6 +14,16 @@ #include "acl/FilledChecklist.h" #include "acl/Strategy.h" +// XXX: Replace with a much simpler abstract ACL child class without the +// ACLStrategy parameter (and associated call forwarding). Duplicating key +// portions of the ACL class API in ACLStrategy is not needed because +// ACLStrategy is unused outside the ACLStrategised context. Existing classes +// like ACLExtUser, ACLProxyAuth, and ACLIdent seem to confirm this assertion. +// It also requires forwarding ACL info to ACLStrategy as method parameters. + +/// Splits the ACL API into two individually configurable components: +/// * ACLStrategy that usually extracts information from the current transaction +/// * ACLData that usually matches information against admin-configured values template class ACLStrategised : public ACL { @@ -23,24 +33,24 @@ typedef M MatchType; ~ACLStrategised(); - ACLStrategised(ACLData *, ACLStrategy *, char const *, const ACLFlag flags[] = ACLFlags::NoFlags); - ACLStrategised (ACLStrategised const &); - ACLStrategised &operator= (ACLStrategised const &); + ACLStrategised(ACLData *, ACLStrategy *, char const *); + ACLStrategised(ACLStrategised const &&) = delete; virtual char const *typeString() const; + virtual void parseFlags(); + virtual bool requiresRequest() const {return matcher->requiresRequest();} virtual bool requiresReply() const {return matcher->requiresReply();} virtual void prepareForUse() { data->prepareForUse();} - + virtual const Acl::Options &options() { return matcher->options(); } virtual void parse(); virtual int match(ACLChecklist *checklist); virtual int match (M const &); virtual SBufList dump() const; virtual bool empty () const; virtual bool valid () const; - virtual ACL *clone()const; private: ACLData *data; @@ -57,27 +67,21 @@ } template -ACLStrategised::ACLStrategised(ACLData *newData, ACLStrategy *theStrategy, char const *theType, const ACLFlag flgs[]) : ACL(flgs), data (newData), type_(theType), matcher(theStrategy) {} - -template -ACLStrategised::ACLStrategised (ACLStrategised const &old) : data (old.data->clone()), type_(old.type_), matcher (old.matcher) +ACLStrategised::ACLStrategised(ACLData *newData, ACLStrategy *theStrategy, char const *theType): data(newData), type_(theType), matcher(theStrategy) {} template -ACLStrategised & -ACLStrategised::operator= (ACLStrategised const &rhs) +char const * +ACLStrategised::typeString() const { - data = rhs.data->clone(); - type_ = rhs.type_; - matcher = rhs.matcher; - return *this; + return type_; } template -char const * -ACLStrategised::typeString() const +void +ACLStrategised::parseFlags() { - return type_; + ParseFlags(options(), data->supportedFlags()); } template @@ -100,7 +104,7 @@ { ACLFilledChecklist *checklist = dynamic_cast(cl); assert(checklist); - return matcher->match(data, checklist, flags); + return matcher->match(data, checklist); } template @@ -124,12 +128,5 @@ return matcher->valid(); } -template -ACL * -ACLStrategised::clone() const -{ - return new ACLStrategised(*this); -} - #endif /* SQUID_ACLSTRATEGISED_H */ diff -u -r -N squid-4.0.20/src/acl/Strategy.h squid-4.0.21/src/acl/Strategy.h --- squid-4.0.20/src/acl/Strategy.h 2017-06-02 00:49:17.000000000 +1200 +++ squid-4.0.21/src/acl/Strategy.h 2017-07-02 20:41:18.000000000 +1200 @@ -11,17 +11,22 @@ #include "acl/Acl.h" #include "acl/Data.h" +#include "acl/Options.h" class ACLFilledChecklist; template +/// A matching algorithm. class ACLStrategy { public: typedef M MatchType; - virtual int match (ACLData * &, ACLFilledChecklist *, ACLFlags &) = 0; + + /* Replicate ACL API parts relevant to the matching algorithm. */ + virtual const Acl::Options &options() { return Acl::NoOptions(); } + virtual int match (ACLData * &, ACLFilledChecklist *) = 0; virtual bool requiresRequest() const {return false;} virtual bool requiresReply() const {return false;} diff -u -r -N squid-4.0.20/src/acl/Tag.cc squid-4.0.21/src/acl/Tag.cc --- squid-4.0.20/src/acl/Tag.cc 2017-06-02 00:49:17.000000000 +1200 +++ squid-4.0.21/src/acl/Tag.cc 2017-07-02 20:41:18.000000000 +1200 @@ -7,24 +7,16 @@ */ #include "squid.h" -#include "acl/Checklist.h" +#include "acl/FilledChecklist.h" #include "acl/StringData.h" #include "acl/Tag.h" #include "HttpRequest.h" int -ACLTagStrategy::match (ACLData * &data, ACLFilledChecklist *checklist, ACLFlags &) +ACLTagStrategy::match (ACLData * &data, ACLFilledChecklist *checklist) { if (checklist->request != NULL) return data->match (checklist->request->tag.termedBuf()); return 0; } -ACLTagStrategy * -ACLTagStrategy::Instance() -{ - return &Instance_; -} - -ACLTagStrategy ACLTagStrategy::Instance_; - diff -u -r -N squid-4.0.20/src/acl/Tag.h squid-4.0.21/src/acl/Tag.h --- squid-4.0.20/src/acl/Tag.h 2017-06-02 00:49:17.000000000 +1200 +++ squid-4.0.21/src/acl/Tag.h 2017-07-02 20:41:18.000000000 +1200 @@ -9,33 +9,13 @@ #ifndef SQUID_ACLTAG_H #define SQUID_ACLTAG_H -#include "acl/Strategised.h" #include "acl/Strategy.h" class ACLTagStrategy : public ACLStrategy { public: - virtual int match (ACLData * &, ACLFilledChecklist *, ACLFlags &); - static ACLTagStrategy *Instance(); - /* Not implemented to prevent copies of the instance. */ - /* Not private to prevent brain dead g+++ warnings about - * private constructors with no friends */ - ACLTagStrategy(ACLTagStrategy const &); - -private: - static ACLTagStrategy Instance_; - ACLTagStrategy() {} - - ACLTagStrategy&operator=(ACLTagStrategy const &); -}; - -class ACLTag -{ - -private: - static ACL::Prototype RegistryProtoype; - static ACLStrategised RegistryEntry_; + virtual int match (ACLData * &, ACLFilledChecklist *) override; }; #endif /* SQUID_ACLMYPORTNAME_H */ diff -u -r -N squid-4.0.20/src/acl/Time.cc squid-4.0.21/src/acl/Time.cc --- squid-4.0.20/src/acl/Time.cc 2017-06-02 00:49:17.000000000 +1200 +++ squid-4.0.21/src/acl/Time.cc 2017-07-02 20:41:18.000000000 +1200 @@ -14,16 +14,8 @@ #include "SquidTime.h" int -ACLTimeStrategy::match(ACLData * &data, ACLFilledChecklist *, ACLFlags &) +ACLTimeStrategy::match(ACLData * &data, ACLFilledChecklist *) { return data->match(squid_curtime); } -ACLTimeStrategy * -ACLTimeStrategy::Instance() -{ - return &Instance_; -} - -ACLTimeStrategy ACLTimeStrategy::Instance_; - diff -u -r -N squid-4.0.20/src/acl/Time.h squid-4.0.21/src/acl/Time.h --- squid-4.0.20/src/acl/Time.h 2017-06-02 00:49:17.000000000 +1200 +++ squid-4.0.21/src/acl/Time.h 2017-07-02 20:41:18.000000000 +1200 @@ -8,36 +8,14 @@ #ifndef SQUID_ACLTIME_H #define SQUID_ACLTIME_H -#include "acl/Acl.h" #include "acl/Data.h" #include "acl/Strategised.h" -class ACLChecklist; // XXX: we do not need it - class ACLTimeStrategy : public ACLStrategy { public: - virtual int match (ACLData * &, ACLFilledChecklist *, ACLFlags &); - static ACLTimeStrategy *Instance(); - /* Not implemented to prevent copies of the instance. */ - /* Not private to prevent brain dead g+++ warnings about - * private constructors with no friends */ - ACLTimeStrategy(ACLTimeStrategy const &); - -private: - static ACLTimeStrategy Instance_; - ACLTimeStrategy() {} - - ACLTimeStrategy&operator=(ACLTimeStrategy const &); -}; - -class ACLTime -{ - -public: - static ACL::Prototype RegistryProtoype; - static ACLStrategised RegistryEntry_; + virtual int match (ACLData * &, ACLFilledChecklist *) override; }; #endif /* SQUID_ACLTIME_H */ diff -u -r -N squid-4.0.20/src/acl/TransactionInitiator.cc squid-4.0.21/src/acl/TransactionInitiator.cc --- squid-4.0.20/src/acl/TransactionInitiator.cc 1970-01-01 12:00:00.000000000 +1200 +++ squid-4.0.21/src/acl/TransactionInitiator.cc 2017-07-02 20:41:18.000000000 +1200 @@ -0,0 +1,65 @@ +/* + * Copyright (C) 1996-2017 The Squid Software Foundation and contributors + * + * Squid software is distributed under GPLv2+ license and includes + * contributions from numerous individuals and organizations. + * Please see the COPYING and CONTRIBUTORS files for details. + */ + +/* DEBUG: section 28 Access Control */ + +#include "squid.h" +#include "acl/FilledChecklist.h" +#include "acl/TransactionInitiator.h" +#include "cache_cf.h" +#include "Debug.h" +#include "HttpRequest.h" +#include "MasterXaction.h" +#include "SquidConfig.h" + +ACL * +Acl::TransactionInitiator::clone() const +{ + return new Acl::TransactionInitiator(*this); +} + +Acl::TransactionInitiator::TransactionInitiator (const char *aClass) : class_ (aClass), initiators_(0) +{} + +char const * +Acl::TransactionInitiator::typeString() const +{ + return class_; +} + +bool +Acl::TransactionInitiator::empty () const +{ + return false; +} + +void +Acl::TransactionInitiator::parse() +{ + while (const char *s = ConfigParser::strtokFile()) { + initiators_ |= XactionInitiator::ParseInitiators(s); + cfgWords.push_back(SBuf(s)); + } +} + +int +Acl::TransactionInitiator::match(ACLChecklist *checklist) +{ + ACLFilledChecklist *filled = Filled((ACLChecklist*)checklist); + assert(filled->request); + assert(filled->request->masterXaction); + const XactionInitiator requestInitiator = filled->request->masterXaction->initiator; + return requestInitiator.in(initiators_) ? 1 : 0; +} + +SBufList +Acl::TransactionInitiator::dump() const +{ + return cfgWords; +} + diff -u -r -N squid-4.0.20/src/acl/TransactionInitiator.h squid-4.0.21/src/acl/TransactionInitiator.h --- squid-4.0.20/src/acl/TransactionInitiator.h 1970-01-01 12:00:00.000000000 +1200 +++ squid-4.0.21/src/acl/TransactionInitiator.h 2017-07-02 20:41:18.000000000 +1200 @@ -0,0 +1,44 @@ +/* + * Copyright (C) 1996-2017 The Squid Software Foundation and contributors + * + * Squid software is distributed under GPLv2+ license and includes + * contributions from numerous individuals and organizations. + * Please see the COPYING and CONTRIBUTORS files for details. + */ + +#ifndef SQUID_ACL_TRANSACTION_INITIATOR_H +#define SQUID_ACL_TRANSACTION_INITIATOR_H + +#include "acl/Acl.h" +#include "acl/Checklist.h" +#include "XactionInitiator.h" + +namespace Acl +{ + +/// transaction_initiator ACL +class TransactionInitiator : public ACL +{ + MEMPROXY_CLASS(TransactionInitiator); + +public: + TransactionInitiator(char const *); + + virtual ACL *clone()const; + virtual char const *typeString() const; + virtual void parse(); + virtual int match(ACLChecklist *checklist); + virtual bool requiresRequest() const { return true; } + virtual SBufList dump() const; + virtual bool empty () const; + +protected: + char const *class_; + XactionInitiator::Initiators initiators_; + SBufList cfgWords; /// initiator names in the configured order +}; + +} // namespace Acl + +#endif /* SQUID_ACL_TRANSACTION_INITIATOR_H */ + diff -u -r -N squid-4.0.20/src/acl/Tree.h squid-4.0.21/src/acl/Tree.h --- squid-4.0.20/src/acl/Tree.h 2017-06-02 00:49:17.000000000 +1200 +++ squid-4.0.21/src/acl/Tree.h 2017-07-02 20:41:18.000000000 +1200 @@ -52,7 +52,7 @@ inline const char * AllowOrDeny(const allow_t &action) { - return action == ACCESS_ALLOWED ? "allow" : "deny"; + return action.allowed() ? "allow" : "deny"; } template diff -u -r -N squid-4.0.20/src/acl/Url.cc squid-4.0.21/src/acl/Url.cc --- squid-4.0.20/src/acl/Url.cc 2017-06-02 00:49:17.000000000 +1200 +++ squid-4.0.21/src/acl/Url.cc 2017-07-02 20:41:18.000000000 +1200 @@ -9,7 +9,7 @@ /* DEBUG: section 28 Access Control */ #include "squid.h" -#include "acl/Checklist.h" +#include "acl/FilledChecklist.h" #include "acl/RegexData.h" #include "acl/Url.h" #include "HttpRequest.h" @@ -17,7 +17,7 @@ #include "src/URL.h" int -ACLUrlStrategy::match (ACLData * &data, ACLFilledChecklist *checklist, ACLFlags &) +ACLUrlStrategy::match (ACLData * &data, ACLFilledChecklist *checklist) { char *esc_buf = SBufToCstring(checklist->request->effectiveRequestUri()); rfc1738_unescape(esc_buf); @@ -26,11 +26,3 @@ return result; } -ACLUrlStrategy * -ACLUrlStrategy::Instance() -{ - return &Instance_; -} - -ACLUrlStrategy ACLUrlStrategy::Instance_; - diff -u -r -N squid-4.0.20/src/acl/Url.h squid-4.0.21/src/acl/Url.h --- squid-4.0.20/src/acl/Url.h 2017-06-02 00:49:17.000000000 +1200 +++ squid-4.0.21/src/acl/Url.h 2017-07-02 20:41:18.000000000 +1200 @@ -8,7 +8,7 @@ #ifndef SQUID_ACLURL_H #define SQUID_ACLURL_H -#include "acl/Acl.h" + #include "acl/Data.h" #include "acl/Strategised.h" @@ -16,29 +16,8 @@ { public: - virtual int match (ACLData * &, ACLFilledChecklist *, ACLFlags &); + virtual int match (ACLData * &, ACLFilledChecklist *); virtual bool requiresRequest() const {return true;} - - static ACLUrlStrategy *Instance(); - /* Not implemented to prevent copies of the instance. */ - /* Not private to prevent brain dead g+++ warnings about - * private constructors with no friends */ - ACLUrlStrategy(ACLUrlStrategy const &); - -private: - static ACLUrlStrategy Instance_; - ACLUrlStrategy() {} - - ACLUrlStrategy&operator=(ACLUrlStrategy const &); -}; - -class ACLUrl -{ - -public: - static ACL::Prototype RegistryProtoype; - static ACL::Prototype LegacyRegistryProtoype; - static ACLStrategised RegistryEntry_; }; #endif /* SQUID_ACLURL_H */ diff -u -r -N squid-4.0.20/src/acl/UrlLogin.cc squid-4.0.21/src/acl/UrlLogin.cc --- squid-4.0.20/src/acl/UrlLogin.cc 2017-06-02 00:49:17.000000000 +1200 +++ squid-4.0.21/src/acl/UrlLogin.cc 2017-07-02 20:41:18.000000000 +1200 @@ -9,14 +9,14 @@ /* DEBUG: section 28 Access Control */ #include "squid.h" -#include "acl/Checklist.h" +#include "acl/FilledChecklist.h" #include "acl/RegexData.h" #include "acl/UrlLogin.h" #include "HttpRequest.h" #include "rfc1738.h" int -ACLUrlLoginStrategy::match(ACLData * &data, ACLFilledChecklist *checklist, ACLFlags &) +ACLUrlLoginStrategy::match(ACLData * &data, ACLFilledChecklist *checklist) { if (checklist->request->url.userInfo().isEmpty()) { debugs(28, 5, "URL has no user-info details. cannot match"); @@ -31,11 +31,3 @@ return data->match(str); } -ACLUrlLoginStrategy * -ACLUrlLoginStrategy::Instance() -{ - return &Instance_; -} - -ACLUrlLoginStrategy ACLUrlLoginStrategy::Instance_; - diff -u -r -N squid-4.0.20/src/acl/UrlLogin.h squid-4.0.21/src/acl/UrlLogin.h --- squid-4.0.20/src/acl/UrlLogin.h 2017-06-02 00:49:17.000000000 +1200 +++ squid-4.0.21/src/acl/UrlLogin.h 2017-07-02 20:41:18.000000000 +1200 @@ -11,36 +11,14 @@ #include "acl/Acl.h" #include "acl/Data.h" -#include "acl/Strategised.h" #include "acl/Strategy.h" class ACLUrlLoginStrategy : public ACLStrategy { public: - virtual int match (ACLData * &, ACLFilledChecklist *, ACLFlags &); + virtual int match (ACLData * &, ACLFilledChecklist *); virtual bool requiresRequest() const {return true;} - - static ACLUrlLoginStrategy *Instance(); - /* Not implemented to prevent copies of the instance. */ - /* Not private to prevent brain dead g+++ warnings about - * private constructors with no friends */ - ACLUrlLoginStrategy(ACLUrlLoginStrategy const &); - -private: - static ACLUrlLoginStrategy Instance_; - ACLUrlLoginStrategy() {} - - ACLUrlLoginStrategy&operator=(ACLUrlLoginStrategy const &); -}; - -class ACLUrlLogin -{ - -public: - static ACL::Prototype RegistryProtoype; - static ACL::Prototype LegacyRegistryProtoype; - static ACLStrategised RegistryEntry_; }; #endif /* SQUID_ACLURLLOGIN_H */ diff -u -r -N squid-4.0.20/src/acl/UrlPath.cc squid-4.0.21/src/acl/UrlPath.cc --- squid-4.0.20/src/acl/UrlPath.cc 2017-06-02 00:49:17.000000000 +1200 +++ squid-4.0.21/src/acl/UrlPath.cc 2017-07-02 20:41:18.000000000 +1200 @@ -9,14 +9,14 @@ /* DEBUG: section 28 Access Control */ #include "squid.h" -#include "acl/Checklist.h" +#include "acl/FilledChecklist.h" #include "acl/RegexData.h" #include "acl/UrlPath.h" #include "HttpRequest.h" #include "rfc1738.h" int -ACLUrlPathStrategy::match (ACLData * &data, ACLFilledChecklist *checklist, ACLFlags &) +ACLUrlPathStrategy::match (ACLData * &data, ACLFilledChecklist *checklist) { if (checklist->request->url.path().isEmpty()) return -1; @@ -28,11 +28,3 @@ return result; } -ACLUrlPathStrategy * -ACLUrlPathStrategy::Instance() -{ - return &Instance_; -} - -ACLUrlPathStrategy ACLUrlPathStrategy::Instance_; - diff -u -r -N squid-4.0.20/src/acl/UrlPath.h squid-4.0.21/src/acl/UrlPath.h --- squid-4.0.20/src/acl/UrlPath.h 2017-06-02 00:49:17.000000000 +1200 +++ squid-4.0.21/src/acl/UrlPath.h 2017-07-02 20:41:18.000000000 +1200 @@ -8,38 +8,15 @@ #ifndef SQUID_ACLURLPATH_H #define SQUID_ACLURLPATH_H -#include "acl/Acl.h" -#include "acl/Data.h" -#include "acl/Strategised.h" + #include "acl/Strategy.h" class ACLUrlPathStrategy : public ACLStrategy { public: - virtual int match (ACLData * &, ACLFilledChecklist *, ACLFlags &); + virtual int match (ACLData * &, ACLFilledChecklist *); virtual bool requiresRequest() const {return true;} - - static ACLUrlPathStrategy *Instance(); - /* Not implemented to prevent copies of the instance. */ - /* Not private to prevent brain dead g+++ warnings about - * private constructors with no friends */ - ACLUrlPathStrategy(ACLUrlPathStrategy const &); - -private: - static ACLUrlPathStrategy Instance_; - ACLUrlPathStrategy() {} - - ACLUrlPathStrategy&operator=(ACLUrlPathStrategy const &); -}; - -class ACLUrlPath -{ - -public: - static ACL::Prototype RegistryProtoype; - static ACL::Prototype LegacyRegistryProtoype; - static ACLStrategised RegistryEntry_; }; #endif /* SQUID_ACLURLPATH_H */ diff -u -r -N squid-4.0.20/src/acl/UrlPort.cc squid-4.0.21/src/acl/UrlPort.cc --- squid-4.0.20/src/acl/UrlPort.cc 2017-06-02 00:49:17.000000000 +1200 +++ squid-4.0.21/src/acl/UrlPort.cc 2017-07-02 20:41:18.000000000 +1200 @@ -7,22 +7,13 @@ */ #include "squid.h" -#include "acl/Checklist.h" -#include "acl/IntRange.h" +#include "acl/FilledChecklist.h" #include "acl/UrlPort.h" #include "HttpRequest.h" int -ACLUrlPortStrategy::match(ACLData * &data, ACLFilledChecklist *checklist, ACLFlags &) +ACLUrlPortStrategy::match(ACLData * &data, ACLFilledChecklist *checklist) { return data->match(checklist->request->url.port()); } -ACLUrlPortStrategy * -ACLUrlPortStrategy::Instance() -{ - return &Instance_; -} - -ACLUrlPortStrategy ACLUrlPortStrategy::Instance_; - diff -u -r -N squid-4.0.20/src/acl/UrlPort.h squid-4.0.21/src/acl/UrlPort.h --- squid-4.0.20/src/acl/UrlPort.h 2017-06-02 00:49:17.000000000 +1200 +++ squid-4.0.21/src/acl/UrlPort.h 2017-07-02 20:41:18.000000000 +1200 @@ -8,35 +8,15 @@ #ifndef SQUID_ACLURLPORT_H #define SQUID_ACLURLPORT_H -#include "acl/Strategised.h" + #include "acl/Strategy.h" class ACLUrlPortStrategy : public ACLStrategy { public: - virtual int match (ACLData * &, ACLFilledChecklist *, ACLFlags &); + virtual int match (ACLData * &, ACLFilledChecklist *); virtual bool requiresRequest() const {return true;} - - static ACLUrlPortStrategy *Instance(); - /* Not implemented to prevent copies of the instance. */ - /* Not private to prevent brain dead g+++ warnings about - * private constructors with no friends */ - ACLUrlPortStrategy(ACLUrlPortStrategy const &); - -private: - static ACLUrlPortStrategy Instance_; - ACLUrlPortStrategy() {} - - ACLUrlPortStrategy&operator=(ACLUrlPortStrategy const &); -}; - -class ACLUrlPort -{ - -private: - static ACL::Prototype RegistryProtoype; - static ACLStrategised RegistryEntry_; }; #endif /* SQUID_ACLURLPORT_H */ diff -u -r -N squid-4.0.20/src/AclRegs.cc squid-4.0.21/src/AclRegs.cc --- squid-4.0.20/src/AclRegs.cc 2017-06-02 00:49:17.000000000 +1200 +++ squid-4.0.21/src/AclRegs.cc 2017-07-02 20:41:18.000000000 +1200 @@ -8,11 +8,6 @@ #include "squid.h" -/** This file exists to provide satic registration code to executables - that need ACLs. We cannot place this code in acl/lib*.la because it - does not get linked in, because nobody is using these classes by name. -*/ - #if USE_ADAPTATION #include "acl/AdaptationService.h" #include "acl/AdaptationServiceData.h" @@ -28,7 +23,6 @@ #include "acl/AtStepData.h" #endif #include "acl/Asn.h" -#include "acl/Browser.h" #include "acl/Checklist.h" #include "acl/ConnectionsEncrypted.h" #include "acl/Data.h" @@ -40,6 +34,7 @@ #include "acl/ExtUser.h" #endif #include "acl/FilledChecklist.h" +#include "acl/forward.h" #include "acl/Gadgets.h" #include "acl/HasComponent.h" #include "acl/HasComponentData.h" @@ -63,7 +58,6 @@ #include "acl/Protocol.h" #include "acl/ProtocolData.h" #include "acl/Random.h" -#include "acl/Referer.h" #include "acl/RegexData.h" #include "acl/ReplyHeaderStrategy.h" #include "acl/ReplyMimeType.h" @@ -90,6 +84,7 @@ #include "acl/Tag.h" #include "acl/Time.h" #include "acl/TimeData.h" +#include "acl/TransactionInitiator.h" #include "acl/Url.h" #include "acl/UrlLogin.h" #include "acl/UrlPath.h" @@ -100,143 +95,98 @@ #include "auth/AclProxyAuth.h" #endif #include "base/RegexPattern.h" +#include "ExternalACL.h" #if USE_IDENT #include "ident/AclIdent.h" #endif +#if SQUID_SNMP +#include "snmp_core.h" +#endif -ACL::Prototype ACLBrowser::RegistryProtoype(&ACLBrowser::RegistryEntry_, "browser"); -ACLStrategised ACLBrowser::RegistryEntry_(new ACLRegexData, ACLRequestHeaderStrategy::Instance(), "browser"); -ACLFlag DestinationDomainFlags[] = {ACL_F_NO_LOOKUP, ACL_F_END}; -ACL::Prototype ACLDestinationDomain::LiteralRegistryProtoype(&ACLDestinationDomain::LiteralRegistryEntry_, "dstdomain"); -ACLStrategised ACLDestinationDomain::LiteralRegistryEntry_(new ACLDomainData, ACLDestinationDomainStrategy::Instance(), "dstdomain", DestinationDomainFlags); -ACL::Prototype ACLDestinationDomain::RegexRegistryProtoype(&ACLDestinationDomain::RegexRegistryEntry_, "dstdom_regex"); -ACLFlag DestinationDomainRegexFlags[] = {ACL_F_NO_LOOKUP, ACL_F_REGEX_CASE, ACL_F_END}; -ACLStrategised ACLDestinationDomain::RegexRegistryEntry_(new ACLRegexData,ACLDestinationDomainStrategy::Instance() ,"dstdom_regex", DestinationDomainRegexFlags); -ACL::Prototype ACLDestinationIP::RegistryProtoype(&ACLDestinationIP::RegistryEntry_, "dst"); -ACLDestinationIP ACLDestinationIP::RegistryEntry_; -#if USE_AUTH -ACL::Prototype ACLExtUser::UserRegistryProtoype(&ACLExtUser::UserRegistryEntry_, "ext_user"); -ACLExtUser ACLExtUser::UserRegistryEntry_(new ACLUserData, "ext_user"); -ACL::Prototype ACLExtUser::RegexRegistryProtoype(&ACLExtUser::RegexRegistryEntry_, "ext_user_regex" ); -ACLExtUser ACLExtUser::RegexRegistryEntry_(new ACLRegexData, "ext_user_regex"); -#endif -ACL::Prototype ACLHierCode::RegistryProtoype(&ACLHierCode::RegistryEntry_, "hier_code"); -ACLStrategised ACLHierCode::RegistryEntry_(new ACLHierCodeData, ACLHierCodeStrategy::Instance(), "hier_code"); -ACL::Prototype ACLHTTPRepHeader::RegistryProtoype(&ACLHTTPRepHeader::RegistryEntry_, "rep_header"); -ACLStrategised ACLHTTPRepHeader::RegistryEntry_(new ACLHTTPHeaderData, ACLHTTPRepHeaderStrategy::Instance(), "rep_header"); -ACL::Prototype ACLHTTPReqHeader::RegistryProtoype(&ACLHTTPReqHeader::RegistryEntry_, "req_header"); -ACLStrategised ACLHTTPReqHeader::RegistryEntry_(new ACLHTTPHeaderData, ACLHTTPReqHeaderStrategy::Instance(), "req_header"); -ACL::Prototype ACLHTTPStatus::RegistryProtoype(&ACLHTTPStatus::RegistryEntry_, "http_status"); -ACLHTTPStatus ACLHTTPStatus::RegistryEntry_("http_status"); -ACL::Prototype ACLMaxConnection::RegistryProtoype(&ACLMaxConnection::RegistryEntry_, "maxconn"); -ACLMaxConnection ACLMaxConnection::RegistryEntry_("maxconn"); -ACL::Prototype ACLMethod::RegistryProtoype(&ACLMethod::RegistryEntry_, "method"); -ACLStrategised ACLMethod::RegistryEntry_(new ACLMethodData, ACLMethodStrategy::Instance(), "method"); -ACL::Prototype ACLLocalIP::RegistryProtoype(&ACLLocalIP::RegistryEntry_, "localip"); -ACLLocalIP ACLLocalIP::RegistryEntry_; -ACL::Prototype ACLLocalPort::RegistryProtoype(&ACLLocalPort::RegistryEntry_, "localport"); -ACLStrategised ACLLocalPort::RegistryEntry_(new ACLIntRange, ACLLocalPortStrategy::Instance(), "localport"); -ACL::Prototype ACLMyPortName::RegistryProtoype(&ACLMyPortName::RegistryEntry_, "myportname"); -ACLStrategised ACLMyPortName::RegistryEntry_(new ACLStringData, ACLMyPortNameStrategy::Instance(), "myportname"); -ACL::Prototype ACLPeerName::RegistryProtoype(&ACLPeerName::RegistryEntry_, "peername"); -ACLStrategised ACLPeerName::RegistryEntry_(new ACLStringData, ACLPeerNameStrategy::Instance(), "peername"); -ACL::Prototype ACLPeerName::RegexRegistryProtoype(&ACLPeerName::RegexRegistryEntry_, "peername_regex"); -ACLStrategised ACLPeerName::RegexRegistryEntry_(new ACLRegexData, ACLPeerNameStrategy::Instance(), "peername_regex"); -ACL::Prototype ACLProtocol::RegistryProtoype(&ACLProtocol::RegistryEntry_, "proto"); -ACLStrategised ACLProtocol::RegistryEntry_(new ACLProtocolData, ACLProtocolStrategy::Instance(), "proto"); -ACL::Prototype ACLRandom::RegistryProtoype(&ACLRandom::RegistryEntry_, "random"); -ACLRandom ACLRandom::RegistryEntry_("random"); -ACL::Prototype ACLReferer::RegistryProtoype(&ACLReferer::RegistryEntry_, "referer_regex"); -ACLStrategised ACLReferer::RegistryEntry_(new ACLRegexData, ACLRequestHeaderStrategy::Instance(), "referer_regex"); -ACL::Prototype ACLReplyMIMEType::RegistryProtoype(&ACLReplyMIMEType::RegistryEntry_, "rep_mime_type"); -ACLStrategised ACLReplyMIMEType::RegistryEntry_(new ACLRegexData, ACLReplyHeaderStrategy::Instance(), "rep_mime_type"); -ACL::Prototype ACLRequestMIMEType::RegistryProtoype(&ACLRequestMIMEType::RegistryEntry_, "req_mime_type"); -ACLStrategised ACLRequestMIMEType::RegistryEntry_(new ACLRegexData, ACLRequestHeaderStrategy::Instance(), "req_mime_type"); -ACL::Prototype ACLSourceDomain::LiteralRegistryProtoype(&ACLSourceDomain::LiteralRegistryEntry_, "srcdomain"); -ACLStrategised ACLSourceDomain::LiteralRegistryEntry_(new ACLDomainData, ACLSourceDomainStrategy::Instance(), "srcdomain"); -ACL::Prototype ACLSourceDomain::RegexRegistryProtoype(&ACLSourceDomain::RegexRegistryEntry_, "srcdom_regex"); -ACLStrategised ACLSourceDomain::RegexRegistryEntry_(new ACLRegexData,ACLSourceDomainStrategy::Instance() ,"srcdom_regex"); -ACL::Prototype ACLSourceIP::RegistryProtoype(&ACLSourceIP::RegistryEntry_, "src"); -ACLSourceIP ACLSourceIP::RegistryEntry_; -ACL::Prototype ACLTime::RegistryProtoype(&ACLTime::RegistryEntry_, "time"); -ACLStrategised ACLTime::RegistryEntry_(new ACLTimeData, ACLTimeStrategy::Instance(), "time"); -ACL::Prototype ACLUrl::RegistryProtoype(&ACLUrl::RegistryEntry_, "url_regex"); -ACLStrategised ACLUrl::RegistryEntry_(new ACLRegexData, ACLUrlStrategy::Instance(), "url_regex"); -ACL::Prototype ACLUrlLogin::RegistryProtoype(&ACLUrlLogin::RegistryEntry_, "urllogin"); -ACLStrategised ACLUrlLogin::RegistryEntry_(new ACLRegexData, ACLUrlLoginStrategy::Instance(), "urllogin"); -ACL::Prototype ACLUrlPath::LegacyRegistryProtoype(&ACLUrlPath::RegistryEntry_, "pattern"); -ACL::Prototype ACLUrlPath::RegistryProtoype(&ACLUrlPath::RegistryEntry_, "urlpath_regex"); -ACLStrategised ACLUrlPath::RegistryEntry_(new ACLRegexData, ACLUrlPathStrategy::Instance(), "urlpath_regex"); -ACL::Prototype ACLUrlPort::RegistryProtoype(&ACLUrlPort::RegistryEntry_, "port"); -ACLStrategised ACLUrlPort::RegistryEntry_(new ACLIntRange, ACLUrlPortStrategy::Instance(), "port"); +// Not in src/acl/ because some of the ACLs it registers are not in src/acl/. +void +Acl::Init() +{ + /* the registration order does not matter */ + + // The explicit return type (ACL*) for lambdas is needed because the type + // of the return expression inside lambda is not ACL* but AclFoo* while + // Acl::Maker is defined to return ACL*. + + RegisterMaker("all-of", [](TypeName)->ACL* { return new Acl::AllOf; }); // XXX: Add name parameter to ctor + RegisterMaker("any-of", [](TypeName)->ACL* { return new Acl::AnyOf; }); // XXX: Add name parameter to ctor + RegisterMaker("random", [](TypeName name)->ACL* { return new ACLRandom(name); }); + RegisterMaker("time", [](TypeName name)->ACL* { return new ACLStrategised(new ACLTimeData, new ACLTimeStrategy, name); }); + RegisterMaker("src_as", [](TypeName name)->ACL* { return new ACLStrategised(new ACLASN, new ACLSourceASNStrategy, name); }); + RegisterMaker("dst_as", [](TypeName name)->ACL* { return new ACLStrategised(new ACLASN, new ACLDestinationASNStrategy, name); }); + RegisterMaker("browser", [](TypeName name)->ACL* { return new ACLStrategised(new ACLRegexData, new ACLRequestHeaderStrategy, name); }); + RegisterMaker("dstdomain", [](TypeName name)->ACL* { return new ACLStrategised(new ACLDomainData, new ACLDestinationDomainStrategy, name); }); + RegisterMaker("dstdom_regex", [](TypeName name)->ACL* { return new ACLStrategised(new ACLRegexData, new ACLDestinationDomainStrategy , name); }); + RegisterMaker("dst", [](TypeName)->ACL* { return new ACLDestinationIP; }); // XXX: Add name parameter to ctor + RegisterMaker("hier_code", [](TypeName name)->ACL* { return new ACLStrategised(new ACLHierCodeData, new ACLHierCodeStrategy, name); }); + RegisterMaker("rep_header", [](TypeName name)->ACL* { return new ACLStrategised(new ACLHTTPHeaderData, new ACLHTTPRepHeaderStrategy, name); }); + RegisterMaker("req_header", [](TypeName name)->ACL* { return new ACLStrategised(new ACLHTTPHeaderData, new ACLHTTPReqHeaderStrategy, name); }); + RegisterMaker("http_status", [](TypeName name)->ACL* { return new ACLHTTPStatus(name); }); + RegisterMaker("maxconn", [](TypeName name)->ACL* { return new ACLMaxConnection(name); }); + RegisterMaker("method", [](TypeName name)->ACL* { return new ACLStrategised(new ACLMethodData, new ACLMethodStrategy, name); }); + RegisterMaker("localip", [](TypeName)->ACL* { return new ACLLocalIP; }); // XXX: Add name parameter to ctor + RegisterMaker("localport", [](TypeName name)->ACL* { return new ACLStrategised(new ACLIntRange, new ACLLocalPortStrategy, name); }); + RegisterMaker("myportname", [](TypeName name)->ACL* { return new ACLStrategised(new ACLStringData, new ACLMyPortNameStrategy, name); }); + RegisterMaker("peername", [](TypeName name)->ACL* { return new ACLStrategised(new ACLStringData, new ACLPeerNameStrategy, name); }); + RegisterMaker("peername_regex", [](TypeName name)->ACL* { return new ACLStrategised(new ACLRegexData, new ACLPeerNameStrategy, name); }); + RegisterMaker("proto", [](TypeName name)->ACL* { return new ACLStrategised(new ACLProtocolData, new ACLProtocolStrategy, name); }); + RegisterMaker("referer_regex", [](TypeName name)->ACL* { return new ACLStrategised(new ACLRegexData, new ACLRequestHeaderStrategy, name); }); + RegisterMaker("rep_mime_type", [](TypeName name)->ACL* { return new ACLStrategised(new ACLRegexData, new ACLReplyHeaderStrategy, name); }); + RegisterMaker("req_mime_type", [](TypeName name)->ACL* { return new ACLStrategised(new ACLRegexData, new ACLRequestHeaderStrategy, name); }); + RegisterMaker("srcdomain", [](TypeName name)->ACL* { return new ACLStrategised(new ACLDomainData, new ACLSourceDomainStrategy, name); }); + RegisterMaker("srcdom_regex", [](TypeName name)->ACL* { return new ACLStrategised(new ACLRegexData, new ACLSourceDomainStrategy, name); }); + RegisterMaker("src", [](TypeName)->ACL* { return new ACLSourceIP; }); // XXX: Add name parameter to ctor + RegisterMaker("url_regex", [](TypeName name)->ACL* { return new ACLStrategised(new ACLRegexData, new ACLUrlStrategy, name); }); + RegisterMaker("urllogin", [](TypeName name)->ACL* { return new ACLStrategised(new ACLRegexData, new ACLUrlLoginStrategy, name); }); + RegisterMaker("urlpath_regex", [](TypeName name)->ACL* { return new ACLStrategised(new ACLRegexData, new ACLUrlPathStrategy, name); }); + RegisterMaker("port", [](TypeName name)->ACL* { return new ACLStrategised(new ACLIntRange, new ACLUrlPortStrategy, name); }); + RegisterMaker("external", [](TypeName name)->ACL* { return new ACLExternal(name); }); + RegisterMaker("squid_error", [](TypeName name)->ACL* { return new ACLStrategised(new ACLSquidErrorData, new ACLSquidErrorStrategy, name); }); + RegisterMaker("connections_encrypted", [](TypeName name)->ACL* { return new Acl::ConnectionsEncrypted(name); }); + RegisterMaker("tag", [](TypeName name)->ACL* { return new ACLStrategised(new ACLStringData, new ACLTagStrategy, name); }); + RegisterMaker("note", [](TypeName name)->ACL* { return new ACLStrategised(new ACLNoteData, new ACLNoteStrategy, name); }); + RegisterMaker("has", [](TypeName name)->ACL* {return new ACLStrategised(new ACLHasComponentData, new ACLHasComponentStrategy, name); }); + RegisterMaker("transaction_initiator", [](TypeName name)->ACL* {return new Acl::TransactionInitiator(name);}); #if USE_OPENSSL -ACL::Prototype ACLSslError::RegistryProtoype(&ACLSslError::RegistryEntry_, "ssl_error"); -ACLStrategised ACLSslError::RegistryEntry_(new ACLSslErrorData, ACLSslErrorStrategy::Instance(), "ssl_error"); -ACL::Prototype ACLCertificate::UserRegistryProtoype(&ACLCertificate::UserRegistryEntry_, "user_cert"); -ACLStrategised ACLCertificate::UserRegistryEntry_(new ACLCertificateData (Ssl::GetX509UserAttribute, "*"), ACLCertificateStrategy::Instance(), "user_cert"); -ACL::Prototype ACLCertificate::CARegistryProtoype(&ACLCertificate::CARegistryEntry_, "ca_cert"); -ACLStrategised ACLCertificate::CARegistryEntry_(new ACLCertificateData (Ssl::GetX509CAAttribute, "*"), ACLCertificateStrategy::Instance(), "ca_cert"); -ACL::Prototype ACLServerCertificate::X509FingerprintRegistryProtoype(&ACLServerCertificate::X509FingerprintRegistryEntry_, "server_cert_fingerprint"); -ACLStrategised ACLServerCertificate::X509FingerprintRegistryEntry_(new ACLCertificateData(Ssl::GetX509Fingerprint, "-sha1", true), ACLServerCertificateStrategy::Instance(), "server_cert_fingerprint"); - -ACL::Prototype ACLAtStep::RegistryProtoype(&ACLAtStep::RegistryEntry_, "at_step"); -ACLStrategised ACLAtStep::RegistryEntry_(new ACLAtStepData, ACLAtStepStrategy::Instance(), "at_step"); - -ACL::Prototype ACLServerName::LiteralRegistryProtoype(&ACLServerName::LiteralRegistryEntry_, "ssl::server_name"); -ACLStrategised ACLServerName::LiteralRegistryEntry_(new ACLServerNameData, ACLServerNameStrategy::Instance(), "ssl::server_name"); -ACL::Prototype ACLServerName::RegexRegistryProtoype(&ACLServerName::RegexRegistryEntry_, "ssl::server_name_regex"); -ACLFlag ServerNameRegexFlags[] = {ACL_F_REGEX_CASE, ACL_F_END}; -ACLStrategised ACLServerName::RegexRegistryEntry_(new ACLRegexData, ACLServerNameStrategy::Instance(), "ssl::server_name_regex", ServerNameRegexFlags); + RegisterMaker("ssl_error", [](TypeName name)->ACL* { return new ACLStrategised(new ACLSslErrorData, new ACLSslErrorStrategy, name); }); + RegisterMaker("user_cert", [](TypeName name)->ACL* { return new ACLStrategised(new ACLCertificateData(Ssl::GetX509UserAttribute, "*"), new ACLCertificateStrategy, name); }); + RegisterMaker("ca_cert", [](TypeName name)->ACL* { return new ACLStrategised(new ACLCertificateData(Ssl::GetX509CAAttribute, "*"), new ACLCertificateStrategy, name); }); + RegisterMaker("server_cert_fingerprint", [](TypeName name)->ACL* { return new ACLStrategised(new ACLCertificateData(Ssl::GetX509Fingerprint, "-sha1", true), new ACLServerCertificateStrategy, name); }); + RegisterMaker("at_step", [](TypeName name)->ACL* { return new ACLStrategised(new ACLAtStepData, new ACLAtStepStrategy, name); }); + RegisterMaker("ssl::server_name", [](TypeName name)->ACL* { return new ACLStrategised(new ACLServerNameData, new ACLServerNameStrategy, name); }); + RegisterMaker("ssl::server_name_regex", [](TypeName name)->ACL* { return new ACLStrategised(new ACLRegexData, new ACLServerNameStrategy, name); }); #endif #if USE_SQUID_EUI -ACL::Prototype ACLARP::RegistryProtoype(&ACLARP::RegistryEntry_, "arp"); -ACLARP ACLARP::RegistryEntry_("arp"); -ACL::Prototype ACLEui64::RegistryProtoype(&ACLEui64::RegistryEntry_, "eui64"); -ACLEui64 ACLEui64::RegistryEntry_("eui64"); + RegisterMaker("arp", [](TypeName name)->ACL* { return new ACLARP(name); }); + RegisterMaker("eui64", [](TypeName name)->ACL* { return new ACLEui64(name); }); #endif #if USE_IDENT -ACL::Prototype ACLIdent::UserRegistryProtoype(&ACLIdent::UserRegistryEntry_, "ident"); -ACLIdent ACLIdent::UserRegistryEntry_(new ACLUserData, "ident"); -ACL::Prototype ACLIdent::RegexRegistryProtoype(&ACLIdent::RegexRegistryEntry_, "ident_regex" ); -ACLIdent ACLIdent::RegexRegistryEntry_(new ACLRegexData, "ident_regex"); + RegisterMaker("ident", [](TypeName name)->ACL* { return new ACLIdent(new ACLUserData, name); }); + RegisterMaker("ident_regex", [](TypeName name)->ACL* { return new ACLIdent(new ACLRegexData, name); }); #endif #if USE_AUTH -ACL::Prototype ACLProxyAuth::UserRegistryProtoype(&ACLProxyAuth::UserRegistryEntry_, "proxy_auth"); -ACLProxyAuth ACLProxyAuth::UserRegistryEntry_(new ACLUserData, "proxy_auth"); -ACL::Prototype ACLProxyAuth::RegexRegistryProtoype(&ACLProxyAuth::RegexRegistryEntry_, "proxy_auth_regex" ); -ACLProxyAuth ACLProxyAuth::RegexRegistryEntry_(new ACLRegexData, "proxy_auth_regex"); - -ACL::Prototype ACLMaxUserIP::RegistryProtoype(&ACLMaxUserIP::RegistryEntry_, "max_user_ip"); -ACLMaxUserIP ACLMaxUserIP::RegistryEntry_("max_user_ip"); + RegisterMaker("ext_user", [](TypeName name)->ACL* { return new ACLExtUser(new ACLUserData, name); }); + RegisterMaker("ext_user_regex", [](TypeName name)->ACL* { return new ACLExtUser(new ACLRegexData, name); }); + RegisterMaker("proxy_auth", [](TypeName name)->ACL* { return new ACLProxyAuth(new ACLUserData, name); }); + RegisterMaker("proxy_auth_regex", [](TypeName name)->ACL* { return new ACLProxyAuth(new ACLRegexData, name); }); + RegisterMaker("max_user_ip", [](TypeName name)->ACL* { return new ACLMaxUserIP(name); }); #endif -ACL::Prototype ACLTag::RegistryProtoype(&ACLTag::RegistryEntry_, "tag"); -ACLStrategised ACLTag::RegistryEntry_(new ACLStringData, ACLTagStrategy::Instance(), "tag"); - -ACL::Prototype Acl::AnyOf::RegistryProtoype(&Acl::AnyOf::RegistryEntry_, "any-of"); -Acl::AnyOf Acl::AnyOf::RegistryEntry_; - -ACL::Prototype Acl::AllOf::RegistryProtoype(&Acl::AllOf::RegistryEntry_, "all-of"); -Acl::AllOf Acl::AllOf::RegistryEntry_; - -ACL::Prototype ACLNote::RegistryProtoype(&ACLNote::RegistryEntry_, "note"); -ACLStrategised ACLNote::RegistryEntry_(new ACLNoteData, ACLNoteStrategy::Instance(), "note"); - #if USE_ADAPTATION -ACL::Prototype ACLAdaptationService::RegistryProtoype(&ACLAdaptationService::RegistryEntry_, "adaptation_service"); -ACLStrategised ACLAdaptationService::RegistryEntry_(new ACLAdaptationServiceData, ACLAdaptationServiceStrategy::Instance(), "adaptation_service"); + RegisterMaker("adaptation_service", [](TypeName name)->ACL* { return new ACLStrategised(new ACLAdaptationServiceData, new ACLAdaptationServiceStrategy, name); }); #endif -ACL::Prototype ACLSquidError::RegistryProtoype(&ACLSquidError::RegistryEntry_, "squid_error"); -ACLStrategised ACLSquidError::RegistryEntry_(new ACLSquidErrorData, ACLSquidErrorStrategy::Instance(), "squid_error"); - -ACL::Prototype Acl::ConnectionsEncrypted::RegistryProtoype(&Acl::ConnectionsEncrypted::RegistryEntry_, "connections_encrypted"); -Acl::ConnectionsEncrypted Acl::ConnectionsEncrypted::RegistryEntry_("connections_encrypted"); - -ACL::Prototype ACLHasComponent::RegistryProtoype(&ACLHasComponent::RegistryEntry_, "has"); -ACLStrategised ACLHasComponent::RegistryEntry_(new ACLHasComponentData, ACLHasComponentStrategy::Instance(), "has"); +#if SQUID_SNMP + RegisterMaker("snmp_community", [](TypeName name)->ACL* { return new ACLStrategised(new ACLStringData, new ACLSNMPCommunityStrategy, name); }); +#endif +} diff -u -r -N squid-4.0.20/src/adaptation/AccessCheck.cc squid-4.0.21/src/adaptation/AccessCheck.cc --- squid-4.0.20/src/adaptation/AccessCheck.cc 2017-06-02 00:49:17.000000000 +1200 +++ squid-4.0.21/src/adaptation/AccessCheck.cc 2017-07-02 20:41:18.000000000 +1200 @@ -174,7 +174,7 @@ Must(!candidates.empty()); // the candidate we were checking must be there debugs(93,5, HERE << topCandidate() << " answer=" << answer); - if (answer == ACCESS_ALLOWED) { // the rule matched + if (answer.allowed()) { // the rule matched ServiceGroupPointer g = topGroup(); if (g != NULL) { // the corresponding group found callBack(g); diff -u -r -N squid-4.0.20/src/adaptation/ecap/Host.cc squid-4.0.21/src/adaptation/ecap/Host.cc --- squid-4.0.20/src/adaptation/ecap/Host.cc 2017-06-02 00:49:17.000000000 +1200 +++ squid-4.0.21/src/adaptation/ecap/Host.cc 2017-07-02 20:41:18.000000000 +1200 @@ -18,6 +18,7 @@ #include "base/TextException.h" #include "HttpReply.h" #include "HttpRequest.h" +#include "MasterXaction.h" const libecap::Name Adaptation::Ecap::protocolInternal("internal", libecap::Name::NextId()); const libecap::Name Adaptation::Ecap::protocolCacheObj("cache_object", libecap::Name::NextId()); @@ -162,7 +163,8 @@ Adaptation::Ecap::Host::MessagePtr Adaptation::Ecap::Host::newRequest() const { - return MessagePtr(new Adaptation::Ecap::MessageRep(new HttpRequest)); + static const MasterXaction::Pointer mx = new MasterXaction(XactionInitiator::initAdaptationOrphan_); + return MessagePtr(new Adaptation::Ecap::MessageRep(new HttpRequest(mx))); } Adaptation::Ecap::Host::MessagePtr diff -u -r -N squid-4.0.20/src/adaptation/ecap/Makefile.in squid-4.0.21/src/adaptation/ecap/Makefile.in --- squid-4.0.20/src/adaptation/ecap/Makefile.in 2017-06-02 00:55:40.000000000 +1200 +++ squid-4.0.21/src/adaptation/ecap/Makefile.in 2017-07-02 20:41:25.000000000 +1200 @@ -1,7 +1,7 @@ -# Makefile.in generated by automake 1.15 from Makefile.am. +# Makefile.in generated by automake 1.15.1 from Makefile.am. # @configure_input@ -# Copyright (C) 1994-2014 Free Software Foundation, Inc. +# Copyright (C) 1994-2017 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, diff -u -r -N squid-4.0.20/src/adaptation/ecap/MessageRep.cc squid-4.0.21/src/adaptation/ecap/MessageRep.cc --- squid-4.0.20/src/adaptation/ecap/MessageRep.cc 2017-06-02 00:49:17.000000000 +1200 +++ squid-4.0.21/src/adaptation/ecap/MessageRep.cc 2017-07-02 20:41:18.000000000 +1200 @@ -199,11 +199,11 @@ void Adaptation::Ecap::RequestLineRep::uri(const Area &aUri) { - // TODO: if method is not set, urlPath will assume it is not connect; - // Can we change urlParse API to remove the method parameter? - // TODO: optimize: urlPath should take constant URL buffer + // TODO: if method is not set, URL::parse will assume it is not connect; + // Can we change URL::parse API to remove the method parameter? + // TODO: optimize: URL::parse should take constant URL buffer char *buf = xstrdup(aUri.toString().c_str()); - const bool ok = urlParse(theMessage.method, buf, &theMessage); + const bool ok = theMessage.url.parse(theMessage.method, buf); xfree(buf); Must(ok); } diff -u -r -N squid-4.0.20/src/adaptation/ecap/XactionRep.cc squid-4.0.21/src/adaptation/ecap/XactionRep.cc --- squid-4.0.20/src/adaptation/ecap/XactionRep.cc 2017-06-02 00:49:17.000000000 +1200 +++ squid-4.0.21/src/adaptation/ecap/XactionRep.cc 2017-07-02 20:41:18.000000000 +1200 @@ -23,6 +23,7 @@ #include "format/Format.h" #include "HttpReply.h" #include "HttpRequest.h" +#include "MasterXaction.h" #include "SquidTime.h" CBDATA_NAMESPACED_CLASS_INIT(Adaptation::Ecap::XactionRep, XactionRep); @@ -738,5 +739,13 @@ Adaptation::Ecap::XactionRep::updateSources(HttpMsg *adapted) { adapted->sources |= service().cfg().connectionEncryption ? HttpMsg::srcEcaps : HttpMsg::srcEcap; + + // Update masterXaction object for adapted HTTP requests. + if (HttpRequest *adaptedReq = dynamic_cast(adapted)) { + HttpRequest *request = dynamic_cast (theCauseRep ? + theCauseRep->raw().header : theVirginRep.raw().header); + Must(request); + adaptedReq->masterXaction = request->masterXaction; + } } diff -u -r -N squid-4.0.20/src/adaptation/icap/Launcher.cc squid-4.0.21/src/adaptation/icap/Launcher.cc --- squid-4.0.20/src/adaptation/icap/Launcher.cc 2017-06-02 00:49:17.000000000 +1200 +++ squid-4.0.21/src/adaptation/icap/Launcher.cc 2017-07-02 20:41:18.000000000 +1200 @@ -147,7 +147,7 @@ cl->reply = info.icapReply; HTTPMSGLOCK(cl->reply); - bool result = cl->fastCheck() == ACCESS_ALLOWED; + bool result = cl->fastCheck().allowed(); delete cl; return result; } diff -u -r -N squid-4.0.20/src/adaptation/icap/Makefile.in squid-4.0.21/src/adaptation/icap/Makefile.in --- squid-4.0.20/src/adaptation/icap/Makefile.in 2017-06-02 00:55:45.000000000 +1200 +++ squid-4.0.21/src/adaptation/icap/Makefile.in 2017-07-02 20:41:25.000000000 +1200 @@ -1,7 +1,7 @@ -# Makefile.in generated by automake 1.15 from Makefile.am. +# Makefile.in generated by automake 1.15.1 from Makefile.am. # @configure_input@ -# Copyright (C) 1994-2014 Free Software Foundation, Inc. +# Copyright (C) 1994-2017 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, diff -u -r -N squid-4.0.20/src/adaptation/icap/ModXact.cc squid-4.0.21/src/adaptation/icap/ModXact.cc --- squid-4.0.20/src/adaptation/icap/ModXact.cc 2017-06-02 00:49:17.000000000 +1200 +++ squid-4.0.21/src/adaptation/icap/ModXact.cc 2017-07-02 20:41:18.000000000 +1200 @@ -30,6 +30,7 @@ #include "HttpMsg.h" #include "HttpReply.h" #include "HttpRequest.h" +#include "MasterXaction.h" #include "SquidTime.h" #include "URL.h" @@ -734,7 +735,7 @@ setOutcome(service().cfg().method == ICAP::methodReqmod ? xoSatisfied : xoModified); } else if (gotEncapsulated("req-hdr")) { - adapted.setHeader(new HttpRequest); + adapted.setHeader(new HttpRequest(virginRequest().masterXaction)); setOutcome(xoModified); } else throw TexcHere("Neither res-hdr nor req-hdr in maybeAllocateHttpMsg()"); @@ -961,8 +962,8 @@ Must(!adapted.header); { HttpMsg::Pointer newHead; - if (dynamic_cast(oldHead)) { - newHead = new HttpRequest; + if (const HttpRequest *r = dynamic_cast(oldHead)) { + newHead = new HttpRequest(r->masterXaction); } else if (dynamic_cast(oldHead)) { newHead = new HttpReply; } @@ -1547,7 +1548,7 @@ HttpMsg::Pointer headClone; if (const HttpRequest* old_request = dynamic_cast(head)) { - HttpRequest::Pointer new_request(new HttpRequest); + HttpRequest::Pointer new_request(new HttpRequest(old_request->masterXaction)); // copy the requst-line details new_request->method = old_request->method; new_request->url = old_request->url; diff -u -r -N squid-4.0.20/src/adaptation/icap/Xaction.cc squid-4.0.21/src/adaptation/icap/Xaction.cc --- squid-4.0.20/src/adaptation/icap/Xaction.cc 2017-06-02 00:49:17.000000000 +1200 +++ squid-4.0.21/src/adaptation/icap/Xaction.cc 2017-07-02 20:41:18.000000000 +1200 @@ -99,7 +99,8 @@ { debugs(93,3, typeName << " constructed, this=" << this << " [icapx" << id << ']'); // we should not call virtual status() here - icapRequest = new HttpRequest; + const MasterXaction::Pointer mx = new MasterXaction(XactionInitiator::initAdaptation); + icapRequest = new HttpRequest(mx); HTTPMSGLOCK(icapRequest); icap_tr_start = current_time; memset(&icap_tio_start, 0, sizeof(icap_tio_start)); diff -u -r -N squid-4.0.20/src/adaptation/Makefile.in squid-4.0.21/src/adaptation/Makefile.in --- squid-4.0.20/src/adaptation/Makefile.in 2017-06-02 00:55:34.000000000 +1200 +++ squid-4.0.21/src/adaptation/Makefile.in 2017-07-02 20:41:25.000000000 +1200 @@ -1,7 +1,7 @@ -# Makefile.in generated by automake 1.15 from Makefile.am. +# Makefile.in generated by automake 1.15.1 from Makefile.am. # @configure_input@ -# Copyright (C) 1994-2014 Free Software Foundation, Inc. +# Copyright (C) 1994-2017 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, diff -u -r -N squid-4.0.20/src/adaptation/ServiceConfig.cc squid-4.0.21/src/adaptation/ServiceConfig.cc --- squid-4.0.20/src/adaptation/ServiceConfig.cc 2017-06-02 00:49:17.000000000 +1200 +++ squid-4.0.21/src/adaptation/ServiceConfig.cc 2017-07-02 20:41:18.000000000 +1200 @@ -189,7 +189,7 @@ Adaptation::ServiceConfig::grokUri(const char *value) { // TODO: find core code that parses URLs and extracts various parts - // AYJ: most of this is duplicate of urlParse() in src/url.cc + // AYJ: most of this is duplicate of URL::parse() in src/url.cc if (!value || !*value) { debugs(3, DBG_CRITICAL, HERE << cfg_filename << ':' << config_lineno << ": " << diff -u -r -N squid-4.0.20/src/anyp/Makefile.in squid-4.0.21/src/anyp/Makefile.in --- squid-4.0.20/src/anyp/Makefile.in 2017-06-02 00:55:53.000000000 +1200 +++ squid-4.0.21/src/anyp/Makefile.in 2017-07-02 20:41:25.000000000 +1200 @@ -1,7 +1,7 @@ -# Makefile.in generated by automake 1.15 from Makefile.am. +# Makefile.in generated by automake 1.15.1 from Makefile.am. # @configure_input@ -# Copyright (C) 1994-2014 Free Software Foundation, Inc. +# Copyright (C) 1994-2017 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, diff -u -r -N squid-4.0.20/src/auth/AclMaxUserIp.cc squid-4.0.21/src/auth/AclMaxUserIp.cc --- squid-4.0.20/src/auth/AclMaxUserIp.cc 2017-06-02 00:49:17.000000000 +1200 +++ squid-4.0.21/src/auth/AclMaxUserIp.cc 2017-07-02 20:41:18.000000000 +1200 @@ -18,24 +18,11 @@ #include "Parsing.h" #include "wordlist.h" -ACLFlag ACLMaxUserIP::SupportedFlags[] = {ACL_F_STRICT, ACL_F_END}; - ACLMaxUserIP::ACLMaxUserIP(char const *theClass) : - ACL(SupportedFlags), class_(theClass), maximum(0) {} -ACLMaxUserIP::ACLMaxUserIP(ACLMaxUserIP const &old) : - class_(old.class_), - maximum(old.maximum) -{ - flags = old.flags; -} - -ACLMaxUserIP::~ACLMaxUserIP() -{} - ACL * ACLMaxUserIP::clone() const { @@ -60,6 +47,15 @@ return maximum > 0; } +const Acl::Options & +ACLMaxUserIP::options() +{ + static const Acl::BooleanOption BeStrict; + static const Acl::Options MyOptions = { { "-s", &BeStrict } }; + BeStrict.linkWith(&beStrict); + return MyOptions; +} + void ACLMaxUserIP::parse() { @@ -102,7 +98,7 @@ debugs(28, DBG_IMPORTANT, "aclMatchUserMaxIP: user '" << auth_user_request->username() << "' tries to use too many IP addresses (max " << maximum << " allowed)!"); /* this is a match */ - if (flags.isSet(ACL_F_STRICT)) { + if (beStrict) { /* * simply deny access - the user name is already associated with * the request diff -u -r -N squid-4.0.20/src/auth/AclMaxUserIp.h squid-4.0.21/src/auth/AclMaxUserIp.h --- squid-4.0.20/src/auth/AclMaxUserIp.h 2017-06-02 00:49:17.000000000 +1200 +++ squid-4.0.21/src/auth/AclMaxUserIp.h 2017-07-02 20:41:18.000000000 +1200 @@ -12,7 +12,6 @@ #if USE_AUTH #include "acl/Acl.h" -#include "acl/Checklist.h" #include "auth/UserRequest.h" class ACLMaxUserIP : public ACL @@ -20,13 +19,11 @@ MEMPROXY_CLASS(ACLMaxUserIP); public: - ACLMaxUserIP(char const *theClass); - ACLMaxUserIP(ACLMaxUserIP const &old); - ~ACLMaxUserIP(); - ACLMaxUserIP &operator =(ACLMaxUserIP const &); + explicit ACLMaxUserIP(char const *theClass); virtual ACL *clone() const; virtual char const *typeString() const; + virtual const Acl::Options &options(); virtual void parse(); virtual int match(ACLChecklist *cl); virtual SBufList dump() const; @@ -36,14 +33,13 @@ int getMaximum() const {return maximum;} - bool getStrict() const {return flags.isSet(ACL_F_STRICT);} - private: - static Prototype RegistryProtoype; - static ACLMaxUserIP RegistryEntry_; - static ACLFlag SupportedFlags[]; - int match(Auth::UserRequest::Pointer auth_user_request, Ip::Address const &src_addr); + +public: + Acl::BooleanOptionValue beStrict; ///< Enforce "one user, one device" policy? + +private: char const *class_; int maximum; }; diff -u -r -N squid-4.0.20/src/auth/AclProxyAuth.cc squid-4.0.21/src/auth/AclProxyAuth.cc --- squid-4.0.20/src/auth/AclProxyAuth.cc 2017-06-02 00:49:17.000000000 +1200 +++ squid-4.0.21/src/auth/AclProxyAuth.cc 2017-07-02 20:41:18.000000000 +1200 @@ -51,6 +51,12 @@ } void +ACLProxyAuth::parseFlags() +{ + ParseFlags(Acl::NoOptions(), data->supportedFlags()); +} + +void ACLProxyAuth::parse() { data->parse(); diff -u -r -N squid-4.0.20/src/auth/AclProxyAuth.h squid-4.0.21/src/auth/AclProxyAuth.h --- squid-4.0.20/src/auth/AclProxyAuth.h 2017-06-02 00:49:17.000000000 +1200 +++ squid-4.0.21/src/auth/AclProxyAuth.h 2017-07-02 20:41:18.000000000 +1200 @@ -37,24 +37,20 @@ ACLProxyAuth(ACLProxyAuth const &); ACLProxyAuth &operator =(ACLProxyAuth const &); + /* ACL API */ virtual char const *typeString() const; virtual void parse(); virtual bool isProxyAuth() const {return true;} - + virtual void parseFlags(); virtual int match(ACLChecklist *checklist); virtual SBufList dump() const; virtual bool valid() const; virtual bool empty() const; virtual bool requiresRequest() const {return true;} - virtual ACL *clone() const; virtual int matchForCache(ACLChecklist *checklist); private: - static Prototype UserRegistryProtoype; - static ACLProxyAuth UserRegistryEntry_; - static Prototype RegexRegistryProtoype; - static ACLProxyAuth RegexRegistryEntry_; int matchProxyAuth(ACLChecklist *); ACLData *data; char const *type_; diff -u -r -N squid-4.0.20/src/auth/basic/DB/basic_db_auth.8 squid-4.0.21/src/auth/basic/DB/basic_db_auth.8 --- squid-4.0.20/src/auth/basic/DB/basic_db_auth.8 2017-06-02 09:55:21.000000000 +1200 +++ squid-4.0.21/src/auth/basic/DB/basic_db_auth.8 2017-07-02 20:57:35.000000000 +1200 @@ -1,4 +1,4 @@ -.\" Automatically generated by Pod::Man 4.08 (Pod::Simple 3.32) +.\" Automatically generated by Pod::Man 4.07 (Pod::Simple 3.32) .\" .\" Standard preamble: .\" ======================================================================== @@ -129,7 +129,7 @@ .\" ======================================================================== .\" .IX Title "BASIC_DB_AUTH 8" -.TH BASIC_DB_AUTH 8 "2017-06-01" "perl v5.24.1" "User Contributed Perl Documentation" +.TH BASIC_DB_AUTH 8 "2017-07-02" "perl v5.24.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 @@ -190,7 +190,7 @@ Keep a persistent database connection open between queries. .IP "\fB\-\-joomla\fR" 12 .IX Item "--joomla" -Tells helper that user database is Joomla \s-1DB.\s0 So their unusual salt +Tells helper that user database is Joomla \s-1DB. \s0 So their unusual salt hashing is understood. .SH "AUTHOR" .IX Header "AUTHOR" @@ -229,7 +229,7 @@ Report ideas for new improvements to the \fISquid Developers mailing list .SH "SEE ALSO" .IX Header "SEE ALSO" -squid (8), \s-1GPL\s0 (7), +squid (8), \s-1GPL \\fIs0\fR\|(7), .PP The Squid \s-1FAQ\s0 wiki http://wiki.squid\-cache.org/SquidFaq .PP diff -u -r -N squid-4.0.20/src/auth/basic/DB/Makefile.in squid-4.0.21/src/auth/basic/DB/Makefile.in --- squid-4.0.20/src/auth/basic/DB/Makefile.in 2017-06-02 00:56:05.000000000 +1200 +++ squid-4.0.21/src/auth/basic/DB/Makefile.in 2017-07-02 20:41:25.000000000 +1200 @@ -1,7 +1,7 @@ -# Makefile.in generated by automake 1.15 from Makefile.am. +# Makefile.in generated by automake 1.15.1 from Makefile.am. # @configure_input@ -# Copyright (C) 1994-2014 Free Software Foundation, Inc. +# Copyright (C) 1994-2017 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, diff -u -r -N squid-4.0.20/src/auth/basic/fake/Makefile.in squid-4.0.21/src/auth/basic/fake/Makefile.in --- squid-4.0.20/src/auth/basic/fake/Makefile.in 2017-06-02 00:57:29.000000000 +1200 +++ squid-4.0.21/src/auth/basic/fake/Makefile.in 2017-07-02 20:41:26.000000000 +1200 @@ -1,7 +1,7 @@ -# Makefile.in generated by automake 1.15 from Makefile.am. +# Makefile.in generated by automake 1.15.1 from Makefile.am. # @configure_input@ -# Copyright (C) 1994-2014 Free Software Foundation, Inc. +# Copyright (C) 1994-2017 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, diff -u -r -N squid-4.0.20/src/auth/basic/getpwnam/Makefile.in squid-4.0.21/src/auth/basic/getpwnam/Makefile.in --- squid-4.0.20/src/auth/basic/getpwnam/Makefile.in 2017-06-02 00:57:34.000000000 +1200 +++ squid-4.0.21/src/auth/basic/getpwnam/Makefile.in 2017-07-02 20:41:26.000000000 +1200 @@ -1,7 +1,7 @@ -# Makefile.in generated by automake 1.15 from Makefile.am. +# Makefile.in generated by automake 1.15.1 from Makefile.am. # @configure_input@ -# Copyright (C) 1994-2014 Free Software Foundation, Inc. +# Copyright (C) 1994-2017 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, diff -u -r -N squid-4.0.20/src/auth/basic/LDAP/Makefile.in squid-4.0.21/src/auth/basic/LDAP/Makefile.in --- squid-4.0.20/src/auth/basic/LDAP/Makefile.in 2017-06-02 00:56:16.000000000 +1200 +++ squid-4.0.21/src/auth/basic/LDAP/Makefile.in 2017-07-02 20:41:25.000000000 +1200 @@ -1,7 +1,7 @@ -# Makefile.in generated by automake 1.15 from Makefile.am. +# Makefile.in generated by automake 1.15.1 from Makefile.am. # @configure_input@ -# Copyright (C) 1994-2014 Free Software Foundation, Inc. +# Copyright (C) 1994-2017 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, diff -u -r -N squid-4.0.20/src/auth/basic/Makefile.in squid-4.0.21/src/auth/basic/Makefile.in --- squid-4.0.20/src/auth/basic/Makefile.in 2017-06-02 00:56:22.000000000 +1200 +++ squid-4.0.21/src/auth/basic/Makefile.in 2017-07-02 20:41:25.000000000 +1200 @@ -1,7 +1,7 @@ -# Makefile.in generated by automake 1.15 from Makefile.am. +# Makefile.in generated by automake 1.15.1 from Makefile.am. # @configure_input@ -# Copyright (C) 1994-2014 Free Software Foundation, Inc. +# Copyright (C) 1994-2017 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, diff -u -r -N squid-4.0.20/src/auth/basic/NCSA/basic_ncsa_auth.8 squid-4.0.21/src/auth/basic/NCSA/basic_ncsa_auth.8 --- squid-4.0.20/src/auth/basic/NCSA/basic_ncsa_auth.8 2017-06-02 00:49:17.000000000 +1200 +++ squid-4.0.21/src/auth/basic/NCSA/basic_ncsa_auth.8 2017-07-02 20:41:18.000000000 +1200 @@ -18,15 +18,15 @@ .PP This authenticator accepts: .BR -* Blowfish - for passwords 72 characters or less in length + * Blowfish \- for passwords 72 characters or less in length. .BR -* SHA256 - with salting and magic strings + * SHA256 \- with salting and magic strings. .BR -* SHA512 - with salting and magic strings + * SHA512 \- with salting and magic strings. .BR -* MD5 - with optional salt and magic strings + * MD5 \- with optional salt and magic strings. .BR -* DES - for passwords 8 characters or less in length + * DES \- for passwords 8 characters or less in length. . NOTE: Blowfish and SHA algorithms require system-specific support. . diff -u -r -N squid-4.0.20/src/auth/basic/NCSA/Makefile.in squid-4.0.21/src/auth/basic/NCSA/Makefile.in --- squid-4.0.20/src/auth/basic/NCSA/Makefile.in 2017-06-02 00:56:30.000000000 +1200 +++ squid-4.0.21/src/auth/basic/NCSA/Makefile.in 2017-07-02 20:41:25.000000000 +1200 @@ -1,7 +1,7 @@ -# Makefile.in generated by automake 1.15 from Makefile.am. +# Makefile.in generated by automake 1.15.1 from Makefile.am. # @configure_input@ -# Copyright (C) 1994-2014 Free Software Foundation, Inc. +# Copyright (C) 1994-2017 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, diff -u -r -N squid-4.0.20/src/auth/basic/NIS/Makefile.in squid-4.0.21/src/auth/basic/NIS/Makefile.in --- squid-4.0.20/src/auth/basic/NIS/Makefile.in 2017-06-02 00:56:35.000000000 +1200 +++ squid-4.0.21/src/auth/basic/NIS/Makefile.in 2017-07-02 20:41:25.000000000 +1200 @@ -1,7 +1,7 @@ -# Makefile.in generated by automake 1.15 from Makefile.am. +# Makefile.in generated by automake 1.15.1 from Makefile.am. # @configure_input@ -# Copyright (C) 1994-2014 Free Software Foundation, Inc. +# Copyright (C) 1994-2017 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, diff -u -r -N squid-4.0.20/src/auth/basic/PAM/Makefile.in squid-4.0.21/src/auth/basic/PAM/Makefile.in --- squid-4.0.20/src/auth/basic/PAM/Makefile.in 2017-06-02 00:56:46.000000000 +1200 +++ squid-4.0.21/src/auth/basic/PAM/Makefile.in 2017-07-02 20:41:25.000000000 +1200 @@ -1,7 +1,7 @@ -# Makefile.in generated by automake 1.15 from Makefile.am. +# Makefile.in generated by automake 1.15.1 from Makefile.am. # @configure_input@ -# Copyright (C) 1994-2014 Free Software Foundation, Inc. +# Copyright (C) 1994-2017 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, diff -u -r -N squid-4.0.20/src/auth/basic/POP3/basic_pop3_auth.8 squid-4.0.21/src/auth/basic/POP3/basic_pop3_auth.8 --- squid-4.0.20/src/auth/basic/POP3/basic_pop3_auth.8 2017-06-02 09:56:01.000000000 +1200 +++ squid-4.0.21/src/auth/basic/POP3/basic_pop3_auth.8 2017-07-02 20:57:35.000000000 +1200 @@ -1,4 +1,4 @@ -.\" Automatically generated by Pod::Man 4.08 (Pod::Simple 3.32) +.\" Automatically generated by Pod::Man 4.07 (Pod::Simple 3.32) .\" .\" Standard preamble: .\" ======================================================================== @@ -129,7 +129,7 @@ .\" ======================================================================== .\" .IX Title "BASIC_POP3_AUTH 8" -.TH BASIC_POP3_AUTH 8 "2017-06-01" "perl v5.24.1" "User Contributed Perl Documentation" +.TH BASIC_POP3_AUTH 8 "2017-07-02" "perl v5.24.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 @@ -198,7 +198,7 @@ Report ideas for new improvements to the \fISquid Developers mailing list .SH "SEE ALSO" .IX Header "SEE ALSO" -squid (8), \s-1GPL\s0 (7), +squid (8), \s-1GPL \\fIs0\fR\|(7), .PP The Squid \s-1FAQ\s0 wiki http://wiki.squid\-cache.org/SquidFaq .PP diff -u -r -N squid-4.0.20/src/auth/basic/POP3/Makefile.in squid-4.0.21/src/auth/basic/POP3/Makefile.in --- squid-4.0.20/src/auth/basic/POP3/Makefile.in 2017-06-02 00:56:53.000000000 +1200 +++ squid-4.0.21/src/auth/basic/POP3/Makefile.in 2017-07-02 20:41:25.000000000 +1200 @@ -1,7 +1,7 @@ -# Makefile.in generated by automake 1.15 from Makefile.am. +# Makefile.in generated by automake 1.15.1 from Makefile.am. # @configure_input@ -# Copyright (C) 1994-2014 Free Software Foundation, Inc. +# Copyright (C) 1994-2017 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, diff -u -r -N squid-4.0.20/src/auth/basic/RADIUS/Makefile.in squid-4.0.21/src/auth/basic/RADIUS/Makefile.in --- squid-4.0.20/src/auth/basic/RADIUS/Makefile.in 2017-06-02 00:57:02.000000000 +1200 +++ squid-4.0.21/src/auth/basic/RADIUS/Makefile.in 2017-07-02 20:41:25.000000000 +1200 @@ -1,7 +1,7 @@ -# Makefile.in generated by automake 1.15 from Makefile.am. +# Makefile.in generated by automake 1.15.1 from Makefile.am. # @configure_input@ -# Copyright (C) 1994-2014 Free Software Foundation, Inc. +# Copyright (C) 1994-2017 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, diff -u -r -N squid-4.0.20/src/auth/basic/SASL/Makefile.in squid-4.0.21/src/auth/basic/SASL/Makefile.in --- squid-4.0.20/src/auth/basic/SASL/Makefile.in 2017-06-02 00:57:07.000000000 +1200 +++ squid-4.0.21/src/auth/basic/SASL/Makefile.in 2017-07-02 20:41:25.000000000 +1200 @@ -1,7 +1,7 @@ -# Makefile.in generated by automake 1.15 from Makefile.am. +# Makefile.in generated by automake 1.15.1 from Makefile.am. # @configure_input@ -# Copyright (C) 1994-2014 Free Software Foundation, Inc. +# Copyright (C) 1994-2017 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, diff -u -r -N squid-4.0.20/src/auth/basic/SMB/Makefile.in squid-4.0.21/src/auth/basic/SMB/Makefile.in --- squid-4.0.20/src/auth/basic/SMB/Makefile.in 2017-06-02 00:57:13.000000000 +1200 +++ squid-4.0.21/src/auth/basic/SMB/Makefile.in 2017-07-02 20:41:25.000000000 +1200 @@ -1,7 +1,7 @@ -# Makefile.in generated by automake 1.15 from Makefile.am. +# Makefile.in generated by automake 1.15.1 from Makefile.am. # @configure_input@ -# Copyright (C) 1994-2014 Free Software Foundation, Inc. +# Copyright (C) 1994-2017 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, diff -u -r -N squid-4.0.20/src/auth/basic/SMB_LM/Makefile.in squid-4.0.21/src/auth/basic/SMB_LM/Makefile.in --- squid-4.0.20/src/auth/basic/SMB_LM/Makefile.in 2017-06-02 00:57:18.000000000 +1200 +++ squid-4.0.21/src/auth/basic/SMB_LM/Makefile.in 2017-07-02 20:41:25.000000000 +1200 @@ -1,7 +1,7 @@ -# Makefile.in generated by automake 1.15 from Makefile.am. +# Makefile.in generated by automake 1.15.1 from Makefile.am. # @configure_input@ -# Copyright (C) 1994-2014 Free Software Foundation, Inc. +# Copyright (C) 1994-2017 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, diff -u -r -N squid-4.0.20/src/auth/basic/SSPI/Makefile.in squid-4.0.21/src/auth/basic/SSPI/Makefile.in --- squid-4.0.20/src/auth/basic/SSPI/Makefile.in 2017-06-02 00:57:25.000000000 +1200 +++ squid-4.0.21/src/auth/basic/SSPI/Makefile.in 2017-07-02 20:41:26.000000000 +1200 @@ -1,7 +1,7 @@ -# Makefile.in generated by automake 1.15 from Makefile.am. +# Makefile.in generated by automake 1.15.1 from Makefile.am. # @configure_input@ -# Copyright (C) 1994-2014 Free Software Foundation, Inc. +# Copyright (C) 1994-2017 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, diff -u -r -N squid-4.0.20/src/auth/digest/eDirectory/Makefile.in squid-4.0.21/src/auth/digest/eDirectory/Makefile.in --- squid-4.0.20/src/auth/digest/eDirectory/Makefile.in 2017-06-02 00:57:48.000000000 +1200 +++ squid-4.0.21/src/auth/digest/eDirectory/Makefile.in 2017-07-02 20:41:26.000000000 +1200 @@ -1,7 +1,7 @@ -# Makefile.in generated by automake 1.15 from Makefile.am. +# Makefile.in generated by automake 1.15.1 from Makefile.am. # @configure_input@ -# Copyright (C) 1994-2014 Free Software Foundation, Inc. +# Copyright (C) 1994-2017 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, diff -u -r -N squid-4.0.20/src/auth/digest/file/Makefile.in squid-4.0.21/src/auth/digest/file/Makefile.in --- squid-4.0.20/src/auth/digest/file/Makefile.in 2017-06-02 00:57:53.000000000 +1200 +++ squid-4.0.21/src/auth/digest/file/Makefile.in 2017-07-02 20:41:26.000000000 +1200 @@ -1,7 +1,7 @@ -# Makefile.in generated by automake 1.15 from Makefile.am. +# Makefile.in generated by automake 1.15.1 from Makefile.am. # @configure_input@ -# Copyright (C) 1994-2014 Free Software Foundation, Inc. +# Copyright (C) 1994-2017 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, diff -u -r -N squid-4.0.20/src/auth/digest/LDAP/ldap_backend.cc squid-4.0.21/src/auth/digest/LDAP/ldap_backend.cc --- squid-4.0.20/src/auth/digest/LDAP/ldap_backend.cc 2017-06-02 00:49:17.000000000 +1200 +++ squid-4.0.21/src/auth/digest/LDAP/ldap_backend.cc 2017-07-02 20:41:18.000000000 +1200 @@ -655,7 +655,7 @@ // use the -l delimiter to find realm, or // only honor the -r specified realm const bool lookup = (!*frealm && *delimiter) || - (*frealm && strcmp(requestData->realm, frealm) != 0); + (*frealm && strcmp(requestData->realm, frealm) == 0); if (lookup) password = getpassword(requestData->user, requestData->realm); diff -u -r -N squid-4.0.20/src/auth/digest/LDAP/Makefile.in squid-4.0.21/src/auth/digest/LDAP/Makefile.in --- squid-4.0.20/src/auth/digest/LDAP/Makefile.in 2017-06-02 00:57:38.000000000 +1200 +++ squid-4.0.21/src/auth/digest/LDAP/Makefile.in 2017-07-02 20:41:26.000000000 +1200 @@ -1,7 +1,7 @@ -# Makefile.in generated by automake 1.15 from Makefile.am. +# Makefile.in generated by automake 1.15.1 from Makefile.am. # @configure_input@ -# Copyright (C) 1994-2014 Free Software Foundation, Inc. +# Copyright (C) 1994-2017 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, diff -u -r -N squid-4.0.20/src/auth/digest/Makefile.in squid-4.0.21/src/auth/digest/Makefile.in --- squid-4.0.20/src/auth/digest/Makefile.in 2017-06-02 00:57:42.000000000 +1200 +++ squid-4.0.21/src/auth/digest/Makefile.in 2017-07-02 20:41:26.000000000 +1200 @@ -1,7 +1,7 @@ -# Makefile.in generated by automake 1.15 from Makefile.am. +# Makefile.in generated by automake 1.15.1 from Makefile.am. # @configure_input@ -# Copyright (C) 1994-2014 Free Software Foundation, Inc. +# Copyright (C) 1994-2017 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, diff -u -r -N squid-4.0.20/src/auth/Makefile.in squid-4.0.21/src/auth/Makefile.in --- squid-4.0.20/src/auth/Makefile.in 2017-06-02 00:56:02.000000000 +1200 +++ squid-4.0.21/src/auth/Makefile.in 2017-07-02 20:41:25.000000000 +1200 @@ -1,7 +1,7 @@ -# Makefile.in generated by automake 1.15 from Makefile.am. +# Makefile.in generated by automake 1.15.1 from Makefile.am. # @configure_input@ -# Copyright (C) 1994-2014 Free Software Foundation, Inc. +# Copyright (C) 1994-2017 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, diff -u -r -N squid-4.0.20/src/auth/negotiate/kerberos/Makefile.in squid-4.0.21/src/auth/negotiate/kerberos/Makefile.in --- squid-4.0.20/src/auth/negotiate/kerberos/Makefile.in 2017-06-02 00:58:09.000000000 +1200 +++ squid-4.0.21/src/auth/negotiate/kerberos/Makefile.in 2017-07-02 20:41:26.000000000 +1200 @@ -1,7 +1,7 @@ -# Makefile.in generated by automake 1.15 from Makefile.am. +# Makefile.in generated by automake 1.15.1 from Makefile.am. # @configure_input@ -# Copyright (C) 1994-2014 Free Software Foundation, Inc. +# Copyright (C) 1994-2017 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, diff -u -r -N squid-4.0.20/src/auth/negotiate/Makefile.in squid-4.0.21/src/auth/negotiate/Makefile.in --- squid-4.0.20/src/auth/negotiate/Makefile.in 2017-06-02 00:58:00.000000000 +1200 +++ squid-4.0.21/src/auth/negotiate/Makefile.in 2017-07-02 20:41:26.000000000 +1200 @@ -1,7 +1,7 @@ -# Makefile.in generated by automake 1.15 from Makefile.am. +# Makefile.in generated by automake 1.15.1 from Makefile.am. # @configure_input@ -# Copyright (C) 1994-2014 Free Software Foundation, Inc. +# Copyright (C) 1994-2017 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, diff -u -r -N squid-4.0.20/src/auth/negotiate/SSPI/Makefile.in squid-4.0.21/src/auth/negotiate/SSPI/Makefile.in --- squid-4.0.20/src/auth/negotiate/SSPI/Makefile.in 2017-06-02 00:58:04.000000000 +1200 +++ squid-4.0.21/src/auth/negotiate/SSPI/Makefile.in 2017-07-02 20:41:26.000000000 +1200 @@ -1,7 +1,7 @@ -# Makefile.in generated by automake 1.15 from Makefile.am. +# Makefile.in generated by automake 1.15.1 from Makefile.am. # @configure_input@ -# Copyright (C) 1994-2014 Free Software Foundation, Inc. +# Copyright (C) 1994-2017 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, diff -u -r -N squid-4.0.20/src/auth/negotiate/wrapper/Makefile.in squid-4.0.21/src/auth/negotiate/wrapper/Makefile.in --- squid-4.0.20/src/auth/negotiate/wrapper/Makefile.in 2017-06-02 00:58:15.000000000 +1200 +++ squid-4.0.21/src/auth/negotiate/wrapper/Makefile.in 2017-07-02 20:41:26.000000000 +1200 @@ -1,7 +1,7 @@ -# Makefile.in generated by automake 1.15 from Makefile.am. +# Makefile.in generated by automake 1.15.1 from Makefile.am. # @configure_input@ -# Copyright (C) 1994-2014 Free Software Foundation, Inc. +# Copyright (C) 1994-2017 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, diff -u -r -N squid-4.0.20/src/auth/ntlm/fake/Makefile.in squid-4.0.21/src/auth/ntlm/fake/Makefile.in --- squid-4.0.20/src/auth/ntlm/fake/Makefile.in 2017-06-02 00:58:34.000000000 +1200 +++ squid-4.0.21/src/auth/ntlm/fake/Makefile.in 2017-07-02 20:41:26.000000000 +1200 @@ -1,7 +1,7 @@ -# Makefile.in generated by automake 1.15 from Makefile.am. +# Makefile.in generated by automake 1.15.1 from Makefile.am. # @configure_input@ -# Copyright (C) 1994-2014 Free Software Foundation, Inc. +# Copyright (C) 1994-2017 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, diff -u -r -N squid-4.0.20/src/auth/ntlm/Makefile.in squid-4.0.21/src/auth/ntlm/Makefile.in --- squid-4.0.20/src/auth/ntlm/Makefile.in 2017-06-02 00:58:20.000000000 +1200 +++ squid-4.0.21/src/auth/ntlm/Makefile.in 2017-07-02 20:41:26.000000000 +1200 @@ -1,7 +1,7 @@ -# Makefile.in generated by automake 1.15 from Makefile.am. +# Makefile.in generated by automake 1.15.1 from Makefile.am. # @configure_input@ -# Copyright (C) 1994-2014 Free Software Foundation, Inc. +# Copyright (C) 1994-2017 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, diff -u -r -N squid-4.0.20/src/auth/ntlm/SMB_LM/Makefile.in squid-4.0.21/src/auth/ntlm/SMB_LM/Makefile.in --- squid-4.0.20/src/auth/ntlm/SMB_LM/Makefile.in 2017-06-02 00:58:25.000000000 +1200 +++ squid-4.0.21/src/auth/ntlm/SMB_LM/Makefile.in 2017-07-02 20:41:26.000000000 +1200 @@ -1,7 +1,7 @@ -# Makefile.in generated by automake 1.15 from Makefile.am. +# Makefile.in generated by automake 1.15.1 from Makefile.am. # @configure_input@ -# Copyright (C) 1994-2014 Free Software Foundation, Inc. +# Copyright (C) 1994-2017 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, diff -u -r -N squid-4.0.20/src/auth/ntlm/SSPI/Makefile.in squid-4.0.21/src/auth/ntlm/SSPI/Makefile.in --- squid-4.0.20/src/auth/ntlm/SSPI/Makefile.in 2017-06-02 00:58:29.000000000 +1200 +++ squid-4.0.21/src/auth/ntlm/SSPI/Makefile.in 2017-07-02 20:41:26.000000000 +1200 @@ -1,7 +1,7 @@ -# Makefile.in generated by automake 1.15 from Makefile.am. +# Makefile.in generated by automake 1.15.1 from Makefile.am. # @configure_input@ -# Copyright (C) 1994-2014 Free Software Foundation, Inc. +# Copyright (C) 1994-2017 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, diff -u -r -N squid-4.0.20/src/base/CharacterSet.cc squid-4.0.21/src/base/CharacterSet.cc --- squid-4.0.20/src/base/CharacterSet.cc 2017-06-02 00:49:17.000000000 +1200 +++ squid-4.0.21/src/base/CharacterSet.cc 2017-07-02 20:41:18.000000000 +1200 @@ -97,6 +97,15 @@ addRange(range.first, range.second); } +void +CharacterSet::printChars(std::ostream &os) const +{ + for (size_t idx = 0; idx < 256; ++idx) { + if (chars_[idx]) + os << static_cast(idx); + } +} + CharacterSet operator+ (CharacterSet lhs, const CharacterSet &rhs) { diff -u -r -N squid-4.0.20/src/base/CharacterSet.h squid-4.0.21/src/base/CharacterSet.h --- squid-4.0.20/src/base/CharacterSet.h 2017-06-02 00:49:17.000000000 +1200 +++ squid-4.0.21/src/base/CharacterSet.h 2017-07-02 20:41:18.000000000 +1200 @@ -19,9 +19,8 @@ public: typedef std::vector Storage; - /// define a character set with the given label ("anonymous" if nullptr) - /// with specified initial contents - CharacterSet(const char *label, const char * const initial); + /// a character set with a given label and contents + explicit CharacterSet(const char *label = "anonymous", const char * const chars = ""); /// define a character set with the given label ("anonymous" if nullptr) /// containing characters defined in the supplied ranges @@ -33,6 +32,9 @@ /// \see addRange CharacterSet(const char *label, std::initializer_list> ranges); + /// whether the set lacks any members + bool isEmpty() const { return chars_.empty(); } + /// whether a given character exists in the set bool operator[](unsigned char c) const {return chars_[static_cast(c)] != 0;} @@ -60,6 +62,9 @@ /// \note Ignores label bool operator != (const CharacterSet &cs) const { return !operator==(cs); } + /// prints all chars in arbitrary order, without any quoting/escaping + void printChars(std::ostream &os) const; + /// optional set label for debugging (default: "anonymous") const char * name; diff -u -r -N squid-4.0.20/src/base/Makefile.in squid-4.0.21/src/base/Makefile.in --- squid-4.0.20/src/base/Makefile.in 2017-06-02 00:58:40.000000000 +1200 +++ squid-4.0.21/src/base/Makefile.in 2017-07-02 20:41:26.000000000 +1200 @@ -1,7 +1,7 @@ -# Makefile.in generated by automake 1.15 from Makefile.am. +# Makefile.in generated by automake 1.15.1 from Makefile.am. # @configure_input@ -# Copyright (C) 1994-2014 Free Software Foundation, Inc. +# Copyright (C) 1994-2017 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, diff -u -r -N squid-4.0.20/src/base/RefCount.h squid-4.0.21/src/base/RefCount.h --- squid-4.0.20/src/base/RefCount.h 2017-06-02 00:49:17.000000000 +1200 +++ squid-4.0.21/src/base/RefCount.h 2017-07-02 20:41:18.000000000 +1200 @@ -70,11 +70,12 @@ C * operator-> () const {return const_cast(p_); } - C & operator * () const {return *const_cast(p_); } + C & operator * () const { + assert(p_); + return *const_cast(p_); + } - C const * getRaw() const {return p_; } - - C * getRaw() {return const_cast(p_); } + C * getRaw() const { return const_cast(p_); } bool operator == (const RefCount& p) const { return p.p_ == p_; diff -u -r -N squid-4.0.20/src/cache_cf.cc squid-4.0.21/src/cache_cf.cc --- squid-4.0.20/src/cache_cf.cc 2017-06-02 00:49:17.000000000 +1200 +++ squid-4.0.21/src/cache_cf.cc 2017-07-02 20:41:18.000000000 +1200 @@ -567,8 +567,9 @@ return err_count; } +static int -parseConfigFile(const char *file_name) +parseConfigFileOrThrow(const char *file_name) { int err_count = 0; @@ -609,6 +610,20 @@ return err_count; } +// TODO: Refactor main.cc to centrally handle (and report) all exceptions. +int +parseConfigFile(const char *file_name) +{ + try { + return parseConfigFileOrThrow(file_name); + } + catch (const std::exception &ex) { + debugs(3, DBG_CRITICAL, "FATAL: bad configuration: " << ex.what()); + self_destruct(); + return 1; // not reached + } +} + static void configDoConfigure(void) { @@ -1308,12 +1323,14 @@ { while (ae != NULL) { debugs(3, 3, "dump_acl: " << name << " " << ae->name); - storeAppendPrintf(entry, "%s %s %s %s ", + storeAppendPrintf(entry, "%s %s %s ", name, ae->name, - ae->typeString(), - ae->flags.flagsStr()); - dump_SBufList(entry, ae->dump()); + ae->typeString()); + SBufList tail; + tail.splice(tail.end(), ae->dumpOptions()); + tail.splice(tail.end(), ae->dump()); // ACL parameters + dump_SBufList(entry, tail); ae = ae->next; } } @@ -2403,7 +2420,7 @@ CachePeer *p = peerFindByName(host); if (!p) { - debugs(15, DBG_CRITICAL, "" << cfg_filename << ", line " << config_lineno << ": No cache_peer '" << host << "'"); + debugs(15, DBG_CRITICAL, "ERROR: " << cfg_filename << ", line " << config_lineno << ": No cache_peer '" << host << "'"); return; } @@ -4038,7 +4055,7 @@ debugs(3, 9, "possible " << cl->filename << " logformat: " << logdef_name); if (cl->type != Log::Format::CLF_UNKNOWN) { - debugs(3, DBG_CRITICAL, "Second logformat name in one access_log: " << + debugs(3, DBG_CRITICAL, "FATAL: Second logformat name in one access_log: " << logdef_name << " " << cl->type << " ? " << Log::Format::CLF_NONE); self_destruct(); return false; @@ -4077,7 +4094,7 @@ } else if (strcmp(logdef_name, "referrer") == 0) { cl->type = Log::Format::CLF_REFERER; } else if (dieWhenMissing) { - debugs(3, DBG_CRITICAL, "Log format '" << logdef_name << "' is not defined"); + debugs(3, DBG_CRITICAL, "FATAL: Log format '" << logdef_name << "' is not defined"); self_destruct(); return false; } else { @@ -4112,7 +4129,8 @@ break; case Log::Format::CLF_SQUID: - storeAppendPrintf(entry, "%s logformat=squid", log->filename); + // this is the default, no need to add to the dump + //storeAppendPrintf(entry, "%s logformat=squid", log->filename); break; case Log::Format::CLF_COMBINED: diff -u -r -N squid-4.0.20/src/cbdata.h squid-4.0.21/src/cbdata.h --- squid-4.0.20/src/cbdata.h 2017-06-02 00:49:17.000000000 +1200 +++ squid-4.0.21/src/cbdata.h 2017-07-02 20:41:18.000000000 +1200 @@ -371,5 +371,25 @@ void *data; }; +// Discouraged: Use CbcPointer<> and asynchronous calls instead if possible. +/// an old-style void* callback parameter +class CallbackData +{ +public: + CallbackData(): data_(nullptr) {} + CallbackData(void *data): data_(cbdataReference(data)) {} + CallbackData(const CallbackData &other): data_(cbdataReference(other.data_)) {} + CallbackData(CallbackData &&other): data_(other.data_) { other.data_ = nullptr; } + ~CallbackData() { cbdataReferenceDone(data_); } + + // implement if needed + CallbackData &operator =(const CallbackData &other) = delete; + + void *validDone() { void *result; return cbdataReferenceValidDone(data_, &result) ? result : nullptr; } + +private: + void *data_; ///< raw callback data, maybe invalid +}; + #endif /* SQUID_CBDATA_H */ diff -u -r -N squid-4.0.20/src/cf.data.pre squid-4.0.21/src/cf.data.pre --- squid-4.0.20/src/cf.data.pre 2017-06-02 00:49:17.000000000 +1200 +++ squid-4.0.21/src/cf.data.pre 2017-07-02 20:41:18.000000000 +1200 @@ -1242,6 +1242,28 @@ # adaptation_meta because it starts matching immediately after # the service has been selected for adaptation. + acl aclname transaction_initiator initiator ... + # Matches transaction's initiator [fast] + # + # Supported initiators are: + # esi: matches transactions fetching ESI resources + # certificate-fetching: matches transactions fetching + # a missing intermediate TLS certificate + # cache-digest: matches transactions fetching Cache Digests + # from a cache_peer + # htcp: matches HTCP requests from peers + # icp: matches ICP requests to peers + # icmp: matches ICMP RTT database (NetDB) requests to peers + # asn: matches asns db requests + # internal: matches any of the above + # client: matches transactions containing an HTTP or FTP + # client request received at a Squid *_port + # all: matches any transaction, including internal transactions + # without a configurable initiator and hopefully rare + # transactions without a known-to-Squid initiator + # + # Multiple initiators are ORed. + acl aclname has component # matches a transaction "component" [fast] # @@ -1311,17 +1333,47 @@ # SslBump2: After getting SSL Client Hello info. # SslBump3: After getting SSL Server Hello info. - acl aclname ssl::server_name .foo.com ... + acl aclname ssl::server_name [option] .foo.com ... # matches server name obtained from various sources [fast] # - # The server name is obtained during Ssl-Bump steps from such sources - # as CONNECT request URI, client SNI, and SSL server certificate CN. - # During each Ssl-Bump step, Squid may improve its understanding of a - # "true server name". Unlike dstdomain, this ACL does not perform - # DNS lookups. - # The "none" name can be used to match transactions where Squid + # The ACL computes server name(s) using such information sources as + # CONNECT request URI, TLS client SNI, and TLS server certificate + # subject (CN and SubjectAltName). The computed server name(s) usually + # change with each SslBump step, as more info becomes available: + # * SNI is used as the server name instead of the request URI, + # * subject name(s) from the server certificate (CN and + # SubjectAltName) are used as the server names instead of SNI. + # + # When the ACL computes multiple server names, matching any single + # computed name is sufficient for the ACL to match. + # + # The "none" name can be used to match transactions where the ACL # could not compute the server name using any information source - # already available at the ACL evaluation time. + # that was both available and allowed to be used by the ACL options at + # the ACL evaluation time. + # + # Unlike dstdomain, this ACL does not perform DNS lookups. + # + # An ACL option below may be used to restrict what information + # sources are used to extract the server names from: + # + # --client-requested + # The server name is SNI regardless of what the server says. + # --server-provided + # The server name(s) are the certificate subject name(s), regardless + # of what the client has requested. If the server certificate is + # unavailable, then the name is "none". + # --consensus + # The server name is either SNI (if SNI matches at least one of the + # certificate subject names) or "none" (otherwise). When the server + # certificate is unavailable, the consensus server name is SNI. + # + # Combining multiple options in one ACL is a fatal configuration + # error. + # + # For all options: If no SNI is available, then the CONNECT request + # target (a.k.a. URI) is used instead of SNI (for an intercepted + # connection, this target is the destination IP address). acl aclname ssl::server_name_regex [-i] \.foo\.com ... # regex matches server name obtained from various sources [fast] @@ -4350,9 +4402,7 @@ In all other cases, a single dash ("-") is logged. - ssl::>sni SSL client SNI sent to Squid. Available only - after the peek, stare, or splice SSL bumping - actions. + ssl::>sni SSL client SNI sent to Squid. ssl::>cert_subject The Subject field of the received client diff -u -r -N squid-4.0.20/src/clients/Client.cc squid-4.0.21/src/clients/Client.cc --- squid-4.0.20/src/clients/Client.cc 2017-06-02 00:49:17.000000000 +1200 +++ squid-4.0.21/src/clients/Client.cc 2017-07-02 20:41:18.000000000 +1200 @@ -539,7 +539,7 @@ ACLFilledChecklist ch(acl, originalRequest(), NULL); ch.reply = const_cast(entry->getReply()); // ACLFilledChecklist API bug HTTPMSGLOCK(ch.reply); - if (ch.fastCheck() != ACCESS_ALLOWED) { // when in doubt, block + if (!ch.fastCheck().allowed()) { // when in doubt, block debugs(20, 3, "store_miss prohibits caching"); return true; } diff -u -r -N squid-4.0.20/src/clients/FtpClient.cc squid-4.0.21/src/clients/FtpClient.cc --- squid-4.0.20/src/clients/FtpClient.cc 2017-06-02 00:49:17.000000000 +1200 +++ squid-4.0.21/src/clients/FtpClient.cc 2017-07-02 20:41:18.000000000 +1200 @@ -705,7 +705,7 @@ bool doEpsv = true; if (Config.accessList.ftp_epsv) { ACLFilledChecklist checklist(Config.accessList.ftp_epsv, fwd->request, NULL); - doEpsv = (checklist.fastCheck() == ACCESS_ALLOWED); + doEpsv = checklist.fastCheck().allowed(); } if (!doEpsv) { debugs(9, 5, "EPSV support manually disabled. Sending PASV for FTP Channel (" << ctrl.conn->remote <<")"); diff -u -r -N squid-4.0.20/src/clients/FtpRelay.cc squid-4.0.21/src/clients/FtpRelay.cc --- squid-4.0.20/src/clients/FtpRelay.cc 2017-06-02 00:49:17.000000000 +1200 +++ squid-4.0.21/src/clients/FtpRelay.cc 2017-07-02 20:41:18.000000000 +1200 @@ -211,9 +211,10 @@ mgr->unpinConnection(false); ctrl.close(); } else { - mgr->pinConnection(ctrl.conn, fwd->request, - ctrl.conn->getPeer(), - fwd->request->flags.connectionAuth); + CallJobHere1(9, 4, mgr, + ConnStateData, + notePinnedConnectionBecameIdle, + ConnStateData::PinnedIdleContext(ctrl.conn, fwd->request)); ctrl.forget(); } } diff -u -r -N squid-4.0.20/src/clients/Makefile.in squid-4.0.21/src/clients/Makefile.in --- squid-4.0.20/src/clients/Makefile.in 2017-06-02 00:58:46.000000000 +1200 +++ squid-4.0.21/src/clients/Makefile.in 2017-07-02 20:41:26.000000000 +1200 @@ -1,7 +1,7 @@ -# Makefile.in generated by automake 1.15 from Makefile.am. +# Makefile.in generated by automake 1.15.1 from Makefile.am. # @configure_input@ -# Copyright (C) 1994-2014 Free Software Foundation, Inc. +# Copyright (C) 1994-2017 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, diff -u -r -N squid-4.0.20/src/client_side.cc squid-4.0.21/src/client_side.cc --- squid-4.0.20/src/client_side.cc 2017-06-02 00:49:17.000000000 +1200 +++ squid-4.0.21/src/client_side.cc 2017-07-02 20:41:18.000000000 +1200 @@ -461,7 +461,7 @@ statsCheck.reply = al->reply; HTTPMSGLOCK(statsCheck.reply); } - updatePerformanceCounters = (statsCheck.fastCheck() == ACCESS_ALLOWED); + updatePerformanceCounters = statsCheck.fastCheck().allowed(); } if (updatePerformanceCounters) { @@ -592,6 +592,7 @@ clientdbEstablished(clientConnection->remote, -1); /* decrement */ pipeline.terminateAll(0); + // XXX: Closing pinned conn is too harsh: The Client may want to continue! unpinConnection(true); Server::swanSong(); // closes the client connection @@ -1526,7 +1527,7 @@ if (Config.ssl_client.cert_error) { ACLFilledChecklist check(Config.ssl_client.cert_error, request, dash_str); check.sslErrors = new Security::CertErrors(Security::CertError(SQUID_X509_V_ERR_DOMAIN_MISMATCH, srvCert)); - allowDomainMismatch = (check.fastCheck() == ACCESS_ALLOWED); + allowDomainMismatch = check.fastCheck().allowed(); delete check.sslErrors; check.sslErrors = NULL; } @@ -1580,7 +1581,7 @@ checklist.my_addr = conn->clientConnection->local; checklist.conn(conn); allow_t answer = checklist.fastCheck(); - if (answer == ACCESS_ALLOWED && answer.kind == 1) { + if (answer.allowed() && answer.kind == 1) { debugs(33, 3, "Request will be tunneled to server"); if (context) { assert(conn->pipeline.front() == context); // XXX: still assumes HTTP/1 semantics @@ -1633,11 +1634,10 @@ // this entire function to remove them from the FTP code path. Connection // setup and body_pipe preparation blobs are needed for FTP. - request->clientConnectionManager = conn; + request->manager(conn, http->al); request->flags.accelerated = http->flags.accel; request->flags.sslBumped=conn->switchedToHttps(); - request->flags.ignoreCc = conn->port->ignore_cc; // TODO: decouple http->flags.accel from request->flags.sslBumped request->flags.noDirect = (request->flags.accelerated && !request->flags.sslBumped) ? !conn->port->allow_direct : 0; @@ -1650,25 +1650,6 @@ } #endif - /** \par - * If transparent or interception mode is working clone the transparent and interception flags - * from the port settings to the request. - */ - if (http->clientConnection != NULL) { - request->flags.intercepted = ((http->clientConnection->flags & COMM_INTERCEPTION) != 0); - request->flags.interceptTproxy = ((http->clientConnection->flags & COMM_TRANSPARENT) != 0 ) ; - static const bool proxyProtocolPort = (conn->port != NULL) ? conn->port->flags.proxySurrogate : false; - if (request->flags.interceptTproxy && !proxyProtocolPort) { - if (Config.accessList.spoof_client_ip) { - ACLFilledChecklist *checklist = clientAclChecklistCreate(Config.accessList.spoof_client_ip, http); - request->flags.spoofClientIp = (checklist->fastCheck() == ACCESS_ALLOWED); - delete checklist; - } else - request->flags.spoofClientIp = true; - } else - request->flags.spoofClientIp = false; - } - if (internalCheck(request->url.path())) { if (internalHostnameIs(request->url.host()) && request->url.port() == getMyPort()) { debugs(33, 2, "internal URL found: " << request->url.getScheme() << "://" << request->url.authority(true)); @@ -1685,14 +1666,6 @@ request->flags.internal = http->flags.internal; setLogUri (http, urlCanonicalClean(request.getRaw())); - request->client_addr = conn->clientConnection->remote; // XXX: remove request->client_addr member. -#if FOLLOW_X_FORWARDED_FOR - // indirect client gets stored here because it is an HTTP header result (from X-Forwarded-For:) - // not details about the TCP connection itself - request->indirect_client_addr = conn->clientConnection->remote; -#endif /* FOLLOW_X_FORWARDED_FOR */ - request->my_addr = conn->clientConnection->local; - request->myportname = conn->port->name; if (!isFtp) { // XXX: for non-HTTP messages instantiate a different HttpMsg child type @@ -1703,10 +1676,6 @@ request->http_ver.minor = http_ver.minor; } - // Link this HttpRequest to ConnStateData relatively early so the following complex handling can use it - // TODO: this effectively obsoletes a lot of conn->FOO copying. That needs cleaning up later. - request->clientConnectionManager = conn; - if (request->header.chunked()) { chunked = true; } else if (request->header.has(Http::HdrType::TRANSFER_ENCODING)) { @@ -1857,7 +1826,7 @@ ch.my_addr = clientConnection->local; ch.conn(this); - if (ch.fastCheck() != ACCESS_ALLOWED) + if (!ch.fastCheck().allowed()) return proxyProtocolError("PROXY client not permitted by ACLs"); return true; @@ -2129,6 +2098,13 @@ // On errors, bodyPipe may become nil, but readMore will be cleared while (!inBuf.isEmpty() && !bodyPipe && flags.readMore) { + // Prohibit concurrent requests when using a pinned to-server connection + // because our Client classes do not support request pipelining. + if (pinning.pinned && !pinning.readHandler) { + debugs(33, 3, clientConnection << " waits for busy " << pinning.serverConnection); + break; + } + /* Limit the number of concurrent requests */ if (concurrentRequestQueueFilled()) break; @@ -2477,7 +2453,7 @@ ACLFilledChecklist identChecklist(Ident::TheConfig.identLookup, NULL, NULL); identChecklist.src_addr = clientConnection->remote; identChecklist.my_addr = clientConnection->local; - if (identChecklist.fastCheck() == ACCESS_ALLOWED) + if (identChecklist.fastCheck().allowed()) Ident::Start(clientConnection, clientIdentDone, this); } #endif @@ -2505,7 +2481,7 @@ if (pools[pool].access) { ch.changeAcl(pools[pool].access); allow_t answer = ch.fastCheck(); - if (answer == ACCESS_ALLOWED) { + if (answer.allowed()) { /* request client information from db after we did all checks this will save hash lookup if client failed checks */ @@ -2737,7 +2713,7 @@ if (!connState->isOpen()) return; - if (answer == ACCESS_ALLOWED) { + if (answer.allowed()) { debugs(33, 2, "sslBump action " << Ssl::bumpMode(answer.kind) << "needed for " << connState->clientConnection); connState->sslBumpMode = static_cast(answer.kind); } else { @@ -2793,9 +2769,11 @@ return; } + MasterXaction::Pointer mx = new MasterXaction(XactionInitiator::initClient); + mx->tcpClient = clientConnection; // Create a fake HTTP request for ssl_bump ACL check, // using tproxy/intercept provided destination IP and port. - HttpRequest *request = new HttpRequest(); + HttpRequest *request = new HttpRequest(mx); static char ip[MAX_IPSTRLEN]; assert(clientConnection->flags & (COMM_TRANSPARENT | COMM_INTERCEPTION)); request->url.host(clientConnection->local.toStr(ip, sizeof(ip))); @@ -2891,7 +2869,7 @@ (ca->alg == Ssl::algSetValidBefore && certProperties.setValidBefore) ) continue; - if (ca->aclList && checklist.fastCheck(ca->aclList) == ACCESS_ALLOWED) { + if (ca->aclList && checklist.fastCheck(ca->aclList).allowed()) { const char *alg = Ssl::CertAdaptAlgorithmStr[ca->alg]; const char *param = ca->param; @@ -2914,7 +2892,7 @@ certProperties.signAlgorithm = Ssl::algSignEnd; for (sslproxy_cert_sign *sg = Config.ssl_client.cert_sign; sg != NULL; sg = sg->next) { - if (sg->aclList && checklist.fastCheck(sg->aclList) == ACCESS_ALLOWED) { + if (sg->aclList && checklist.fastCheck(sg->aclList).allowed()) { certProperties.signAlgorithm = (Ssl::CertSignAlgorithm)sg->alg; break; } @@ -3157,8 +3135,7 @@ clientConnection->tlsNegotiations()->retrieveParsedInfo(details); if (details && !details->serverName.isEmpty()) { resetSslCommonName(details->serverName.c_str()); - if (sslServerBump) - sslServerBump->clientSni = details->serverName; + tlsClientSni_ = details->serverName; } // We should disable read/write handlers @@ -3200,7 +3177,7 @@ debugs(33, 5, "Answer: " << answer << " kind:" << answer.kind); assert(connState->serverBump()); Ssl::BumpMode bumpAction; - if (answer == ACCESS_ALLOWED) { + if (answer.allowed()) { bumpAction = (Ssl::BumpMode)answer.kind; } else bumpAction = Ssl::bumpSplice; @@ -3329,22 +3306,18 @@ } void -ConnStateData::httpsPeeked(Comm::ConnectionPointer serverConnection) +ConnStateData::httpsPeeked(PinnedIdleContext pic) { Must(sslServerBump != NULL); + Must(sslServerBump->request == pic.request); + Must(pipeline.empty() || pipeline.front()->http == nullptr || pipeline.front()->http->request == pic.request.getRaw()); - if (Comm::IsConnOpen(serverConnection)) { - pinConnection(serverConnection, NULL, NULL, false); - + if (Comm::IsConnOpen(pic.connection)) { + notePinnedConnectionBecameIdle(pic); debugs(33, 5, HERE << "bumped HTTPS server: " << sslConnectHostOrIp); - } else { + } else debugs(33, 5, HERE << "Error while bumping: " << sslConnectHostOrIp); - // copy error detail from bump-server-first request to CONNECT request - if (!pipeline.empty() && pipeline.front()->http != nullptr && pipeline.front()->http->request) - pipeline.front()->http->request->detailError(sslServerBump->request->errType, sslServerBump->request->errDetail); - } - getSslContextStart(); } @@ -3391,8 +3364,8 @@ const unsigned short connectPort = clientConnection->local.port(); #if USE_OPENSSL - if (serverBump() && !serverBump()->clientSni.isEmpty()) - connectHost.assign(serverBump()->clientSni); + if (!tlsClientSni_.isEmpty()) + connectHost.assign(tlsClientSni_); else #endif { @@ -3436,9 +3409,11 @@ stream->registerWithConn(); + MasterXaction::Pointer mx = new MasterXaction(XactionInitiator::initClient); + mx->tcpClient = clientConnection; // Setup Http::Request object. Maybe should be replaced by a call to (modified) // clientProcessRequest - HttpRequest::Pointer request = new HttpRequest(); + HttpRequest::Pointer request = new HttpRequest(mx); AnyP::ProtocolType proto = (method == Http::METHOD_NONE) ? AnyP::PROTO_AUTHORITY_FORM : AnyP::PROTO_HTTP; request->url.setScheme(proto, nullptr); request->method = method; @@ -3447,23 +3422,16 @@ http->request = request.getRaw(); HTTPMSGLOCK(http->request); - request->clientConnectionManager = this; + request->manager(this, http->al); if (proto == AnyP::PROTO_HTTP) request->header.putStr(Http::HOST, useHost.c_str()); - request->flags.intercepted = ((clientConnection->flags & COMM_INTERCEPTION) != 0); - request->flags.interceptTproxy = ((clientConnection->flags & COMM_TRANSPARENT) != 0 ); + request->sources |= ((switchedToHttps() || port->transport.protocol == AnyP::PROTO_HTTPS) ? HttpMsg::srcHttps : HttpMsg::srcHttp); #if USE_AUTH if (getAuth()) request->auth_user_request = getAuth(); #endif - request->client_addr = clientConnection->remote; -#if FOLLOW_X_FORWARDED_FOR - request->indirect_client_addr = clientConnection->remote; -#endif /* FOLLOW_X_FORWARDED_FOR */ - request->my_addr = clientConnection->local; - request->myportname = port->name; inBuf = payload; flags.readMore = false; @@ -3891,19 +3859,35 @@ } void -ConnStateData::pinConnection(const Comm::ConnectionPointer &pinServer, HttpRequest *request, CachePeer *aPeer, bool auth, bool monitor) +ConnStateData::pinBusyConnection(const Comm::ConnectionPointer &pinServer, const HttpRequest::Pointer &request) { - if (!Comm::IsConnOpen(pinning.serverConnection) || - pinning.serverConnection->fd != pinServer->fd) - pinNewConnection(pinServer, request, aPeer, auth); + pinConnection(pinServer, *request); +} - if (monitor) - startPinnedConnectionMonitoring(); +void +ConnStateData::notePinnedConnectionBecameIdle(PinnedIdleContext pic) +{ + Must(pic.connection); + Must(pic.request); + pinConnection(pic.connection, *pic.request); + + // monitor pinned server connection for remote-end closures. + startPinnedConnectionMonitoring(); + + if (pipeline.empty()) + kick(); // in case clientParseRequests() was blocked by a busy pic.connection } +/// Forward future client requests using the given server connection. void -ConnStateData::pinNewConnection(const Comm::ConnectionPointer &pinServer, HttpRequest *request, CachePeer *aPeer, bool auth) +ConnStateData::pinConnection(const Comm::ConnectionPointer &pinServer, const HttpRequest &request) { + if (Comm::IsConnOpen(pinning.serverConnection) && + pinning.serverConnection->fd == pinServer->fd) { + debugs(33, 3, "already pinned" << pinServer); + return; + } + unpinConnection(true); // closes pinned connection, if any, and resets fields pinning.serverConnection = pinServer; @@ -3912,23 +3896,18 @@ Must(pinning.serverConnection != NULL); - // when pinning an SSL bumped connection, the request may be NULL const char *pinnedHost = "[unknown]"; - if (request) { - pinning.host = xstrdup(request->url.host()); - pinning.port = request->url.port(); - pinnedHost = pinning.host; - } else { - pinning.port = pinServer->remote.port(); - } + pinning.host = xstrdup(request.url.host()); + pinning.port = request.url.port(); + pinnedHost = pinning.host; pinning.pinned = true; - if (aPeer) + if (CachePeer *aPeer = pinServer->getPeer()) pinning.peer = cbdataReference(aPeer); - pinning.auth = auth; + pinning.auth = request.flags.connectionAuth; char stmp[MAX_IPSTRLEN]; char desc[FD_DESC_SZ]; snprintf(desc, FD_DESC_SZ, "%s pinned connection for %s (%d)", - (auth || !aPeer) ? pinnedHost : aPeer->name, + (pinning.auth || !pinning.peer) ? pinnedHost : pinning.peer->name, clientConnection->remote.toUrl(stmp,MAX_IPSTRLEN), clientConnection->fd); fd_note(pinning.serverConnection->fd, desc); @@ -4127,6 +4106,7 @@ /* Create a temporary ClientHttpRequest object. Its destructor will log. */ ClientHttpRequest http(this); http.req_sz = inBuf.length(); + // XXX: Or we died while waiting for the pinned connection to become idle. char const *uri = "error:transaction-end-before-headers"; http.uri = xstrdup(uri); setLogUri(&http, uri); @@ -4144,3 +4124,9 @@ ; } +std::ostream & +operator <<(std::ostream &os, const ConnStateData::PinnedIdleContext &pic) +{ + return os << pic.connection << ", request=" << pic.request; +} + diff -u -r -N squid-4.0.20/src/client_side.h squid-4.0.21/src/client_side.h --- squid-4.0.20/src/client_side.h 2017-06-02 00:49:17.000000000 +1200 +++ squid-4.0.21/src/client_side.h 2017-07-02 20:41:18.000000000 +1200 @@ -28,9 +28,14 @@ #include "ssl/support.h" #endif +#include + class ClientHttpRequest; class HttpHdrRangeSpec; +class MasterXaction; +typedef RefCount MasterXactionPointer; + #if USE_OPENSSL namespace Ssl { @@ -66,7 +71,7 @@ { public: - explicit ConnStateData(const MasterXaction::Pointer &xact); + explicit ConnStateData(const MasterXactionPointer &xact); virtual ~ConnStateData(); /* ::Server API */ @@ -155,9 +160,21 @@ bool handleRequestBodyData(); - /// Forward future client requests using the given server connection. - /// Optionally, monitor pinned server connection for remote-end closures. - void pinConnection(const Comm::ConnectionPointer &pinServerConn, HttpRequest *request, CachePeer *peer, bool auth, bool monitor = true); + /// parameters for the async notePinnedConnectionBecameIdle() call + class PinnedIdleContext + { + public: + PinnedIdleContext(const Comm::ConnectionPointer &conn, const HttpRequest::Pointer &req): connection(conn), request(req) {} + + Comm::ConnectionPointer connection; ///< to-server connection to be pinned + HttpRequest::Pointer request; ///< to-server request that initiated serverConnection + }; + + /// Called when a pinned connection becomes available for forwarding the next request. + void notePinnedConnectionBecameIdle(PinnedIdleContext pic); + /// Forward future client requests using the given to-server connection. + /// The connection is still being used by the current client request. + void pinBusyConnection(const Comm::ConnectionPointer &pinServerConn, const HttpRequest::Pointer &request); /// Undo pinConnection() and, optionally, close the pinned connection. void unpinConnection(const bool andClose); /// Returns validated pinnned server connection (and stops its monitoring). @@ -211,7 +228,7 @@ /// generated void doPeekAndSpliceStep(); /// called by FwdState when it is done bumping the server - void httpsPeeked(Comm::ConnectionPointer serverConnection); + void httpsPeeked(PinnedIdleContext pic); /// Splice a bumped client connection on peek-and-splice mode bool splice(); @@ -241,6 +258,7 @@ } const SBuf &sslCommonName() const {return sslCommonName_;} void resetSslCommonName(const char *name) {sslCommonName_ = name;} + const SBuf &tlsClientSni() const { return tlsClientSni_; } /// Fill the certAdaptParams with the required data for certificate adaptation /// and create the key for storing/retrieve the certificate to/from the cache void buildSslCertGenerationParams(Ssl::CertificateProperties &certProperties); @@ -342,7 +360,7 @@ void clientAfterReadingRequests(); bool concurrentRequestQueueFilled() const; - void pinNewConnection(const Comm::ConnectionPointer &pinServer, HttpRequest *request, CachePeer *aPeer, bool auth); + void pinConnection(const Comm::ConnectionPointer &pinServerConn, const HttpRequest &request); /* PROXY protocol functionality */ bool proxyProtocolValidateClient(); @@ -369,6 +387,9 @@ /// 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 SBuf sslCommonName_; ///< CN name for SSL certificate generation + + /// TLS client delivered SNI value. Empty string if none has been received. + SBuf tlsClientSni_; String sslBumpCertKey; ///< Key to use to store/retrieve generated certificate /// HTTPS server cert. fetching state for bump-ssl-server-first @@ -418,5 +439,7 @@ void clientProcessRequest(ConnStateData *, const Http1::RequestParserPointer &, Http::Stream *); void clientPostHttpsAccept(ConnStateData *); +std::ostream &operator <<(std::ostream &os, const ConnStateData::PinnedIdleContext &pic); + #endif /* SQUID_CLIENTSIDE_H */ diff -u -r -N squid-4.0.20/src/client_side_reply.cc squid-4.0.21/src/client_side_reply.cc --- squid-4.0.20/src/client_side_reply.cc 2017-06-02 00:49:17.000000000 +1200 +++ squid-4.0.21/src/client_side_reply.cc 2017-07-02 20:41:18.000000000 +1200 @@ -89,6 +89,7 @@ reply(NULL), old_entry(NULL), old_sc(NULL), + old_lastmod(-1), deleting(false), collapsedRevalidation(crNone) { @@ -204,6 +205,8 @@ debugs(88, 3, "clientReplyContext::saveState: saving store context"); old_entry = http->storeEntry(); old_sc = sc; + old_lastmod = http->request->lastmod; + old_etag = http->request->etag; old_reqsize = reqsize; tempBuffer.offset = reqofs; /* Prevent accessing the now saved entries */ @@ -223,9 +226,13 @@ sc = old_sc; reqsize = old_reqsize; reqofs = tempBuffer.offset; + http->request->lastmod = old_lastmod; + http->request->etag = old_etag; /* Prevent accessed the old saved entries */ old_entry = NULL; old_sc = NULL; + old_lastmod = -1; + old_etag.clean(); old_reqsize = 0; tempBuffer.offset = 0; } @@ -415,8 +422,8 @@ if (result.flags.error && !EBIT_TEST(http->storeEntry()->flags, ENTRY_ABORTED)) return; - if (collapsedRevalidation == crSlave && EBIT_TEST(http->storeEntry()->flags, KEY_PRIVATE)) { - debugs(88, 3, "CF slave hit private " << *http->storeEntry() << ". MISS"); + if (collapsedRevalidation == crSlave && !http->storeEntry()->mayStartHitting()) { + debugs(88, 3, "CF slave hit private non-shareable " << *http->storeEntry() << ". MISS"); // restore context to meet processMiss() expectations restoreState(); http->logType = LOG_TCP_MISS; @@ -548,7 +555,7 @@ // The previously identified hit suddenly became unsharable! // This is common for collapsed forwarding slaves but might also // happen to regular hits because we are called asynchronously. - if (EBIT_TEST(e->flags, KEY_PRIVATE)) { + if (!e->mayStartHitting()) { debugs(88, 3, "unsharable " << *e << ". MISS"); http->logType = LOG_TCP_MISS; processMiss(); @@ -746,10 +753,13 @@ return; } + Comm::ConnectionPointer conn = http->getConn() != nullptr ? http->getConn()->clientConnection : nullptr; /// Deny loops if (r->flags.loopDetected) { http->al->http.code = Http::scForbidden; - err = clientBuildError(ERR_ACCESS_DENIED, Http::scForbidden, NULL, http->getConn()->clientConnection->remote, http->request); + Ip::Address tmp_noaddr; + tmp_noaddr.setNoAddr(); + err = clientBuildError(ERR_ACCESS_DENIED, Http::scForbidden, nullptr, conn ? conn->remote : tmp_noaddr, http->request); createStoreEntry(r->method, RequestFlags()); errorAppendEntry(http->storeEntry(), err); triggerInitialStoreRead(); @@ -772,7 +782,6 @@ assert(r->clientConnectionManager == http->getConn()); /** Start forwarding to get the new object from network */ - Comm::ConnectionPointer conn = http->getConn() != NULL ? http->getConn()->clientConnection : NULL; FwdState::Start(conn, http->storeEntry(), r, http->al); } } @@ -788,8 +797,11 @@ { debugs(88, 4, http->request->method << ' ' << http->uri); http->al->http.code = Http::scGatewayTimeout; + Ip::Address tmp_noaddr; + tmp_noaddr.setNoAddr(); ErrorState *err = clientBuildError(ERR_ONLY_IF_CACHED_MISS, Http::scGatewayTimeout, NULL, - http->getConn()->clientConnection->remote, http->request); + http->getConn() ? http->getConn()->clientConnection->remote : tmp_noaddr, + http->request); removeClientStoreReference(&sc, http); startError(err); } @@ -861,7 +873,7 @@ std::unique_ptr chl(clientAclChecklistCreate(Config.accessList.sendHit, http)); chl->reply = const_cast(rep); // ACLChecklist API bug HTTPMSGLOCK(chl->reply); - return chl->fastCheck() != ACCESS_ALLOWED; // when in doubt, block + return !chl->fastCheck().allowed(); // when in doubt, block } // This does not happen, I hope, because we are called from CacheHit, which @@ -967,8 +979,11 @@ if (EBIT_TEST(entry->flags, ENTRY_SPECIAL)) { http->logType = LOG_TCP_DENIED; + Ip::Address tmp_noaddr; + tmp_noaddr.setNoAddr(); // TODO: make a global const ErrorState *err = clientBuildError(ERR_ACCESS_DENIED, Http::scForbidden, NULL, - http->getConn()->clientConnection->remote, http->request); + http->getConn() ? http->getConn()->clientConnection->remote : tmp_noaddr, + http->request); startError(err); return; // XXX: leaking unused entry if some store does not keep it } @@ -1005,7 +1020,10 @@ if (!Config2.onoff.enable_purge) { http->logType = LOG_TCP_DENIED; - ErrorState *err = clientBuildError(ERR_ACCESS_DENIED, Http::scForbidden, NULL, http->getConn()->clientConnection->remote, http->request); + Ip::Address tmp_noaddr; + tmp_noaddr.setNoAddr(); + ErrorState *err = clientBuildError(ERR_ACCESS_DENIED, Http::scForbidden, NULL, + http->getConn() ? http->getConn()->clientConnection->remote : tmp_noaddr, http->request); startError(err); return; } @@ -1224,7 +1242,8 @@ #if SIZEOF_INT64_T == 4 if (http->out.size > 0x7FFF0000) { debugs(88, DBG_IMPORTANT, "WARNING: closing FD " << fd << " to prevent out.size counter overflow"); - debugs(88, DBG_IMPORTANT, "\tclient " << http->getConn()->peer); + if (http->getConn()) + debugs(88, DBG_IMPORTANT, "\tclient " << http->getConn()->peer); debugs(88, DBG_IMPORTANT, "\treceived " << http->out.size << " bytes"); debugs(88, DBG_IMPORTANT, "\tURI " << http->log_uri); return 1; @@ -1232,7 +1251,8 @@ if (http->out.offset > 0x7FFF0000) { debugs(88, DBG_IMPORTANT, "WARNING: closing FD " << fd < " to prevent out.offset counter overflow"); - debugs(88, DBG_IMPORTANT, "\tclient " << http->getConn()->peer); + if (http->getConn()) + debugs(88, DBG_IMPORTANT, "\tclient " << http->getConn()->peer); debugs(88, DBG_IMPORTANT, "\treceived " << http->out.size << " bytes, offset " << http->out.offset); debugs(88, DBG_IMPORTANT, "\tURI " << http->log_uri); return 1; @@ -1852,12 +1872,14 @@ assert(http->out.size == 0); assert(http->out.offset == 0); - if (Ip::Qos::TheConfig.isHitTosActive()) { - Ip::Qos::doTosLocalHit(http->getConn()->clientConnection); - } + if (ConnStateData *conn = http->getConn()) { + if (Ip::Qos::TheConfig.isHitTosActive()) { + Ip::Qos::doTosLocalHit(conn->clientConnection); + } - if (Ip::Qos::TheConfig.isHitNfmarkActive()) { - Ip::Qos::doNfmarkLocalHit(http->getConn()->clientConnection); + if (Ip::Qos::TheConfig.isHitNfmarkActive()) { + Ip::Qos::doNfmarkLocalHit(conn->clientConnection); + } } localTempBuffer.offset = reqofs; @@ -1971,9 +1993,11 @@ clientReplyContext::sendPreconditionFailedError() { http->logType = LOG_TCP_HIT; + Ip::Address tmp_noaddr; + tmp_noaddr.setNoAddr(); ErrorState *const err = clientBuildError(ERR_PRECONDITION_FAILED, Http::scPreconditionFailed, - NULL, http->getConn()->clientConnection->remote, http->request); + NULL, http->getConn() ? http->getConn()->clientConnection->remote : tmp_noaddr, http->request); removeClientStoreReference(&sc, http); HTTPMSGUNLOCK(reply); startError(err); @@ -2072,7 +2096,7 @@ << ' ' << http->uri << " is " << accessAllowed << ", because it matched " << (AclMatchedName ? AclMatchedName : "NO ACL's")); - if (accessAllowed != ACCESS_ALLOWED) { + if (!accessAllowed.allowed()) { ErrorState *err; err_type page_id; page_id = aclGetDenyInfoPage(&Config.denyInfoList, AclMatchedName, 1); @@ -2272,7 +2296,8 @@ */ if (http->request == NULL) { - http->request = new HttpRequest(m, AnyP::PROTO_NONE, "http", null_string); + const MasterXaction::Pointer mx = new MasterXaction(XactionInitiator::initClient); + http->request = new HttpRequest(m, AnyP::PROTO_NONE, "http", null_string, mx); HTTPMSGLOCK(http->request); } diff -u -r -N squid-4.0.20/src/client_side_reply.h squid-4.0.21/src/client_side_reply.h --- squid-4.0.20/src/client_side_reply.h 2017-06-02 00:49:17.000000000 +1200 +++ squid-4.0.21/src/client_side_reply.h 2017-07-02 20:41:18.000000000 +1200 @@ -131,7 +131,11 @@ void sendNotModifiedOrPreconditionFailedError(); StoreEntry *old_entry; - store_client *old_sc; /* ... for entry to be validated */ + /* ... for entry to be validated */ + store_client *old_sc; + time_t old_lastmod; + String old_etag; + bool deleting; typedef enum { diff -u -r -N squid-4.0.20/src/client_side_request.cc squid-4.0.21/src/client_side_request.cc --- squid-4.0.20/src/client_side_request.cc 2017-06-02 00:49:17.000000000 +1200 +++ squid-4.0.21/src/client_side_request.cc 2017-07-02 20:41:18.000000000 +1200 @@ -320,7 +320,7 @@ int clientBeginRequest(const HttpRequestMethod& method, char const *url, CSCB * streamcallback, CSD * streamdetach, ClientStreamData streamdata, HttpHeader const *header, - char *tailbuf, size_t taillen) + char *tailbuf, size_t taillen, const MasterXaction::Pointer &mx) { size_t url_sz; ClientHttpRequest *http = new ClientHttpRequest(NULL); @@ -346,15 +346,15 @@ http->uri = (char *)xcalloc(url_sz, 1); strcpy(http->uri, url); - if ((request = HttpRequest::CreateFromUrl(http->uri, method)) == NULL) { + if ((request = HttpRequest::FromUrl(http->uri, mx, method)) == NULL) { debugs(85, 5, "Invalid URL: " << http->uri); return -1; } /* - * now update the headers in request with our supplied headers. urlParse - * should return a blank header set, but we use Update to be sure of - * correctness. + * now update the headers in request with our supplied headers. + * HttpRequest::FromUrl() should return a blank header set, but + * we use Update to be sure of correctness. */ if (header) request->header.update(header); @@ -368,8 +368,6 @@ */ request->flags.accelerated = http->flags.accel; - request->flags.internalClient = true; - /* this is an internally created * request, not subject to acceleration * target overrides */ @@ -451,13 +449,7 @@ ClientHttpRequest *http = calloutContext->http; HttpRequest *request = http->request; - /* - * answer should be be ACCESS_ALLOWED or ACCESS_DENIED if we are - * called as a result of ACL checks, or -1 if we are called when - * there's nothing left to do. - */ - if (answer == ACCESS_ALLOWED && - request->x_forwarded_for_iterator.size () != 0) { + if (answer.allowed() && request->x_forwarded_for_iterator.size() != 0) { /* * Remove the last comma-delimited element from the @@ -499,8 +491,7 @@ calloutContext->acl_checklist->nonBlockingCheck(clientFollowXForwardedForCheck, data); return; } - } /*if (answer == ACCESS_ALLOWED && - request->x_forwarded_for_iterator.size () != 0)*/ + } /* clean up, and pass control to clientAccessCheck */ if (Config.onoff.log_uses_indirect_client) { @@ -515,7 +506,7 @@ request->x_forwarded_for_iterator.clean(); request->flags.done_follow_x_forwarded_for = true; - if (answer != ACCESS_ALLOWED && answer != ACCESS_DENIED) { + if (!answer.someRuleMatched()) { debugs(28, DBG_CRITICAL, "ERROR: Processing X-Forwarded-For. Stopping at IP address: " << request->indirect_client_addr ); } @@ -771,7 +762,7 @@ proxy_auth_msg = http->request->auth_user_request->denyMessage(""); #endif - if (answer != ACCESS_ALLOWED) { + if (!answer.allowed()) { // auth has a grace period where credentials can be expired but okay not to challenge. /* Send an auth challenge or error */ @@ -882,7 +873,7 @@ ClientHttpRequest *http = context->http; context->acl_checklist = NULL; - if (answer == ACCESS_ALLOWED) + if (answer.allowed()) redirectStart(http, clientRedirectDoneWrapper, context); else { Helper::Reply const nilReply(Helper::Error); @@ -913,7 +904,7 @@ ClientHttpRequest *http = context->http; context->acl_checklist = NULL; - if (answer == ACCESS_ALLOWED) + if (answer.allowed()) storeIdStart(http, clientStoreIdDoneWrapper, context); else { debugs(85, 3, "access denied expected ERR reply handling: " << answer); @@ -1273,10 +1264,10 @@ // prevent broken helpers causing too much damage. If old URL == new URL skip the re-write. if (urlNote != NULL && strcmp(urlNote, http->uri)) { - // XXX: validate the URL properly *without* generating a whole new request object right here. - // XXX: the clone() should be done only AFTER we know the new URL is valid. - HttpRequest *new_request = old_request->clone(); - if (urlParse(old_request->method, const_cast(urlNote), new_request)) { + URL tmpUrl; + if (tmpUrl.parse(old_request->method, const_cast(urlNote))) { + HttpRequest *new_request = old_request->clone(); + new_request->url = tmpUrl; debugs(61, 2, "URL-rewriter diverts URL from " << old_request->effectiveRequestUri() << " to " << new_request->effectiveRequestUri()); // update the new request to flag the re-writing was done on it @@ -1298,7 +1289,6 @@ } else { debugs(85, DBG_CRITICAL, "ERROR: URL-rewrite produces invalid request: " << old_request->method << " " << urlNote << " " << old_request->http_ver); - delete new_request; } } } @@ -1399,7 +1389,7 @@ ClientRequestContext::checkNoCacheDone(const allow_t &answer) { acl_checklist = NULL; - if (answer == ACCESS_DENIED) { + if (answer.denied()) { http->request->flags.noCache = true; // dont read reply from cache http->request->flags.cachable = false; // dont store reply into cache } @@ -1498,7 +1488,7 @@ if (!httpStateIsValid()) return; - const Ssl::BumpMode bumpMode = answer == ACCESS_ALLOWED ? + const Ssl::BumpMode bumpMode = answer.allowed() ? static_cast(answer.kind) : Ssl::bumpSplice; http->sslBumpNeed(bumpMode); // for processRequest() to bump if needed http->al->ssl.bumpMode = bumpMode; // for logging diff -u -r -N squid-4.0.20/src/client_side_request.h squid-4.0.21/src/client_side_request.h --- squid-4.0.20/src/client_side_request.h 2017-06-02 00:49:17.000000000 +1200 +++ squid-4.0.21/src/client_side_request.h 2017-07-02 20:41:18.000000000 +1200 @@ -13,6 +13,7 @@ #include "acl/forward.h" #include "client_side.h" #include "clientStream.h" +#include "http/forward.h" #include "HttpHeaderRange.h" #include "LogTags.h" @@ -27,7 +28,7 @@ class MemObject; /* client_side_request.c - client side request related routines (pure logic) */ -int clientBeginRequest(const HttpRequestMethod&, char const *, CSCB *, CSD *, ClientStreamData, HttpHeader const *, char *, size_t); +int clientBeginRequest(const HttpRequestMethod&, char const *, CSCB *, CSD *, ClientStreamData, HttpHeader const *, char *, size_t, const MasterXactionPointer &); class ClientHttpRequest #if USE_ADAPTATION diff -u -r -N squid-4.0.20/src/comm/Makefile.in squid-4.0.21/src/comm/Makefile.in --- squid-4.0.20/src/comm/Makefile.in 2017-06-02 00:58:52.000000000 +1200 +++ squid-4.0.21/src/comm/Makefile.in 2017-07-02 20:41:26.000000000 +1200 @@ -1,7 +1,7 @@ -# Makefile.in generated by automake 1.15 from Makefile.am. +# Makefile.in generated by automake 1.15.1 from Makefile.am. # @configure_input@ -# Copyright (C) 1994-2014 Free Software Foundation, Inc. +# Copyright (C) 1994-2017 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, diff -u -r -N squid-4.0.20/src/comm/TcpAcceptor.cc squid-4.0.21/src/comm/TcpAcceptor.cc --- squid-4.0.20/src/comm/TcpAcceptor.cc 2017-06-02 00:49:17.000000000 +1200 +++ squid-4.0.21/src/comm/TcpAcceptor.cc 2017-07-02 20:41:18.000000000 +1200 @@ -328,7 +328,7 @@ if (theCallSub != NULL) { AsyncCall::Pointer call = theCallSub->callback(); CommAcceptCbParams ¶ms = GetCommParams(call); - params.xaction = new MasterXaction; + params.xaction = new MasterXaction(XactionInitiator::initClient); params.xaction->squidPort = listenPort_; params.fd = conn->fd; params.conn = params.xaction->tcpClient = newConnDetails; diff -u -r -N squid-4.0.20/src/defines.h squid-4.0.21/src/defines.h --- squid-4.0.20/src/defines.h 2017-06-02 00:49:17.000000000 +1200 +++ squid-4.0.21/src/defines.h 2017-07-02 20:41:18.000000000 +1200 @@ -93,8 +93,6 @@ #define NTLM_CHALLENGE_SZ 300 -#define CONNECT_PORT 443 - #define current_stacksize(stack) ((stack)->top - (stack)->base) /* logfile status */ diff -u -r -N squid-4.0.20/src/DelayId.cc squid-4.0.21/src/DelayId.cc --- squid-4.0.20/src/DelayId.cc 2017-06-02 00:49:17.000000000 +1200 +++ squid-4.0.21/src/DelayId.cc 2017-07-02 20:41:18.000000000 +1200 @@ -101,7 +101,7 @@ if (http->getConn() != NULL) ch.conn(http->getConn()); - if (DelayPools::delay_data[pool].theComposite().getRaw() && ch.fastCheck() == ACCESS_ALLOWED) { + if (DelayPools::delay_data[pool].theComposite().getRaw() && ch.fastCheck().allowed()) { DelayId result (pool + 1); CompositePoolNode::CompositeSelectionDetails details; diff -u -r -N squid-4.0.20/src/DiskIO/AIO/Makefile.in squid-4.0.21/src/DiskIO/AIO/Makefile.in --- squid-4.0.20/src/DiskIO/AIO/Makefile.in 2017-06-02 00:53:26.000000000 +1200 +++ squid-4.0.21/src/DiskIO/AIO/Makefile.in 2017-07-02 20:41:24.000000000 +1200 @@ -1,7 +1,7 @@ -# Makefile.in generated by automake 1.15 from Makefile.am. +# Makefile.in generated by automake 1.15.1 from Makefile.am. # @configure_input@ -# Copyright (C) 1994-2014 Free Software Foundation, Inc. +# Copyright (C) 1994-2017 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, diff -u -r -N squid-4.0.20/src/DiskIO/Blocking/Makefile.in squid-4.0.21/src/DiskIO/Blocking/Makefile.in --- squid-4.0.20/src/DiskIO/Blocking/Makefile.in 2017-06-02 00:53:29.000000000 +1200 +++ squid-4.0.21/src/DiskIO/Blocking/Makefile.in 2017-07-02 20:41:24.000000000 +1200 @@ -1,7 +1,7 @@ -# Makefile.in generated by automake 1.15 from Makefile.am. +# Makefile.in generated by automake 1.15.1 from Makefile.am. # @configure_input@ -# Copyright (C) 1994-2014 Free Software Foundation, Inc. +# Copyright (C) 1994-2017 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, diff -u -r -N squid-4.0.20/src/DiskIO/DiskDaemon/Makefile.in squid-4.0.21/src/DiskIO/DiskDaemon/Makefile.in --- squid-4.0.20/src/DiskIO/DiskDaemon/Makefile.in 2017-06-02 00:53:34.000000000 +1200 +++ squid-4.0.21/src/DiskIO/DiskDaemon/Makefile.in 2017-07-02 20:41:24.000000000 +1200 @@ -1,7 +1,7 @@ -# Makefile.in generated by automake 1.15 from Makefile.am. +# Makefile.in generated by automake 1.15.1 from Makefile.am. # @configure_input@ -# Copyright (C) 1994-2014 Free Software Foundation, Inc. +# Copyright (C) 1994-2017 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, diff -u -r -N squid-4.0.20/src/DiskIO/DiskThreads/Makefile.in squid-4.0.21/src/DiskIO/DiskThreads/Makefile.in --- squid-4.0.20/src/DiskIO/DiskThreads/Makefile.in 2017-06-02 00:53:43.000000000 +1200 +++ squid-4.0.21/src/DiskIO/DiskThreads/Makefile.in 2017-07-02 20:41:24.000000000 +1200 @@ -1,7 +1,7 @@ -# Makefile.in generated by automake 1.15 from Makefile.am. +# Makefile.in generated by automake 1.15.1 from Makefile.am. # @configure_input@ -# Copyright (C) 1994-2014 Free Software Foundation, Inc. +# Copyright (C) 1994-2017 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, diff -u -r -N squid-4.0.20/src/DiskIO/IpcIo/Makefile.in squid-4.0.21/src/DiskIO/IpcIo/Makefile.in --- squid-4.0.20/src/DiskIO/IpcIo/Makefile.in 2017-06-02 00:53:52.000000000 +1200 +++ squid-4.0.21/src/DiskIO/IpcIo/Makefile.in 2017-07-02 20:41:24.000000000 +1200 @@ -1,7 +1,7 @@ -# Makefile.in generated by automake 1.15 from Makefile.am. +# Makefile.in generated by automake 1.15.1 from Makefile.am. # @configure_input@ -# Copyright (C) 1994-2014 Free Software Foundation, Inc. +# Copyright (C) 1994-2017 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, diff -u -r -N squid-4.0.20/src/DiskIO/Makefile.in squid-4.0.21/src/DiskIO/Makefile.in --- squid-4.0.20/src/DiskIO/Makefile.in 2017-06-02 00:53:57.000000000 +1200 +++ squid-4.0.21/src/DiskIO/Makefile.in 2017-07-02 20:41:24.000000000 +1200 @@ -1,7 +1,7 @@ -# Makefile.in generated by automake 1.15 from Makefile.am. +# Makefile.in generated by automake 1.15.1 from Makefile.am. # @configure_input@ -# Copyright (C) 1994-2014 Free Software Foundation, Inc. +# Copyright (C) 1994-2017 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, diff -u -r -N squid-4.0.20/src/DiskIO/Mmapped/Makefile.in squid-4.0.21/src/DiskIO/Mmapped/Makefile.in --- squid-4.0.20/src/DiskIO/Mmapped/Makefile.in 2017-06-02 00:54:02.000000000 +1200 +++ squid-4.0.21/src/DiskIO/Mmapped/Makefile.in 2017-07-02 20:41:24.000000000 +1200 @@ -1,7 +1,7 @@ -# Makefile.in generated by automake 1.15 from Makefile.am. +# Makefile.in generated by automake 1.15.1 from Makefile.am. # @configure_input@ -# Copyright (C) 1994-2014 Free Software Foundation, Inc. +# Copyright (C) 1994-2017 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, diff -u -r -N squid-4.0.20/src/dns/Makefile.in squid-4.0.21/src/dns/Makefile.in --- squid-4.0.20/src/dns/Makefile.in 2017-06-02 00:58:58.000000000 +1200 +++ squid-4.0.21/src/dns/Makefile.in 2017-07-02 20:41:26.000000000 +1200 @@ -1,7 +1,7 @@ -# Makefile.in generated by automake 1.15 from Makefile.am. +# Makefile.in generated by automake 1.15.1 from Makefile.am. # @configure_input@ -# Copyright (C) 1994-2014 Free Software Foundation, Inc. +# Copyright (C) 1994-2017 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, diff -u -r -N squid-4.0.20/src/Downloader.cc squid-4.0.21/src/Downloader.cc --- squid-4.0.20/src/Downloader.cc 2017-06-02 00:49:17.000000000 +1200 +++ squid-4.0.21/src/Downloader.cc 2017-07-02 20:41:18.000000000 +1200 @@ -63,11 +63,12 @@ os << " Http Status:" << status << Raw("body data", object.rawContent(), 64).hex(); } -Downloader::Downloader(SBuf &url, AsyncCall::Pointer &aCallback, unsigned int level): +Downloader::Downloader(SBuf &url, AsyncCall::Pointer &aCallback, const XactionInitiator initiator, unsigned int level): AsyncJob("Downloader"), url_(url), callback_(aCallback), - level_(level) + level_(level), + initiator_(initiator) { } @@ -128,7 +129,8 @@ const HttpRequestMethod method = Http::METHOD_GET; char *uri = xstrdup(url_.c_str()); - HttpRequest *const request = HttpRequest::CreateFromUrl(uri, method); + const MasterXaction::Pointer mx = new MasterXaction(initiator_); + HttpRequest *const request = HttpRequest::FromUrl(uri, mx, method); if (!request) { debugs(33, 5, "Invalid URI: " << url_); xfree(uri); @@ -137,7 +139,6 @@ request->http_ver = Http::ProtocolVersion(); request->header.putStr(Http::HdrType::HOST, request->url.host()); request->header.putTime(Http::HdrType::DATE, squid_curtime); - request->flags.internalClient = true; request->client_addr.setNoAddr(); #if FOLLOW_X_FORWARDED_FOR request->indirect_client_addr.setNoAddr(); diff -u -r -N squid-4.0.20/src/Downloader.h squid-4.0.21/src/Downloader.h --- squid-4.0.20/src/Downloader.h 2017-06-02 00:49:17.000000000 +1200 +++ squid-4.0.21/src/Downloader.h 2017-07-02 20:41:18.000000000 +1200 @@ -14,6 +14,7 @@ #include "http/forward.h" #include "http/StatusCode.h" #include "sbuf/SBuf.h" +#include "XactionInitiator.h" class ClientHttpRequest; class StoreIOBuffer; @@ -45,7 +46,7 @@ Http::StatusCode status; }; - Downloader(SBuf &url, AsyncCall::Pointer &aCallback, unsigned int level = 0); + Downloader(SBuf &url, AsyncCall::Pointer &aCallback, const XactionInitiator initiator, unsigned int level = 0); virtual ~Downloader(); virtual void swanSong(); @@ -75,6 +76,8 @@ AsyncCall::Pointer callback_; ///< callback to call when download finishes SBuf object_; ///< the object body data const unsigned int level_; ///< holds the nested downloads level + /// The initiator of the download request. + XactionInitiator initiator_; /// Pointer to an object that stores the clientStream required info DownloaderContextPointer context_; diff -u -r -N squid-4.0.20/src/esi/Include.cc squid-4.0.21/src/esi/Include.cc --- squid-4.0.20/src/esi/Include.cc 2017-06-02 00:49:17.000000000 +1200 +++ squid-4.0.21/src/esi/Include.cc 2017-07-02 20:41:18.000000000 +1200 @@ -299,8 +299,8 @@ char const *tempUrl = vars->extractChar (); debugs(86, 5, "ESIIncludeStart: Starting subrequest with url '" << tempUrl << "'"); - - if (clientBeginRequest(Http::METHOD_GET, tempUrl, esiBufferRecipient, esiBufferDetach, stream.getRaw(), &tempheaders, stream->localbuffer->buf, HTTP_REQBUF_SZ)) { + const MasterXaction::Pointer mx = new MasterXaction(XactionInitiator::initEsi); + if (clientBeginRequest(Http::METHOD_GET, tempUrl, esiBufferRecipient, esiBufferDetach, stream.getRaw(), &tempheaders, stream->localbuffer->buf, HTTP_REQBUF_SZ, mx)) { debugs(86, DBG_CRITICAL, "starting new ESI subrequest failed"); } diff -u -r -N squid-4.0.20/src/esi/Makefile.in squid-4.0.21/src/esi/Makefile.in --- squid-4.0.20/src/esi/Makefile.in 2017-06-02 00:59:03.000000000 +1200 +++ squid-4.0.21/src/esi/Makefile.in 2017-07-02 20:41:26.000000000 +1200 @@ -1,7 +1,7 @@ -# Makefile.in generated by automake 1.15 from Makefile.am. +# Makefile.in generated by automake 1.15.1 from Makefile.am. # @configure_input@ -# Copyright (C) 1994-2014 Free Software Foundation, Inc. +# Copyright (C) 1994-2017 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, diff -u -r -N squid-4.0.20/src/eui/Makefile.in squid-4.0.21/src/eui/Makefile.in --- squid-4.0.20/src/eui/Makefile.in 2017-06-02 00:59:10.000000000 +1200 +++ squid-4.0.21/src/eui/Makefile.in 2017-07-02 20:41:26.000000000 +1200 @@ -1,7 +1,7 @@ -# Makefile.in generated by automake 1.15 from Makefile.am. +# Makefile.in generated by automake 1.15.1 from Makefile.am. # @configure_input@ -# Copyright (C) 1994-2014 Free Software Foundation, Inc. +# Copyright (C) 1994-2017 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, diff -u -r -N squid-4.0.20/src/external_acl.cc squid-4.0.21/src/external_acl.cc --- squid-4.0.20/src/external_acl.cc 2017-06-02 00:49:17.000000000 +1200 +++ squid-4.0.21/src/external_acl.cc 2017-07-02 20:41:18.000000000 +1200 @@ -456,7 +456,7 @@ if (result == ACCESS_DUNNO) return false; // non-cacheable response - if ((result == ACCESS_ALLOWED ? ttl : negative_ttl) <= 0) + if ((result.allowed() ? ttl : negative_ttl) <= 0) return false; // not caching this type of response return true; @@ -615,7 +615,7 @@ /* Make sure the user is authenticated */ debugs(82, 3, HERE << acl->def->name << " check user authenticated."); const allow_t ti = AuthenticateAcl(ch); - if (ti != ACCESS_ALLOWED) { + if (!ti.allowed()) { debugs(82, 2, HERE << acl->def->name << " user not authenticated (" << ti << ")"); return ti; } @@ -802,7 +802,7 @@ if (def->cache_size <= 0 || entry->result == ACCESS_DUNNO) return 1; - if (entry->date + (entry->result == ACCESS_ALLOWED ? def->ttl : def->negative_ttl) < squid_curtime) + if (entry->date + (entry->result.allowed() ? def->ttl : def->negative_ttl) < squid_curtime) return 1; else return 0; @@ -815,7 +815,7 @@ return 1; int ttl; - ttl = entry->result == ACCESS_ALLOWED ? def->ttl : def->negative_ttl; + ttl = entry->result.allowed() ? def->ttl : def->negative_ttl; ttl = (ttl * (100 - def->grace)) / 100; if (entry->date + ttl <= squid_curtime) @@ -1149,17 +1149,6 @@ checklist->resumeNonBlockingCheck(ExternalACLLookup::Instance()); } -/* This registers "external" in the registry. To do dynamic definitions - * of external ACL's, rather than a static prototype, have a Prototype instance - * prototype in the class that defines each external acl 'class'. - * Then, then the external acl instance is created, it self registers under - * it's name. - * Be sure that clone is fully functional for that acl class though! - */ -ACL::Prototype ACLExternal::RegistryProtoype(&ACLExternal::RegistryEntry_, "external"); - -ACLExternal ACLExternal::RegistryEntry_("external"); - ACL * ACLExternal::clone() const { diff -u -r -N squid-4.0.20/src/ExternalACL.h squid-4.0.21/src/ExternalACL.h --- squid-4.0.20/src/ExternalACL.h 2017-06-02 00:49:17.000000000 +1200 +++ squid-4.0.21/src/ExternalACL.h 2017-07-02 20:41:18.000000000 +1200 @@ -62,8 +62,6 @@ virtual bool empty () const; protected: - static Prototype RegistryProtoype; - static ACLExternal RegistryEntry_; external_acl_data *data; char const *class_; }; diff -u -r -N squid-4.0.20/src/format/Format.cc squid-4.0.21/src/format/Format.cc --- squid-4.0.20/src/format/Format.cc 2017-06-02 00:49:17.000000000 +1200 +++ squid-4.0.21/src/format/Format.cc 2017-07-02 20:41:18.000000000 +1200 @@ -1236,9 +1236,11 @@ case LFT_SSL_CLIENT_SNI: if (al->request && al->request->clientConnectionManager.valid()) { - if (Ssl::ServerBump * srvBump = al->request->clientConnectionManager->serverBump()) { - if (!srvBump->clientSni.isEmpty()) - out = srvBump->clientSni.c_str(); + if (const ConnStateData *conn = al->request->clientConnectionManager.get()) { + if (!conn->tlsClientSni().isEmpty()) { + sb = conn->tlsClientSni(); + out = sb.c_str(); + } } } break; diff -u -r -N squid-4.0.20/src/format/Makefile.in squid-4.0.21/src/format/Makefile.in --- squid-4.0.20/src/format/Makefile.in 2017-06-02 00:59:17.000000000 +1200 +++ squid-4.0.21/src/format/Makefile.in 2017-07-02 20:41:26.000000000 +1200 @@ -1,7 +1,7 @@ -# Makefile.in generated by automake 1.15 from Makefile.am. +# Makefile.in generated by automake 1.15.1 from Makefile.am. # @configure_input@ -# Copyright (C) 1994-2014 Free Software Foundation, Inc. +# Copyright (C) 1994-2017 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, diff -u -r -N squid-4.0.20/src/format/Token.cc squid-4.0.21/src/format/Token.cc --- squid-4.0.20/src/format/Token.cc 2017-06-02 00:49:17.000000000 +1200 +++ squid-4.0.21/src/format/Token.cc 2017-07-02 20:41:18.000000000 +1200 @@ -210,7 +210,7 @@ #endif #if USE_OPENSSL -// SSL (ssl::) tokens +// TLS/SSL (tls:: or ssl::) tokens static TokenTableEntry TokenTableSsl[] = { TokenTableEntry("bump_mode", LFT_SSL_BUMP_MODE), TokenTableEntry(">cert_subject", LFT_SSL_USER_CERT_SUBJECT), @@ -245,6 +245,7 @@ TheConfig.registerTokens(String("icap"),::Format::TokenTableIcap); #endif #if USE_OPENSSL + TheConfig.registerTokens(String("tls"),::Format::TokenTableSsl); TheConfig.registerTokens(String("ssl"),::Format::TokenTableSsl); #endif } diff -u -r -N squid-4.0.20/src/fs/Makefile.in squid-4.0.21/src/fs/Makefile.in --- squid-4.0.20/src/fs/Makefile.in 2017-06-02 00:59:23.000000000 +1200 +++ squid-4.0.21/src/fs/Makefile.in 2017-07-02 20:41:26.000000000 +1200 @@ -1,7 +1,7 @@ -# Makefile.in generated by automake 1.15 from Makefile.am. +# Makefile.in generated by automake 1.15.1 from Makefile.am. # @configure_input@ -# Copyright (C) 1994-2014 Free Software Foundation, Inc. +# Copyright (C) 1994-2017 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, diff -u -r -N squid-4.0.20/src/fs/rock/RockSwapDir.cc squid-4.0.21/src/fs/rock/RockSwapDir.cc --- squid-4.0.20/src/fs/rock/RockSwapDir.cc 2017-06-02 00:49:17.000000000 +1200 +++ squid-4.0.21/src/fs/rock/RockSwapDir.cc 2017-07-02 20:41:18.000000000 +1200 @@ -137,7 +137,7 @@ e.ping_status = PING_NONE; EBIT_CLR(e.flags, RELEASE_REQUEST); - EBIT_CLR(e.flags, KEY_PRIVATE); + e.clearPrivate(); EBIT_SET(e.flags, ENTRY_VALIDATED); e.swap_dirn = index; diff -u -r -N squid-4.0.20/src/fs/ufs/UFSSwapDir.cc squid-4.0.21/src/fs/ufs/UFSSwapDir.cc --- squid-4.0.20/src/fs/ufs/UFSSwapDir.cc 2017-06-02 00:49:17.000000000 +1200 +++ squid-4.0.21/src/fs/ufs/UFSSwapDir.cc 2017-07-02 20:41:18.000000000 +1200 @@ -812,7 +812,7 @@ e->refcount = refcount; e->flags = newFlags; EBIT_CLR(e->flags, RELEASE_REQUEST); - EBIT_CLR(e->flags, KEY_PRIVATE); + e->clearPrivate(); e->ping_status = PING_NONE; EBIT_CLR(e->flags, ENTRY_VALIDATED); mapBitSet(e->swap_filen); diff -u -r -N squid-4.0.20/src/ftp/Makefile.in squid-4.0.21/src/ftp/Makefile.in --- squid-4.0.20/src/ftp/Makefile.in 2017-06-02 00:59:31.000000000 +1200 +++ squid-4.0.21/src/ftp/Makefile.in 2017-07-02 20:41:26.000000000 +1200 @@ -1,7 +1,7 @@ -# Makefile.in generated by automake 1.15 from Makefile.am. +# Makefile.in generated by automake 1.15.1 from Makefile.am. # @configure_input@ -# Copyright (C) 1994-2014 Free Software Foundation, Inc. +# Copyright (C) 1994-2017 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, diff -u -r -N squid-4.0.20/src/FwdState.cc squid-4.0.21/src/FwdState.cc --- squid-4.0.20/src/FwdState.cc 2017-06-02 00:49:17.000000000 +1200 +++ squid-4.0.21/src/FwdState.cc 2017-07-02 20:41:18.000000000 +1200 @@ -254,7 +254,7 @@ #if USE_OPENSSL if (request->flags.sslPeek && request->clientConnectionManager.valid()) { CallJobHere1(17, 4, request->clientConnectionManager, ConnStateData, - ConnStateData::httpsPeeked, Comm::ConnectionPointer(NULL)); + ConnStateData::httpsPeeked, ConnStateData::PinnedIdleContext(Comm::ConnectionPointer(nullptr), request)); } #endif } else { @@ -324,7 +324,7 @@ */ ACLFilledChecklist ch(Config.accessList.miss, request, NULL); ch.src_addr = request->client_addr; - if (ch.fastCheck() == ACCESS_DENIED) { + if (ch.fastCheck().denied()) { err_type page_id; page_id = aclGetDenyInfoPage(&Config.denyInfoList, AclMatchedName, 1); @@ -975,7 +975,7 @@ #if USE_OPENSSL if (request->flags.sslPeek) { CallJobHere1(17, 4, request->clientConnectionManager, ConnStateData, - ConnStateData::httpsPeeked, serverConnection()); + ConnStateData::httpsPeeked, ConnStateData::PinnedIdleContext(serverConnection(), request)); unregister(serverConn); // async call owns it now complete(); // destroys us return; @@ -1180,7 +1180,7 @@ bool retriable = checkRetriable(); if (!retriable && Config.accessList.serverPconnForNonretriable) { ACLFilledChecklist ch(Config.accessList.serverPconnForNonretriable, request, NULL); - retriable = (ch.fastCheck() == ACCESS_ALLOWED); + retriable = ch.fastCheck().allowed(); } // always call shared pool first because we need to close an idle // connection there if we have to use a standby connection. @@ -1232,7 +1232,7 @@ aclMapTOS(acl_tos * head, ACLChecklist * ch) { for (acl_tos *l = head; l; l = l->next) { - if (!l->aclList || ch->fastCheck(l->aclList) == ACCESS_ALLOWED) + if (!l->aclList || ch->fastCheck(l->aclList).allowed()) return l->tos; } @@ -1244,7 +1244,7 @@ aclMapNfmark(acl_nfmark * head, ACLChecklist * ch) { for (acl_nfmark *l = head; l; l = l->next) { - if (!l->aclList || ch->fastCheck(l->aclList) == ACCESS_ALLOWED) + if (!l->aclList || ch->fastCheck(l->aclList).allowed()) return l->nfmark; } @@ -1295,7 +1295,7 @@ if (conn->remote.isIPv4() != l->addr.isIPv4()) continue; /* check ACLs for this outgoing address */ - if (!l->aclList || ch.fastCheck(l->aclList) == ACCESS_ALLOWED) { + if (!l->aclList || ch.fastCheck(l->aclList).allowed()) { conn->local = l->addr; return; } diff -u -r -N squid-4.0.20/src/helper/Makefile.in squid-4.0.21/src/helper/Makefile.in --- squid-4.0.20/src/helper/Makefile.in 2017-06-02 00:59:35.000000000 +1200 +++ squid-4.0.21/src/helper/Makefile.in 2017-07-02 20:41:27.000000000 +1200 @@ -1,7 +1,7 @@ -# Makefile.in generated by automake 1.15 from Makefile.am. +# Makefile.in generated by automake 1.15.1 from Makefile.am. # @configure_input@ -# Copyright (C) 1994-2014 Free Software Foundation, Inc. +# Copyright (C) 1994-2017 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, diff -u -r -N squid-4.0.20/src/htcp.cc squid-4.0.21/src/htcp.cc --- squid-4.0.20/src/htcp.cc 2017-06-02 00:49:17.000000000 +1200 +++ squid-4.0.21/src/htcp.cc 2017-07-02 20:41:18.000000000 +1200 @@ -678,7 +678,8 @@ // Parse the request method.HttpRequestMethodXXX(s->method); - s->request = HttpRequest::CreateFromUrl(s->uri, method == Http::METHOD_NONE ? HttpRequestMethod(Http::METHOD_GET) : method); + const MasterXaction::Pointer mx = new MasterXaction(XactionInitiator::initHtcp); + s->request = HttpRequest::FromUrl(s->uri, mx, method == Http::METHOD_NONE ? HttpRequestMethod(Http::METHOD_GET) : method); return s; } @@ -774,7 +775,7 @@ ACLFilledChecklist checklist(acl, s->request.getRaw(), nullptr); checklist.src_addr = from; checklist.my_addr.setNoAddr(); - return (checklist.fastCheck() == ACCESS_ALLOWED); + return checklist.fastCheck().allowed(); } static void diff -u -r -N squid-4.0.20/src/http/Makefile.in squid-4.0.21/src/http/Makefile.in --- squid-4.0.20/src/http/Makefile.in 2017-06-02 00:59:43.000000000 +1200 +++ squid-4.0.21/src/http/Makefile.in 2017-07-02 20:41:27.000000000 +1200 @@ -1,7 +1,7 @@ -# Makefile.in generated by automake 1.15 from Makefile.am. +# Makefile.in generated by automake 1.15.1 from Makefile.am. # @configure_input@ -# Copyright (C) 1994-2014 Free Software Foundation, Inc. +# Copyright (C) 1994-2017 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, diff -u -r -N squid-4.0.20/src/http/one/Makefile.in squid-4.0.21/src/http/one/Makefile.in --- squid-4.0.20/src/http/one/Makefile.in 2017-06-02 00:59:47.000000000 +1200 +++ squid-4.0.21/src/http/one/Makefile.in 2017-07-02 20:41:27.000000000 +1200 @@ -1,7 +1,7 @@ -# Makefile.in generated by automake 1.15 from Makefile.am. +# Makefile.in generated by automake 1.15.1 from Makefile.am. # @configure_input@ -# Copyright (C) 1994-2014 Free Software Foundation, Inc. +# Copyright (C) 1994-2017 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, diff -u -r -N squid-4.0.20/src/http/one/Parser.cc squid-4.0.21/src/http/one/Parser.cc --- squid-4.0.20/src/http/one/Parser.cc 2017-06-02 00:49:17.000000000 +1200 +++ squid-4.0.21/src/http/one/Parser.cc 2017-07-02 20:41:18.000000000 +1200 @@ -47,7 +47,13 @@ return RelaxedDels; } -/// characters used to separate HTTP fields +const CharacterSet & +Http::One::Parser::WhitespaceCharacters() +{ + return Config.onoff.relaxed_header_parser ? + RelaxedDelimiterCharacters() : CharacterSet::WSP; +} + const CharacterSet & Http::One::Parser::DelimiterCharacters() { @@ -259,11 +265,24 @@ return NULL; } -#if USE_HTTP_VIOLATIONS int -Http::One::Parser::violationLevel() const +Http::One::ErrorLevel() { return Config.onoff.relaxed_header_parser < 0 ? DBG_IMPORTANT : 5; } -#endif + +// BWS = *( SP / HTAB ) ; WhitespaceCharacters() may relax this RFC 7230 rule +bool +Http::One::ParseBws(Tokenizer &tok) +{ + if (const auto count = tok.skipAll(Parser::WhitespaceCharacters())) { + // Generating BWS is a MUST-level violation so warn about it as needed. + debugs(33, ErrorLevel(), "found " << count << " BWS octets"); + // RFC 7230 says we MUST parse BWS, so we fall through even if + // Config.onoff.relaxed_header_parser is off. + } + // else we successfully "parsed" an empty BWS sequence + + return true; +} diff -u -r -N squid-4.0.20/src/http/one/Parser.h squid-4.0.21/src/http/one/Parser.h --- squid-4.0.20/src/http/one/Parser.h 2017-06-02 00:49:17.000000000 +1200 +++ squid-4.0.21/src/http/one/Parser.h 2017-07-02 20:41:18.000000000 +1200 @@ -91,11 +91,6 @@ /// the remaining unprocessed section of buffer const SBuf &remaining() const {return buf_;} -#if USE_HTTP_VIOLATIONS - /// the right debugs() level for parsing HTTP violation messages - int violationLevel() const; -#endif - /** * HTTP status code resulting from the parse process. * to be used on the invalid message handling. @@ -106,8 +101,16 @@ */ Http::StatusCode parseStatusCode; - /// the characters which are to be considered valid whitespace - /// (WSP / BSP / OWS) + /// Whitespace between regular protocol elements. + /// Seen in RFCs as OWS, RWS, BWS, SP/HTAB but may be "relaxed" by us. + /// See also: DelimiterCharacters(). + static const CharacterSet &WhitespaceCharacters(); + + /// Whitespace between protocol elements in restricted contexts like + /// request line, status line, asctime-date, and credentials + /// Seen in RFCs as SP but may be "relaxed" by us. + /// See also: WhitespaceCharacters(). + /// XXX: Misnamed and overused. static const CharacterSet &DelimiterCharacters(); protected: @@ -155,6 +158,13 @@ void unfoldMime(); }; +/// skips and, if needed, warns about RFC 7230 BWS ("bad" whitespace) +/// \returns true (always; unlike all the skip*() functions) +bool ParseBws(Tokenizer &tok); + +/// the right debugs() level for logging HTTP violation messages +int ErrorLevel(); + } // namespace One } // namespace Http diff -u -r -N squid-4.0.20/src/http/one/RequestParser.cc squid-4.0.21/src/http/one/RequestParser.cc --- squid-4.0.20/src/http/one/RequestParser.cc 2017-06-02 00:49:17.000000000 +1200 +++ squid-4.0.21/src/http/one/RequestParser.cc 2017-07-02 20:41:18.000000000 +1200 @@ -14,12 +14,6 @@ #include "profiler/Profiler.h" #include "SquidConfig.h" -// the right debugs() level for parsing errors -inline static int -ErrorLevel() { - return Config.onoff.relaxed_header_parser < 0 ? DBG_IMPORTANT : 5; -} - Http::One::RequestParser::RequestParser(bool preserveParsed) : Parser(), preserveParsed_(preserveParsed) diff -u -r -N squid-4.0.20/src/http/one/TeChunkedParser.cc squid-4.0.21/src/http/one/TeChunkedParser.cc --- squid-4.0.20/src/http/one/TeChunkedParser.cc 2017-06-02 00:49:17.000000000 +1200 +++ squid-4.0.21/src/http/one/TeChunkedParser.cc 2017-07-02 20:41:18.000000000 +1200 @@ -105,10 +105,10 @@ } /** - * Parses a set of RFC 7230 section 4.1.1 chunk-ext - * http://tools.ietf.org/html/rfc7230#section-4.1.1 + * Parses chunk metadata suffix, looking for interesting extensions and/or + * getting to the line terminator. RFC 7230 section 4.1.1 and its Errata #4667: * - * chunk-ext = *( ";" chunk-ext-name [ "=" chunk-ext-val ] ) + * chunk-ext = *( BWS ";" BWS chunk-ext-name [ BWS "=" BWS chunk-ext-val ] ) * chunk-ext-name = token * chunk-ext-val = token / quoted-string * @@ -117,17 +117,16 @@ bool Http::One::TeChunkedParser::parseChunkExtension(Http1::Tokenizer &tok, bool skipKnown) { - // Bug 4492: IBM_HTTP_Server sends SP padding - if (auto n = tok.skipAll(CharacterSet::SP)) { - debugs(94, 3, "skipping " << n << " spurious whitespace at start of chunk extension"); - } - SBuf ext; SBuf value; - while (tok.skip(';') && tok.prefix(ext, CharacterSet::TCHAR)) { + while ( + ParseBws(tok) && // Bug 4492: IBM_HTTP_Server sends SP after chunk-size + tok.skip(';') && + ParseBws(tok) && // Bug 4492: ICAP servers send SP before chunk-ext-name + tok.prefix(ext, CharacterSet::TCHAR)) { // chunk-ext-name // whole value part is optional. if no '=' expect next chunk-ext - if (tok.skip('=')) { + if (ParseBws(tok) && tok.skip('=') && ParseBws(tok)) { if (!skipKnown) { if (ext.cmp("use-original-body",17) == 0 && tok.int64(useOriginBody, 10)) { diff -u -r -N squid-4.0.20/src/http/url_rewriters/fake/Makefile.in squid-4.0.21/src/http/url_rewriters/fake/Makefile.in --- squid-4.0.20/src/http/url_rewriters/fake/Makefile.in 2017-06-02 01:00:01.000000000 +1200 +++ squid-4.0.21/src/http/url_rewriters/fake/Makefile.in 2017-07-02 20:41:27.000000000 +1200 @@ -1,7 +1,7 @@ -# Makefile.in generated by automake 1.15 from Makefile.am. +# Makefile.in generated by automake 1.15.1 from Makefile.am. # @configure_input@ -# Copyright (C) 1994-2014 Free Software Foundation, Inc. +# Copyright (C) 1994-2017 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, diff -u -r -N squid-4.0.20/src/http/url_rewriters/LFS/Makefile.in squid-4.0.21/src/http/url_rewriters/LFS/Makefile.in --- squid-4.0.20/src/http/url_rewriters/LFS/Makefile.in 2017-06-02 00:59:51.000000000 +1200 +++ squid-4.0.21/src/http/url_rewriters/LFS/Makefile.in 2017-07-02 20:41:27.000000000 +1200 @@ -1,7 +1,7 @@ -# Makefile.in generated by automake 1.15 from Makefile.am. +# Makefile.in generated by automake 1.15.1 from Makefile.am. # @configure_input@ -# Copyright (C) 1994-2014 Free Software Foundation, Inc. +# Copyright (C) 1994-2017 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, diff -u -r -N squid-4.0.20/src/http/url_rewriters/LFS/url_lfs_rewrite.8 squid-4.0.21/src/http/url_rewriters/LFS/url_lfs_rewrite.8 --- squid-4.0.20/src/http/url_rewriters/LFS/url_lfs_rewrite.8 2017-06-02 09:57:33.000000000 +1200 +++ squid-4.0.21/src/http/url_rewriters/LFS/url_lfs_rewrite.8 2017-07-02 20:57:35.000000000 +1200 @@ -1,4 +1,4 @@ -.\" Automatically generated by Pod::Man 4.08 (Pod::Simple 3.32) +.\" Automatically generated by Pod::Man 4.07 (Pod::Simple 3.32) .\" .\" Standard preamble: .\" ======================================================================== @@ -129,7 +129,7 @@ .\" ======================================================================== .\" .IX Title "URL_LFS_REWRITE 8" -.TH URL_LFS_REWRITE 8 "2017-06-01" "perl v5.24.1" "User Contributed Perl Documentation" +.TH URL_LFS_REWRITE 8 "2017-07-02" "perl v5.24.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 @@ -234,7 +234,7 @@ Report ideas for new improvements to the \fISquid Developers mailing list .SH "SEE ALSO" .IX Header "SEE ALSO" -squid (8), \s-1GPL\s0 (7), +squid (8), \s-1GPL \\fIs0\fR\|(7), .PP The Squid \s-1FAQ\s0 wiki http://wiki.squid\-cache.org/SquidFaq .PP diff -u -r -N squid-4.0.20/src/http/url_rewriters/Makefile.in squid-4.0.21/src/http/url_rewriters/Makefile.in --- squid-4.0.20/src/http/url_rewriters/Makefile.in 2017-06-02 00:59:55.000000000 +1200 +++ squid-4.0.21/src/http/url_rewriters/Makefile.in 2017-07-02 20:41:27.000000000 +1200 @@ -1,7 +1,7 @@ -# Makefile.in generated by automake 1.15 from Makefile.am. +# Makefile.in generated by automake 1.15.1 from Makefile.am. # @configure_input@ -# Copyright (C) 1994-2014 Free Software Foundation, Inc. +# Copyright (C) 1994-2017 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, diff -u -r -N squid-4.0.20/src/http.cc squid-4.0.21/src/http.cc --- squid-4.0.20/src/http.cc 2017-06-02 00:49:17.000000000 +1200 +++ squid-4.0.21/src/http.cc 2017-07-02 20:41:18.000000000 +1200 @@ -288,7 +288,9 @@ (Config.onoff.surrogate_is_remote && sctusable->noStoreRemote())) { surrogateNoStore = true; - entry->makePrivate(); + // Be conservative for now and make it non-shareable because + // there is no enough information here to make the decision. + entry->makePrivate(false); } /* The HttpHeader logic cannot tell if the header it's parsing is a reply to an @@ -313,8 +315,8 @@ } } -int -HttpStateData::cacheableReply() +HttpStateData::ReuseDecision::Answers +HttpStateData::reusableReply(HttpStateData::ReuseDecision &decision) { HttpReply const *rep = finalReply(); HttpHeader const *hdr = &rep->header; @@ -335,24 +337,19 @@ #define REFRESH_OVERRIDE(flag) 0 #endif - if (EBIT_TEST(entry->flags, RELEASE_REQUEST)) { - debugs(22, 3, "NO because " << *entry << " has been released."); - return 0; - } + if (EBIT_TEST(entry->flags, RELEASE_REQUEST)) + return decision.make(ReuseDecision::reuseNot, "the entry has been released"); // RFC 7234 section 4: a cache MUST use the most recent response // (as determined by the Date header field) - if (sawDateGoBack) { - debugs(22, 3, "NO because " << *entry << " has an older date header."); - return 0; - } + // TODO: whether such responses could be shareable? + if (sawDateGoBack) + return decision.make(ReuseDecision::reuseNot, "the response has an older date header"); // Check for Surrogate/1.0 protocol conditions // NP: reverse-proxy traffic our parent server has instructed us never to cache - if (surrogateNoStore) { - debugs(22, 3, HERE << "NO because Surrogate-Control:no-store"); - return 0; - } + if (surrogateNoStore) + return decision.make(ReuseDecision::reuseNot, "Surrogate-Control:no-store"); // RFC 2616: HTTP/1.1 Cache-Control conditions if (!ignoreCacheControl) { @@ -362,10 +359,9 @@ // RFC 2616 section 14.9.2 - MUST NOT cache any response with request CC:no-store if (request && request->cache_control && request->cache_control->hasNoStore() && - !REFRESH_OVERRIDE(ignore_no_store)) { - debugs(22, 3, HERE << "NO because client request Cache-Control:no-store"); - return 0; - } + !REFRESH_OVERRIDE(ignore_no_store)) + return decision.make(ReuseDecision::reuseNot, + "client request Cache-Control:no-store"); // NP: request CC:no-cache only means cache READ is forbidden. STORE is permitted. if (rep->cache_control && rep->cache_control->hasNoCacheWithParameters()) { @@ -374,8 +370,8 @@ * successfully (ie, must revalidate AND these headers are prohibited on stale replies). * That is a bit tricky for squid right now so we avoid caching entirely. */ - debugs(22, 3, HERE << "NO because server reply Cache-Control:no-cache has parameters"); - return 0; + return decision.make(ReuseDecision::reuseNot, + "server reply Cache-Control:no-cache has parameters"); } // NP: request CC:private is undefined. We ignore. @@ -383,10 +379,9 @@ // RFC 2616 section 14.9.2 - MUST NOT cache any response with CC:no-store if (rep->cache_control && rep->cache_control->hasNoStore() && - !REFRESH_OVERRIDE(ignore_no_store)) { - debugs(22, 3, HERE << "NO because server reply Cache-Control:no-store"); - return 0; - } + !REFRESH_OVERRIDE(ignore_no_store)) + return decision.make(ReuseDecision::reuseNot, + "server reply Cache-Control:no-store"); // RFC 2616 section 14.9.1 - MUST NOT cache any response with CC:private in a shared cache like Squid. // CC:private overrides CC:public when both are present in a response. @@ -399,23 +394,21 @@ * successfully (ie, must revalidate AND these headers are prohibited on stale replies). * That is a bit tricky for squid right now so we avoid caching entirely. */ - debugs(22, 3, HERE << "NO because server reply Cache-Control:private"); - return 0; + return decision.make(ReuseDecision::reuseNot, + "server reply Cache-Control:private"); } } // RFC 2068, sec 14.9.4 - MUST NOT cache any response with Authentication UNLESS certain CC controls are present // allow HTTP violations to IGNORE those controls (ie re-block caching Auth) if (request && (request->flags.auth || request->flags.authSent)) { - if (!rep->cache_control) { - debugs(22, 3, HERE << "NO because Authenticated and server reply missing Cache-Control"); - return 0; - } - - if (ignoreCacheControl) { - debugs(22, 3, HERE << "NO because Authenticated and ignoring Cache-Control"); - return 0; - } + if (!rep->cache_control) + return decision.make(ReuseDecision::reuseNot, + "authenticated and server reply missing Cache-Control"); + + if (ignoreCacheControl) + return decision.make(ReuseDecision::reuseNot, + "authenticated and ignoring Cache-Control"); bool mayStore = false; // HTTPbis pt6 section 3.2: a response CC:public is present @@ -444,10 +437,8 @@ mayStore = true; } - if (!mayStore) { - debugs(22, 3, HERE << "NO because Authenticated transaction"); - return 0; - } + if (!mayStore) + return decision.make(ReuseDecision::reuseNot, "authenticated transaction"); // NP: response CC:no-cache is equivalent to CC:must-revalidate,max-age=0. We MAY cache, and do so. // NP: other request CC flags are limiters on HIT/MISS/REFRESH. We don't care about here. @@ -458,12 +449,26 @@ * probably should not be cachable */ if ((v = hdr->getStr(Http::HdrType::CONTENT_TYPE))) - if (!strncasecmp(v, "multipart/x-mixed-replace", 25)) { - debugs(22, 3, HERE << "NO because Content-Type:multipart/x-mixed-replace"); - return 0; - } + if (!strncasecmp(v, "multipart/x-mixed-replace", 25)) + return decision.make(ReuseDecision::reuseNot, "Content-Type:multipart/x-mixed-replace"); + + // TODO: if possible, provide more specific message for each status code + static const char *shareableError = "shareable error status code"; + static const char *nonShareableError = "non-shareable error status code"; + ReuseDecision::Answers statusAnswer = ReuseDecision::reuseNot; + const char *statusReason = nonShareableError; switch (rep->sline.status()) { + + /* There are several situations when a non-cacheable response may be + * still shareable (e.g., among collapsed clients). We assume that these + * are 3xx and 5xx responses, indicating server problems and some of + * 4xx responses, common for all clients with a given cache key (e.g., + * 404 Not Found or 414 URI Too Long). On the other hand, we should not + * share non-cacheable client-specific errors, such as 400 Bad Request + * or 406 Not Acceptable. + */ + /* Responses that are cacheable */ case Http::scOkay: @@ -481,111 +486,87 @@ * unless we know how to refresh it. */ - if (!refreshIsCachable(entry) && !REFRESH_OVERRIDE(store_stale)) { - debugs(22, 3, "NO because refreshIsCachable() returned non-cacheable.."); - return 0; - } else { - debugs(22, 3, HERE << "YES because HTTP status " << rep->sline.status()); - return 1; - } - /* NOTREACHED */ + if (refreshIsCachable(entry) || REFRESH_OVERRIDE(store_stale)) + decision.make(ReuseDecision::cachePositively, "refresh check returned cacheable"); + else + decision.make(ReuseDecision::doNotCacheButShare, "refresh check returned non-cacheable"); break; /* Responses that only are cacheable if the server says so */ case Http::scFound: case Http::scTemporaryRedirect: - if (rep->date <= 0) { - debugs(22, 3, HERE << "NO because HTTP status " << rep->sline.status() << " and Date missing/invalid"); - return 0; - } - if (rep->expires > rep->date) { - debugs(22, 3, HERE << "YES because HTTP status " << rep->sline.status() << " and Expires > Date"); - return 1; - } else { - debugs(22, 3, HERE << "NO because HTTP status " << rep->sline.status() << " and Expires <= Date"); - return 0; - } - /* NOTREACHED */ + if (rep->date <= 0) + decision.make(ReuseDecision::doNotCacheButShare, "Date is missing/invalid"); + else if (rep->expires > rep->date) + decision.make(ReuseDecision::cachePositively, "Expires > Date"); + else + decision.make(ReuseDecision::doNotCacheButShare, "Expires <= Date"); break; - /* Errors can be negatively cached */ - + /* These responses can be negatively cached. Most can also be shared. */ case Http::scNoContent: - case Http::scUseProxy: - - case Http::scBadRequest: - case Http::scForbidden: - case Http::scNotFound: - case Http::scMethodNotAllowed: - case Http::scUriTooLong: - case Http::scInternalServerError: - case Http::scNotImplemented: - case Http::scBadGateway: - case Http::scServiceUnavailable: - case Http::scGatewayTimeout: case Http::scMisdirectedRequest: + statusAnswer = ReuseDecision::doNotCacheButShare; + statusReason = shareableError; + // fall through to the actual decision making below - debugs(22, 3, "MAYBE because HTTP status " << rep->sline.status()); - return -1; - - /* NOTREACHED */ + case Http::scBadRequest: // no sharing; perhaps the server did not like something specific to this request +#if USE_HTTP_VIOLATIONS + if (Config.negativeTtl > 0) + decision.make(ReuseDecision::cacheNegatively, "Config.negativeTtl > 0"); + else +#endif + decision.make(statusAnswer, statusReason); break; - /* Some responses can never be cached */ - - case Http::scPartialContent: /* Not yet supported */ - + /* these responses can never be cached, some + of them can be shared though */ case Http::scSeeOther: - case Http::scNotModified: - case Http::scUnauthorized: - case Http::scProxyAuthenticationRequired: - - case Http::scInvalidHeader: /* Squid header parsing error */ - - case Http::scHeaderTooLarge: - case Http::scPaymentRequired: + case Http::scInsufficientStorage: + // TODO: use more specific reason for non-error status codes + decision.make(ReuseDecision::doNotCacheButShare, shareableError); + break; + + case Http::scPartialContent: /* Not yet supported. TODO: make shareable for suitable ranges */ case Http::scNotAcceptable: - case Http::scRequestTimeout: - case Http::scConflict: + case Http::scRequestTimeout: // TODO: is this shareable? + case Http::scConflict: // TODO: is this shareable? case Http::scLengthRequired: case Http::scPreconditionFailed: case Http::scPayloadTooLarge: case Http::scUnsupportedMediaType: case Http::scUnprocessableEntity: - case Http::scLocked: + case Http::scLocked: // TODO: is this shareable? case Http::scFailedDependency: - case Http::scInsufficientStorage: case Http::scRequestedRangeNotSatisfied: case Http::scExpectationFailed: - - debugs(22, 3, HERE << "NO because HTTP status " << rep->sline.status()); - return 0; + case Http::scInvalidHeader: /* Squid header parsing error */ + case Http::scHeaderTooLarge: + decision.make(ReuseDecision::reuseNot, nonShareableError); + break; default: /* RFC 2616 section 6.1.1: an unrecognized response MUST NOT be cached. */ - debugs (11, 3, HERE << "NO because unknown HTTP status code " << rep->sline.status()); - return 0; - - /* NOTREACHED */ + decision.make(ReuseDecision::reuseNot, "unknown status code"); break; } - /* NOTREACHED */ + return decision.answer; } /// assemble a variant key (vary-mark) from the given Vary header and HTTP request @@ -826,7 +807,7 @@ ACLFilledChecklist ch(Config.accessList.reply, originalRequest(), NULL); ch.reply = reply; HTTPMSGLOCK(ch.reply); - if (ch.fastCheck() != ACCESS_ALLOWED) { // TODO: support slow lookups? + if (!ch.fastCheck().allowed()) { // TODO: support slow lookups? debugs(11, 3, HERE << "ignoring denied 1xx"); proceedAfter1xx(); return; @@ -921,11 +902,12 @@ Ctx ctx = ctx_enter(entry->mem_obj->urlXXX()); HttpReply *rep = finalReply(); + const Http::StatusCode statusCode = rep->sline.status(); entry->timestampsSet(); /* Check if object is cacheable or not based on reply code */ - debugs(11, 3, "HTTP CODE: " << rep->sline.status()); + debugs(11, 3, "HTTP CODE: " << statusCode); if (const StoreEntry *oldEntry = findPreviouslyCachedEntry(entry)) sawDateGoBack = rep->olderThan(oldEntry->getReply()); @@ -942,7 +924,9 @@ const SBuf vary(httpMakeVaryMark(request, rep)); if (vary.isEmpty()) { - entry->makePrivate(); + // TODO: check whether such responses are shareable. + // Do not share for now. + entry->makePrivate(false); if (!fwd->reforwardableStatus(rep->sline.status())) EBIT_CLR(entry->flags, ENTRY_FWD_HDR_WAIT); varyFailure = true; @@ -965,30 +949,31 @@ if (!fwd->reforwardableStatus(rep->sline.status())) EBIT_CLR(entry->flags, ENTRY_FWD_HDR_WAIT); - switch (cacheableReply()) { + ReuseDecision decision(entry, statusCode); - case 1: - entry->makePublic(); + switch (reusableReply(decision)) { + + case ReuseDecision::reuseNot: + entry->makePrivate(false); break; - case 0: - entry->makePrivate(); + case ReuseDecision::cachePositively: + entry->makePublic(); break; - case -1: + case ReuseDecision::cacheNegatively: + entry->cacheNegatively(); + break; -#if USE_HTTP_VIOLATIONS - if (Config.negativeTtl > 0) - entry->cacheNegatively(); - else -#endif - entry->makePrivate(); + case ReuseDecision::doNotCacheButShare: + entry->makePrivate(true); break; default: assert(0); break; } + debugs(11, 3, "decided: " << decision); } if (!ignoreCacheControl) { @@ -1409,9 +1394,6 @@ void HttpStateData::processReplyBody() { - Ip::Address client_addr; - bool ispinned = false; - if (!flags.headers_parsed) { flags.do_next_read = true; maybeReadVirginBody(); @@ -1464,35 +1446,49 @@ } break; - case COMPLETE_PERSISTENT_MSG: + case COMPLETE_PERSISTENT_MSG: { debugs(11, 5, "processReplyBody: COMPLETE_PERSISTENT_MSG from " << serverConnection); - /* yes we have to clear all these! */ + + // TODO: Remove serverConnectionSaved but preserve exception safety. + commUnsetConnTimeout(serverConnection); flags.do_next_read = false; comm_remove_close_handler(serverConnection->fd, closeHandler); closeHandler = NULL; - fwd->unregister(serverConnection); + Ip::Address client_addr; // XXX: Remove as unused. Why was it added? if (request->flags.spoofClientIp) client_addr = request->client_addr; + auto serverConnectionSaved = serverConnection; + fwd->unregister(serverConnection); + serverConnection = nullptr; + + bool ispinned = false; // TODO: Rename to isOrShouldBePinned if (request->flags.pinned) { ispinned = true; } else if (request->flags.connectionAuth && request->flags.authSent) { ispinned = true; } - if (ispinned && request->clientConnectionManager.valid()) { - request->clientConnectionManager->pinConnection(serverConnection, request, _peer, - (request->flags.connectionAuth)); + if (ispinned) { + if (request->clientConnectionManager.valid()) { + CallJobHere1(11, 4, request->clientConnectionManager, + ConnStateData, + notePinnedConnectionBecameIdle, + ConnStateData::PinnedIdleContext(serverConnectionSaved, request)); + } else { + // must not pool/share ispinned connections, even orphaned ones + serverConnectionSaved->close(); + } } else { - fwd->pconnPush(serverConnection, request->url.host()); + fwd->pconnPush(serverConnectionSaved, request->url.host()); } - serverConnection = NULL; serverComplete(); return; + } case COMPLETE_NONPERSISTENT_MSG: debugs(11, 5, "processReplyBody: COMPLETE_NONPERSISTENT_MSG from " << serverConnection); @@ -2333,7 +2329,7 @@ } ACLFilledChecklist ch(Config.accessList.brokenPosts, originalRequest(), NULL); - if (ch.fastCheck() != ACCESS_ALLOWED) { + if (!ch.fastCheck().allowed()) { debugs(11, 5, HERE << "didn't match brokenPosts"); return false; } @@ -2457,3 +2453,29 @@ mustStop(reason); } +HttpStateData::ReuseDecision::ReuseDecision(const StoreEntry *e, const Http::StatusCode code) + : answer(HttpStateData::ReuseDecision::reuseNot), reason(nullptr), entry(e), statusCode(code) {} + +HttpStateData::ReuseDecision::Answers +HttpStateData::ReuseDecision::make(const HttpStateData::ReuseDecision::Answers ans, const char *why) +{ + answer = ans; + reason = why; + return answer; +} + +std::ostream &operator <<(std::ostream &os, const HttpStateData::ReuseDecision &d) +{ + static const char *ReuseMessages[] = { + "do not cache and do not share", // reuseNot + "cache positively and share", // cachePositively + "cache negatively and share", // cacheNegatively + "do not cache but share" // doNotCacheButShare + }; + + assert(d.answer >= HttpStateData::ReuseDecision::reuseNot && + d.answer <= HttpStateData::ReuseDecision::doNotCacheButShare); + return os << ReuseMessages[d.answer] << " because " << d.reason << + "; HTTP status " << d.statusCode << " " << *(d.entry); +} + diff -u -r -N squid-4.0.20/src/http.h squid-4.0.21/src/http.h --- squid-4.0.20/src/http.h 2017-06-02 00:49:17.000000000 +1200 +++ squid-4.0.21/src/http.h 2017-07-02 20:41:18.000000000 +1200 @@ -23,6 +23,23 @@ CBDATA_CLASS(HttpStateData); public: + + /// assists in making and relaying entry caching/sharing decision + class ReuseDecision + { + public: + enum Answers { reuseNot = 0, cachePositively, cacheNegatively, doNotCacheButShare }; + + ReuseDecision(const StoreEntry *e, const Http::StatusCode code); + /// stores the corresponding decision + Answers make(const Answers ans, const char *why); + + Answers answer; ///< the decision id + const char *reason; ///< the decision reason + const StoreEntry *entry; ///< entry for debugging + const Http::StatusCode statusCode; ///< HTTP status for debugging + }; + HttpStateData(FwdState *); ~HttpStateData(); @@ -40,8 +57,8 @@ void readReply(const CommIoCbParams &io); virtual void maybeReadVirginBody(); // read response data from the network - // Determine whether the response is a cacheable representation - int cacheableReply(); + // Checks whether the response is cacheable/shareable. + ReuseDecision::Answers reusableReply(ReuseDecision &decision); CachePeer *_peer; /* CachePeer request made to */ int eof; /* reached end-of-object? */ @@ -135,6 +152,8 @@ bool sawDateGoBack; }; +std::ostream &operator <<(std::ostream &os, const HttpStateData::ReuseDecision &d); + int httpCachable(const HttpRequestMethod&); void httpStart(FwdState *); SBuf httpMakeVaryMark(HttpRequest * request, HttpReply const * reply); diff -u -r -N squid-4.0.20/src/HttpHeaderTools.cc squid-4.0.21/src/HttpHeaderTools.cc --- squid-4.0.20/src/HttpHeaderTools.cc 2017-06-02 00:49:17.000000000 +1200 +++ squid-4.0.21/src/HttpHeaderTools.cc 2017-07-02 20:41:18.000000000 +1200 @@ -289,7 +289,7 @@ ACLFilledChecklist checklist(hm->access_list, request, NULL); - if (checklist.fastCheck() == ACCESS_ALLOWED) { + if (checklist.fastCheck().allowed()) { /* aclCheckFast returns true for allow. */ debugs(66, 7, "checklist for mangler is positive. Mangle"); retval = 1; @@ -478,7 +478,7 @@ ACLFilledChecklist checklist(NULL, request, NULL); for (HeaderWithAclList::const_iterator hwa = headersAdd.begin(); hwa != headersAdd.end(); ++hwa) { - if (!hwa->aclList || checklist.fastCheck(hwa->aclList) == ACCESS_ALLOWED) { + if (!hwa->aclList || checklist.fastCheck(hwa->aclList).allowed()) { const char *fieldValue = NULL; MemBuf mb; if (hwa->quoted) { diff -u -r -N squid-4.0.20/src/HttpReply.cc squid-4.0.21/src/HttpReply.cc --- squid-4.0.20/src/HttpReply.cc 2017-06-02 00:49:17.000000000 +1200 +++ squid-4.0.21/src/HttpReply.cc 2017-07-02 20:41:18.000000000 +1200 @@ -517,7 +517,7 @@ HTTPMSGLOCK(ch.reply); for (AclSizeLimit *l = Config.ReplyBodySize; l; l = l -> next) { /* if there is no ACL list or if the ACLs listed match use this size value */ - if (!l->aclList || ch.fastCheck(l->aclList) == ACCESS_ALLOWED) { + if (!l->aclList || ch.fastCheck(l->aclList).allowed()) { debugs(58, 4, HERE << "bodySizeMax=" << bodySizeMax); bodySizeMax = l->size; // may be -1 break; diff -u -r -N squid-4.0.20/src/HttpRequest.cc squid-4.0.21/src/HttpRequest.cc --- squid-4.0.20/src/HttpRequest.cc 2017-06-02 00:49:17.000000000 +1200 +++ squid-4.0.21/src/HttpRequest.cc 2017-07-02 20:41:18.000000000 +1200 @@ -13,6 +13,7 @@ #include "acl/AclSizeLimit.h" #include "acl/FilledChecklist.h" #include "client_side.h" +#include "client_side_request.h" #include "dns/LookupDetails.h" #include "Downloader.h" #include "err_detail_type.h" @@ -38,15 +39,19 @@ #include "adaptation/icap/icap_log.h" #endif -HttpRequest::HttpRequest() : - HttpMsg(hoRequest) +HttpRequest::HttpRequest(const MasterXaction::Pointer &mx) : + HttpMsg(hoRequest), + masterXaction(mx) { + assert(mx); init(); } -HttpRequest::HttpRequest(const HttpRequestMethod& aMethod, AnyP::ProtocolType aProtocol, const char *aSchemeImg, const char *aUrlpath) : - HttpMsg(hoRequest) +HttpRequest::HttpRequest(const HttpRequestMethod& aMethod, AnyP::ProtocolType aProtocol, const char *aSchemeImg, const char *aUrlpath, const MasterXaction::Pointer &mx) : + HttpMsg(hoRequest), + masterXaction(mx) { + assert(mx); static unsigned int id = 1; debugs(93,7, HERE << "constructed, this=" << this << " id=" << ++id); init(); @@ -170,7 +175,7 @@ HttpRequest * HttpRequest::clone() const { - HttpRequest *copy = new HttpRequest(); + HttpRequest *copy = new HttpRequest(masterXaction); copy->method = method; // TODO: move common cloning clone to Msg::copyTo() or copy ctor copy->header.append(&header); @@ -327,14 +332,11 @@ * (char *) end = '\0'; // temp terminate URI, XXX dangerous? - HttpRequest *tmp = urlParse(method, (char *) start, this); + const bool ret = url.parse(method, (char *) start); * (char *) end = save; - if (NULL == tmp) - return false; - - return true; + return ret; } /* swaps out request using httpRequestPack */ @@ -518,9 +520,14 @@ * If the request cannot be created cleanly, NULL is returned */ HttpRequest * -HttpRequest::CreateFromUrl(char * url, const HttpRequestMethod& method) +HttpRequest::FromUrl(char * url, const MasterXaction::Pointer &mx, const HttpRequestMethod& method) { - return urlParse(method, url, NULL); + std::unique_ptr req(new HttpRequest(mx)); + if (req->url.parse(method, url)) { + req->method = method; + return req.release(); + } + return nullptr; } /** @@ -604,7 +611,7 @@ for (AclSizeLimit *l = Config.rangeOffsetLimit; l; l = l -> next) { /* if there is no ACL list or if the ACLs listed match use this limit value */ - if (!l->aclList || ch.fastCheck(l->aclList) == ACCESS_ALLOWED) { + if (!l->aclList || ch.fastCheck(l->aclList).allowed()) { debugs(58, 4, HERE << "rangeOffsetLimit=" << rangeOffsetLimit); rangeOffsetLimit = l->size; // may be -1 break; @@ -667,3 +674,42 @@ return url.absolute(); } +void +HttpRequest::manager(const CbcPointer &aMgr, const AccessLogEntryPointer &al) +{ + clientConnectionManager = aMgr; + + if (!clientConnectionManager.valid()) + return; + + AnyP::PortCfgPointer port = clientConnectionManager->port; + if (port) { + myportname = port->name; + flags.ignoreCc = port->ignore_cc; + } + + if (auto clientConnection = clientConnectionManager->clientConnection) { + client_addr = clientConnection->remote; // XXX: remove request->client_addr member. +#if FOLLOW_X_FORWARDED_FOR + // indirect client gets stored here because it is an HTTP header result (from X-Forwarded-For:) + // not details about the TCP connection itself + indirect_client_addr = clientConnection->remote; +#endif /* FOLLOW_X_FORWARDED_FOR */ + my_addr = clientConnection->local; + + flags.intercepted = ((clientConnection->flags & COMM_INTERCEPTION) != 0); + flags.interceptTproxy = ((clientConnection->flags & COMM_TRANSPARENT) != 0 ) ; + const bool proxyProtocolPort = port ? port->flags.proxySurrogate : false; + if (flags.interceptTproxy && !proxyProtocolPort) { + if (Config.accessList.spoof_client_ip) { + ACLFilledChecklist *checklist = new ACLFilledChecklist(Config.accessList.spoof_client_ip, this, clientConnection->rfc931); + checklist->al = al; + flags.spoofClientIp = checklist->fastCheck().allowed(); + delete checklist; + } else + flags.spoofClientIp = true; + } else + flags.spoofClientIp = false; + } +} + diff -u -r -N squid-4.0.20/src/HttpRequest.h squid-4.0.21/src/HttpRequest.h --- squid-4.0.20/src/HttpRequest.h 2017-06-02 00:49:17.000000000 +1200 +++ squid-4.0.21/src/HttpRequest.h 2017-07-02 20:41:18.000000000 +1200 @@ -15,6 +15,7 @@ #include "HierarchyLogEntry.h" #include "http/RequestMethod.h" #include "HttpMsg.h" +#include "MasterXaction.h" #include "Notes.h" #include "RequestFlags.h" #include "URL.h" @@ -35,6 +36,8 @@ class ConnStateData; class Downloader; +class AccessLogEntry; +typedef RefCount AccessLogEntryPointer; /* Http Request */ void httpRequestPack(void *obj, Packable *p); @@ -48,8 +51,8 @@ public: typedef RefCount Pointer; - HttpRequest(); - HttpRequest(const HttpRequestMethod& aMethod, AnyP::ProtocolType aProtocol, const char *schemeImage, const char *aUrlpath); + HttpRequest(const MasterXaction::Pointer &); + HttpRequest(const HttpRequestMethod& aMethod, AnyP::ProtocolType aProtocol, const char *schemeImage, const char *aUrlpath, const MasterXaction::Pointer &); ~HttpRequest(); virtual void reset(); @@ -87,6 +90,9 @@ /// clear error details, useful for retries/repeats void clearError(); + /// associates the request with a from-client connection manager + void manager(const CbcPointer &aMgr, const AccessLogEntryPointer &al); + protected: void clean(); @@ -195,7 +201,7 @@ static void httpRequestPack(void *obj, Packable *p); - static HttpRequest * CreateFromUrl(char * url, const HttpRequestMethod &method = Http::METHOD_GET); + static HttpRequest * FromUrl(char * url, const MasterXaction::Pointer &, const HttpRequestMethod &method = Http::METHOD_GET); ConnStateData *pinnedConnection(); @@ -216,6 +222,9 @@ /// The Downloader object which initiated the HTTP request if any CbcPointer downloader; + /// the master transaction this request belongs to. Never nil. + MasterXaction::Pointer masterXaction; + /// forgets about the cached Range header (for a reason) void ignoreRange(const char *reason); int64_t getRangeOffsetLimit(); /* the result of this function gets cached in rangeOffsetLimit */ diff -u -r -N squid-4.0.20/src/icmp/Makefile.in squid-4.0.21/src/icmp/Makefile.in --- squid-4.0.20/src/icmp/Makefile.in 2017-06-02 01:00:08.000000000 +1200 +++ squid-4.0.21/src/icmp/Makefile.in 2017-07-02 20:41:27.000000000 +1200 @@ -1,7 +1,7 @@ -# Makefile.in generated by automake 1.15 from Makefile.am. +# Makefile.in generated by automake 1.15.1 from Makefile.am. # @configure_input@ -# Copyright (C) 1994-2014 Free Software Foundation, Inc. +# Copyright (C) 1994-2017 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, diff -u -r -N squid-4.0.20/src/icmp/net_db.cc squid-4.0.21/src/icmp/net_db.cc --- squid-4.0.20/src/icmp/net_db.cc 2017-06-02 00:49:17.000000000 +1200 +++ squid-4.0.21/src/icmp/net_db.cc 2017-07-02 20:41:18.000000000 +1200 @@ -1286,7 +1286,8 @@ char *uri = internalRemoteUri(p->host, p->http_port, "/squid-internal-dynamic/", netDB); debugs(38, 3, "netdbExchangeStart: Requesting '" << uri << "'"); assert(NULL != uri); - HttpRequest *req = HttpRequest::CreateFromUrl(uri); + const MasterXaction::Pointer mx = new MasterXaction(XactionInitiator::initIcmp); + HttpRequest *req = HttpRequest::FromUrl(uri, mx); if (req == NULL) { debugs(38, DBG_IMPORTANT, "netdbExchangeStart: Bad URI " << uri); diff -u -r -N squid-4.0.20/src/icp_v2.cc squid-4.0.21/src/icp_v2.cc --- squid-4.0.20/src/icp_v2.cc 2017-06-02 00:49:17.000000000 +1200 +++ squid-4.0.21/src/icp_v2.cc 2017-07-02 20:41:18.000000000 +1200 @@ -417,7 +417,7 @@ ACLFilledChecklist checklist(Config.accessList.icp, icp_request, NULL); checklist.src_addr = from; checklist.my_addr.setNoAddr(); - return (checklist.fastCheck() == ACCESS_ALLOWED); + return checklist.fastCheck().allowed(); } char const * @@ -439,8 +439,8 @@ } HttpRequest *result; - - if ((result = HttpRequest::CreateFromUrl(url)) == NULL) + const MasterXaction::Pointer mx = new MasterXaction(XactionInitiator::initIcp); + if ((result = HttpRequest::FromUrl(url, mx)) == NULL) icpCreateAndSend(ICP_ERR, 0, url, reqnum, 0, fd, from); return result; diff -u -r -N squid-4.0.20/src/ident/AclIdent.cc squid-4.0.21/src/ident/AclIdent.cc --- squid-4.0.20/src/ident/AclIdent.cc 2017-06-02 00:49:17.000000000 +1200 +++ squid-4.0.21/src/ident/AclIdent.cc 2017-07-02 20:41:18.000000000 +1200 @@ -47,6 +47,12 @@ } void +ACLIdent::parseFlags() +{ + ParseFlags(Acl::NoOptions(), data->supportedFlags()); +} + +void ACLIdent::parse() { if (!data) { diff -u -r -N squid-4.0.20/src/ident/AclIdent.h squid-4.0.21/src/ident/AclIdent.h --- squid-4.0.20/src/ident/AclIdent.h 2017-06-02 00:49:17.000000000 +1200 +++ squid-4.0.21/src/ident/AclIdent.h 2017-07-02 20:41:18.000000000 +1200 @@ -40,20 +40,17 @@ ACLIdent & operator= (ACLIdent const &rhs); ~ACLIdent(); + /* ACL API */ virtual char const *typeString() const; virtual void parse(); virtual bool isProxyAuth() const {return true;} - + virtual void parseFlags(); virtual int match(ACLChecklist *checklist); virtual SBufList dump() const; virtual bool empty () const; virtual ACL *clone()const; private: - static Prototype UserRegistryProtoype; - static ACLIdent UserRegistryEntry_; - static Prototype RegexRegistryProtoype; - static ACLIdent RegexRegistryEntry_; ACLData *data; char const *type_; }; diff -u -r -N squid-4.0.20/src/ident/Makefile.in squid-4.0.21/src/ident/Makefile.in --- squid-4.0.20/src/ident/Makefile.in 2017-06-02 01:00:11.000000000 +1200 +++ squid-4.0.21/src/ident/Makefile.in 2017-07-02 20:41:27.000000000 +1200 @@ -1,7 +1,7 @@ -# Makefile.in generated by automake 1.15 from Makefile.am. +# Makefile.in generated by automake 1.15.1 from Makefile.am. # @configure_input@ -# Copyright (C) 1994-2014 Free Software Foundation, Inc. +# Copyright (C) 1994-2017 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, diff -u -r -N squid-4.0.20/src/ip/Makefile.in squid-4.0.21/src/ip/Makefile.in --- squid-4.0.20/src/ip/Makefile.in 2017-06-02 01:00:17.000000000 +1200 +++ squid-4.0.21/src/ip/Makefile.in 2017-07-02 20:41:27.000000000 +1200 @@ -1,7 +1,7 @@ -# Makefile.in generated by automake 1.15 from Makefile.am. +# Makefile.in generated by automake 1.15.1 from Makefile.am. # @configure_input@ -# Copyright (C) 1994-2014 Free Software Foundation, Inc. +# Copyright (C) 1994-2017 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, diff -u -r -N squid-4.0.20/src/ipc/Forwarder.cc squid-4.0.21/src/ipc/Forwarder.cc --- squid-4.0.20/src/ipc/Forwarder.cc 2017-06-02 00:49:17.000000000 +1200 +++ squid-4.0.21/src/ipc/Forwarder.cc 2017-07-02 20:41:18.000000000 +1200 @@ -62,6 +62,7 @@ // assume the pack() call failed because the message did not fit // TODO: add a more specific exception? handleError(); + return; } SendMessage(Ipc::Port::CoordinatorAddr(), message); diff -u -r -N squid-4.0.20/src/ipc/Forwarder.h squid-4.0.21/src/ipc/Forwarder.h --- squid-4.0.20/src/ipc/Forwarder.h 2017-06-02 00:49:17.000000000 +1200 +++ squid-4.0.21/src/ipc/Forwarder.h 2017-07-02 20:41:18.000000000 +1200 @@ -49,12 +49,14 @@ virtual void handleError(); virtual void handleTimeout(); virtual void handleException(const std::exception& e); - virtual void handleRemoteAck(); private: static void RequestTimedOut(void* param); void requestTimedOut(); void removeTimeoutEvent(); + + void handleRemoteAck(); + static AsyncCall::Pointer DequeueRequest(unsigned int requestId); protected: diff -u -r -N squid-4.0.20/src/ipc/Makefile.in squid-4.0.21/src/ipc/Makefile.in --- squid-4.0.20/src/ipc/Makefile.in 2017-06-02 01:00:22.000000000 +1200 +++ squid-4.0.21/src/ipc/Makefile.in 2017-07-02 20:41:27.000000000 +1200 @@ -1,7 +1,7 @@ -# Makefile.in generated by automake 1.15 from Makefile.am. +# Makefile.in generated by automake 1.15.1 from Makefile.am. # @configure_input@ -# Copyright (C) 1994-2014 Free Software Foundation, Inc. +# Copyright (C) 1994-2017 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, diff -u -r -N squid-4.0.20/src/log/access_log.cc squid-4.0.21/src/log/access_log.cc --- squid-4.0.20/src/log/access_log.cc 2017-06-02 00:49:17.000000000 +1200 +++ squid-4.0.21/src/log/access_log.cc 2017-07-02 20:41:18.000000000 +1200 @@ -84,7 +84,7 @@ xstrncpy(al->hier.host, dash_str, SQUIDHOSTNAMELEN); for (; log; log = log->next) { - if (log->aclList && checklist && checklist->fastCheck(log->aclList) != ACCESS_ALLOWED) + if (log->aclList && checklist && !checklist->fastCheck(log->aclList).allowed()) continue; // The special-case "none" type has no logfile object set diff -u -r -N squid-4.0.20/src/log/Config.cc squid-4.0.21/src/log/Config.cc --- squid-4.0.20/src/log/Config.cc 2017-06-02 00:49:17.000000000 +1200 +++ squid-4.0.21/src/log/Config.cc 2017-07-02 20:41:18.000000000 +1200 @@ -20,7 +20,27 @@ char *name, *def; if (!(name = ConfigParser::NextToken())) { + debugs(3, DBG_CRITICAL, "FATAL: missing logformat details in " << cfg_filename << " line " << config_lineno); self_destruct(); + return; + } + + // check for re-definition of built-in formats + if (strcmp(name, "squid") == 0 || + strcmp(name, "common") == 0 || + strcmp(name, "combined") == 0 || + strcmp(name, "useragent") == 0 || + strcmp(name, "referrer") == 0) { + debugs(3, DBG_PARSE_NOTE(DBG_IMPORTANT), "ERROR: logformat " << name << " is already defined. Ignoring."); + return; + } + + // check for re-definition of custom formats + for (auto i = logformats; i ; i = i->next) { + if (strcmp(i->name, name) == 0) { + debugs(3, DBG_PARSE_NOTE(DBG_IMPORTANT), "ERROR: logformat " << name << " is already defined. Ignoring."); + return; + } } ::Format::Format *nlf = new ::Format::Format(name); diff -u -r -N squid-4.0.20/src/log/DB/log_db_daemon.8 squid-4.0.21/src/log/DB/log_db_daemon.8 --- squid-4.0.20/src/log/DB/log_db_daemon.8 2017-06-02 09:57:57.000000000 +1200 +++ squid-4.0.21/src/log/DB/log_db_daemon.8 2017-07-02 20:57:36.000000000 +1200 @@ -1,4 +1,4 @@ -.\" Automatically generated by Pod::Man 4.08 (Pod::Simple 3.32) +.\" Automatically generated by Pod::Man 4.07 (Pod::Simple 3.32) .\" .\" Standard preamble: .\" ======================================================================== @@ -129,7 +129,7 @@ .\" ======================================================================== .\" .IX Title "LOG_DB_DAEMON 8" -.TH LOG_DB_DAEMON 8 "2017-06-01" "perl v5.24.1" "User Contributed Perl Documentation" +.TH LOG_DB_DAEMON 8 "2017-07-02" "perl v5.24.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-4.0.20/src/log/DB/Makefile.in squid-4.0.21/src/log/DB/Makefile.in --- squid-4.0.20/src/log/DB/Makefile.in 2017-06-02 01:00:27.000000000 +1200 +++ squid-4.0.21/src/log/DB/Makefile.in 2017-07-02 20:41:27.000000000 +1200 @@ -1,7 +1,7 @@ -# Makefile.in generated by automake 1.15 from Makefile.am. +# Makefile.in generated by automake 1.15.1 from Makefile.am. # @configure_input@ -# Copyright (C) 1994-2014 Free Software Foundation, Inc. +# Copyright (C) 1994-2017 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, diff -u -r -N squid-4.0.20/src/log/file/Makefile.in squid-4.0.21/src/log/file/Makefile.in --- squid-4.0.20/src/log/file/Makefile.in 2017-06-02 01:00:36.000000000 +1200 +++ squid-4.0.21/src/log/file/Makefile.in 2017-07-02 20:41:27.000000000 +1200 @@ -1,7 +1,7 @@ -# Makefile.in generated by automake 1.15 from Makefile.am. +# Makefile.in generated by automake 1.15.1 from Makefile.am. # @configure_input@ -# Copyright (C) 1994-2014 Free Software Foundation, Inc. +# Copyright (C) 1994-2017 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, diff -u -r -N squid-4.0.20/src/log/Makefile.in squid-4.0.21/src/log/Makefile.in --- squid-4.0.20/src/log/Makefile.in 2017-06-02 01:00:31.000000000 +1200 +++ squid-4.0.21/src/log/Makefile.in 2017-07-02 20:41:27.000000000 +1200 @@ -1,7 +1,7 @@ -# Makefile.in generated by automake 1.15 from Makefile.am. +# Makefile.in generated by automake 1.15.1 from Makefile.am. # @configure_input@ -# Copyright (C) 1994-2014 Free Software Foundation, Inc. +# Copyright (C) 1994-2017 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, diff -u -r -N squid-4.0.20/src/main.cc squid-4.0.21/src/main.cc --- squid-4.0.20/src/main.cc 2017-06-02 00:49:17.000000000 +1200 +++ squid-4.0.21/src/main.cc 2017-07-02 20:41:18.000000000 +1200 @@ -10,8 +10,9 @@ #include "squid.h" #include "AccessLogEntry.h" -#include "acl/Acl.h" +//#include "acl/Acl.h" #include "acl/Asn.h" +#include "acl/forward.h" #include "anyp/UriScheme.h" #include "AuthReg.h" #include "base/RunnersRegistry.h" @@ -387,9 +388,9 @@ " -C Do not catch fatal signals.\n" " -D OBSOLETE. Scheduled for removal.\n" " -F Don't serve any requests until store is rebuilt.\n" - " -N No daemon mode.\n" + " -N Master process runs in foreground and is a worker. No kids.\n" " --foreground\n" - " Parent process does not exit until its children have finished.\n" + " Master process runs in foreground and creates worker kids.\n" #if USE_WIN32_SERVICE " -O options\n" " Set Windows Service Command line options in Registry.\n" @@ -1339,6 +1340,39 @@ configured_once = 1; } +/// describes active (i.e., thrown but not yet handled) exception +static std::ostream & +CurrentException(std::ostream &os) +{ + if (std::current_exception()) { + try { + throw; // re-throw to recognize the exception type + } + catch (const std::exception &ex) { + os << ex.what(); + } + catch (...) { + os << "[unknown exception type]"; + } + } else { + os << "[no active exception]"; + } + return os; +} + +static void +OnTerminate() +{ + // ignore recursive calls to avoid termination loops + static bool terminating = false; + if (terminating) + return; + terminating = true; + + debugs(1, DBG_CRITICAL, "FATAL: Dying from an exception handling failure; exception: " << CurrentException); + abort(); +} + /// unsafe main routine -- may throw int SquidMain(int argc, char **argv); /// unsafe main routine wrapper to catch exceptions @@ -1372,12 +1406,15 @@ static int SquidMainSafe(int argc, char **argv) { + (void)std::set_terminate(&OnTerminate); + // XXX: This top-level catch works great for startup, but, during runtime, + // it erases valuable stack info. TODO: Let stack-preserving OnTerminate() + // handle FATAL runtime errors by splitting main code into protected + // startup, unprotected runtime, and protected termination sections! try { return SquidMain(argc, argv); - } catch (const std::exception &e) { - debugs(1, DBG_CRITICAL, "FATAL: " << e.what()); } catch (...) { - debugs(1, DBG_CRITICAL, "FATAL: dying from an unhandled exception."); + debugs(1, DBG_CRITICAL, "FATAL: " << CurrentException); } return -1; // TODO: return EXIT_FAILURE instead } @@ -1521,6 +1558,7 @@ /* we may want the parsing process to set this up in the future */ Store::Init(); + Acl::Init(); Auth::Init(); /* required for config parsing. NOP if !USE_AUTH */ Ip::ProbeTransport(); // determine IPv4 or IPv6 capabilities before parsing. @@ -1762,12 +1800,29 @@ return (DebugSignal > 0 || RotateSignal > 0 || ReconfigureSignal > 0 || ShutdownSignal > 0); } +#if !_SQUID_WINDOWS_ +/// makes the caller a daemon process running in the background +static void +GoIntoBackground() +{ + pid_t pid; + if ((pid = fork()) < 0) { + int xerrno = errno; + syslog(LOG_ALERT, "fork failed: %s", xstrerr(xerrno)); + // continue anyway, mimicking --foreground mode (XXX?) + } else if (pid > 0) { + // parent + exit(EXIT_SUCCESS); + } + // child, running as a background daemon (or a failed-to-fork parent) +} +#endif /* !_SQUID_WINDOWS_ */ + static void watch_child(char *argv[]) { #if !_SQUID_WINDOWS_ char *prog; - PidStatus status_f, status; pid_t pid; #ifdef TIOCNOTTY @@ -1780,21 +1835,12 @@ openlog(APP_SHORTNAME, LOG_PID | LOG_NDELAY | LOG_CONS, LOG_LOCAL4); - if ((pid = fork()) < 0) { - int xerrno = errno; - syslog(LOG_ALERT, "fork failed: %s", xstrerr(xerrno)); - } else if (pid > 0) { - // parent - if (opt_foreground) { - if (WaitForAnyPid(status_f, 0) < 0) { - int xerrno = errno; - syslog(LOG_ALERT, "WaitForAnyPid failed: %s", xstrerr(xerrno)); - } - } - - exit(0); - } + if (!opt_foreground) + GoIntoBackground(); + // TODO: Fails with --foreground if the calling process is process group + // leader, which is always (?) the case. Should probably moved to + // GoIntoBackground and executed only after successfully forking if (setsid() < 0) { int xerrno = errno; syslog(LOG_ALERT, "setsid failed: %s", xstrerr(xerrno)); @@ -1904,6 +1950,7 @@ int waitFlag = 0; if (masterSignaled()) waitFlag = WNOHANG; + PidStatus status; pid = WaitForAnyPid(status, waitFlag); // check for a stopped kid diff -u -r -N squid-4.0.20/src/Makefile.am squid-4.0.21/src/Makefile.am --- squid-4.0.20/src/Makefile.am 2017-06-02 00:49:17.000000000 +1200 +++ squid-4.0.21/src/Makefile.am 2017-07-02 20:41:18.000000000 +1200 @@ -483,6 +483,8 @@ whois.cc \ wordlist.h \ wordlist.cc \ + XactionInitiator.h \ + XactionInitiator.cc \ $(WIN32_SOURCE) \ $(WINSVC_SOURCE) diff -u -r -N squid-4.0.20/src/Makefile.in squid-4.0.21/src/Makefile.in --- squid-4.0.20/src/Makefile.in 2017-06-02 00:54:20.000000000 +1200 +++ squid-4.0.21/src/Makefile.in 2017-07-02 20:41:24.000000000 +1200 @@ -1,7 +1,7 @@ -# Makefile.in generated by automake 1.15 from Makefile.am. +# Makefile.in generated by automake 1.15.1 from Makefile.am. # @configure_input@ -# Copyright (C) 1994-2014 Free Software Foundation, Inc. +# Copyright (C) 1994-2017 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -309,8 +309,9 @@ MemStore.h time.cc TimeOrTag.h tools.h tools.cc tunnel.cc \ typedefs.h unlinkd.h unlinkd.cc url.cc URL.h urn.h urn.cc \ wccp.h wccp.cc wccp2.h wccp2.cc whois.h whois.cc wordlist.h \ - wordlist.cc win32.cc WinSvc.cc LoadableModule.h \ - LoadableModule.cc LoadableModules.h LoadableModules.cc + wordlist.cc XactionInitiator.h XactionInitiator.cc win32.cc \ + WinSvc.cc LoadableModule.h LoadableModule.cc LoadableModules.h \ + LoadableModules.cc am__objects_1 = AclRegs.$(OBJEXT) AuthReg.$(OBJEXT) am__objects_2 = delay_pools.$(OBJEXT) DelayId.$(OBJEXT) \ DelayBucket.$(OBJEXT) DelayConfig.$(OBJEXT) \ @@ -383,8 +384,8 @@ MemStore.$(OBJEXT) time.$(OBJEXT) tools.$(OBJEXT) \ tunnel.$(OBJEXT) $(am__objects_12) url.$(OBJEXT) urn.$(OBJEXT) \ wccp.$(OBJEXT) wccp2.$(OBJEXT) whois.$(OBJEXT) \ - wordlist.$(OBJEXT) $(am__objects_13) $(am__objects_14) \ - $(am__objects_16) + wordlist.$(OBJEXT) XactionInitiator.$(OBJEXT) \ + $(am__objects_13) $(am__objects_14) $(am__objects_16) am__EXTRA_squid_SOURCES_DIST = ConfigOption.h CommonPool.h \ CompositePoolNode.h delay_pools.cc DelayId.cc DelayId.h \ DelayIdComposite.h DelayBucket.cc DelayBucket.h DelayConfig.cc \ @@ -2905,8 +2906,8 @@ MemStore.cc MemStore.h time.cc TimeOrTag.h tools.h tools.cc \ tunnel.cc typedefs.h $(UNLINKDSOURCE) url.cc URL.h urn.h \ urn.cc wccp.h wccp.cc wccp2.h wccp2.cc whois.h whois.cc \ - wordlist.h wordlist.cc $(WIN32_SOURCE) $(WINSVC_SOURCE) \ - $(am__append_9) + wordlist.h wordlist.cc XactionInitiator.h XactionInitiator.cc \ + $(WIN32_SOURCE) $(WINSVC_SOURCE) $(am__append_9) EXTRA_squid_SOURCES = \ $(all_AUTHMODULES) \ ConfigOption.h \ @@ -6616,6 +6617,7 @@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/String.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/Transients.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/WinSvc.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/XactionInitiator.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cache_cf.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cache_manager.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/carp.Po@am__quote@ diff -u -r -N squid-4.0.20/src/MasterXaction.h squid-4.0.21/src/MasterXaction.h --- squid-4.0.20/src/MasterXaction.h 2017-06-02 00:49:17.000000000 +1200 +++ squid-4.0.21/src/MasterXaction.h 2017-07-02 20:41:18.000000000 +1200 @@ -10,9 +10,12 @@ #define SQUID_SRC_MASTERXACTION_H #include "anyp/forward.h" +#include "anyp/PortCfg.h" #include "base/InstanceId.h" #include "base/Lock.h" +#include "base/RefCount.h" #include "comm/forward.h" +#include "XactionInitiator.h" /** Master transaction details. * @@ -38,6 +41,8 @@ public: typedef RefCount Pointer; + explicit MasterXaction(const XactionInitiator anInitiator) : initiator(anInitiator) {}; + /// transaction ID. InstanceId id; @@ -47,6 +52,9 @@ /// the client TCP connection which originated this transaction Comm::ConnectionPointer tcpClient; + /// the initiator of this transaction + XactionInitiator initiator; + // TODO: add state from other Jobs in the transaction }; diff -u -r -N squid-4.0.20/src/mem/Makefile.in squid-4.0.21/src/mem/Makefile.in --- squid-4.0.20/src/mem/Makefile.in 2017-06-02 01:00:44.000000000 +1200 +++ squid-4.0.21/src/mem/Makefile.in 2017-07-02 20:41:27.000000000 +1200 @@ -1,7 +1,7 @@ -# Makefile.in generated by automake 1.15 from Makefile.am. +# Makefile.in generated by automake 1.15.1 from Makefile.am. # @configure_input@ -# Copyright (C) 1994-2014 Free Software Foundation, Inc. +# Copyright (C) 1994-2017 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, diff -u -r -N squid-4.0.20/src/MemStore.cc squid-4.0.21/src/MemStore.cc --- squid-4.0.20/src/MemStore.cc 2017-06-02 00:49:17.000000000 +1200 +++ squid-4.0.21/src/MemStore.cc 2017-07-02 20:41:18.000000000 +1200 @@ -474,7 +474,7 @@ e.ping_status = PING_NONE; EBIT_CLR(e.flags, RELEASE_REQUEST); - EBIT_CLR(e.flags, KEY_PRIVATE); + e.clearPrivate(); EBIT_SET(e.flags, ENTRY_VALIDATED); MemObject::MemCache &mc = e.mem_obj->memCache; diff -u -r -N squid-4.0.20/src/mgr/Forwarder.cc squid-4.0.21/src/mgr/Forwarder.cc --- squid-4.0.20/src/mgr/Forwarder.cc 2017-06-02 00:49:17.000000000 +1200 +++ squid-4.0.21/src/mgr/Forwarder.cc 2017-07-02 20:41:18.000000000 +1200 @@ -102,17 +102,6 @@ mustStop("commClosed"); } -/// called when Coordinator starts processing the request -void -Mgr::Forwarder::handleRemoteAck() -{ - Ipc::Forwarder::handleRemoteAck(); - - Must(entry != NULL); - EBIT_CLR(entry->flags, ENTRY_FWD_HDR_WAIT); - entry->complete(); -} - /// send error page void Mgr::Forwarder::sendError(ErrorState *error) diff -u -r -N squid-4.0.20/src/mgr/Forwarder.h squid-4.0.21/src/mgr/Forwarder.h --- squid-4.0.20/src/mgr/Forwarder.h 2017-06-02 00:49:17.000000000 +1200 +++ squid-4.0.21/src/mgr/Forwarder.h 2017-07-02 20:41:18.000000000 +1200 @@ -42,7 +42,6 @@ virtual void handleError(); virtual void handleTimeout(); virtual void handleException(const std::exception& e); - virtual void handleRemoteAck(); private: void noteCommClosed(const CommCloseCbParams& params); diff -u -r -N squid-4.0.20/src/mgr/Inquirer.cc squid-4.0.21/src/mgr/Inquirer.cc --- squid-4.0.20/src/mgr/Inquirer.cc 2017-06-02 00:49:17.000000000 +1200 +++ squid-4.0.21/src/mgr/Inquirer.cc 2017-07-02 20:41:18.000000000 +1200 @@ -76,7 +76,8 @@ if (strands.empty()) { LOCAL_ARRAY(char, url, MAX_URL); snprintf(url, MAX_URL, "%s", aggrAction->command().params.httpUri.termedBuf()); - HttpRequest *req = HttpRequest::CreateFromUrl(url); + const MasterXaction::Pointer mx = new MasterXaction(XactionInitiator::initIpc); + HttpRequest *req = HttpRequest::FromUrl(url, mx); ErrorState err(ERR_INVALID_URL, Http::scNotFound, req); std::unique_ptr reply(err.BuildHttpReply()); replyBuf.reset(reply->pack()); diff -u -r -N squid-4.0.20/src/mgr/Makefile.in squid-4.0.21/src/mgr/Makefile.in --- squid-4.0.20/src/mgr/Makefile.in 2017-06-02 01:00:48.000000000 +1200 +++ squid-4.0.21/src/mgr/Makefile.in 2017-07-02 20:41:27.000000000 +1200 @@ -1,7 +1,7 @@ -# Makefile.in generated by automake 1.15 from Makefile.am. +# Makefile.in generated by automake 1.15.1 from Makefile.am. # @configure_input@ -# Copyright (C) 1994-2014 Free Software Foundation, Inc. +# Copyright (C) 1994-2017 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, diff -u -r -N squid-4.0.20/src/mime.cc squid-4.0.21/src/mime.cc --- squid-4.0.20/src/mime.cc 2017-06-02 00:49:17.000000000 +1200 +++ squid-4.0.21/src/mime.cc 2017-07-02 20:41:18.000000000 +1200 @@ -402,7 +402,8 @@ EBIT_SET(e->flags, ENTRY_SPECIAL); e->setPublicKey(); e->buffer(); - HttpRequest *r = HttpRequest::CreateFromUrl(url_); + const MasterXaction::Pointer mx = new MasterXaction(XactionInitiator::initIcon); + HttpRequest *r = HttpRequest::FromUrl(url_, mx); if (NULL == r) fatalf("mimeLoadIcon: cannot parse internal URL: %s", url_); diff -u -r -N squid-4.0.20/src/neighbors.cc squid-4.0.21/src/neighbors.cc --- squid-4.0.20/src/neighbors.cc 2017-06-02 00:49:17.000000000 +1200 +++ squid-4.0.21/src/neighbors.cc 2017-07-02 20:41:18.000000000 +1200 @@ -168,7 +168,7 @@ ACLFilledChecklist checklist(p->access, request, NULL); - return (checklist.fastCheck() == ACCESS_ALLOWED); + return checklist.fastCheck().allowed(); } /* Return TRUE if it is okay to send an ICP request to this CachePeer. */ @@ -1382,7 +1382,8 @@ p->in_addr.toUrl(url+7, MAX_URL -8 ); strcat(url, "/"); fake = storeCreateEntry(url, url, RequestFlags(), Http::METHOD_GET); - HttpRequest *req = HttpRequest::CreateFromUrl(url); + const MasterXaction::Pointer mx = new MasterXaction(XactionInitiator::initPeerMcast); + HttpRequest *req = HttpRequest::FromUrl(url, mx); psstate = new ps_state; psstate->request = req; HTTPMSGLOCK(psstate->request); diff -u -r -N squid-4.0.20/src/Notes.cc squid-4.0.21/src/Notes.cc --- squid-4.0.20/src/Notes.cc 2017-06-02 00:49:17.000000000 +1200 +++ squid-4.0.21/src/Notes.cc 2017-07-02 20:41:18.000000000 +1200 @@ -47,10 +47,10 @@ HTTPMSGLOCK(ch.reply); for (VLI i = values.begin(); i != values.end(); ++i ) { - const int ret= ch.fastCheck((*i)->aclList); + const auto ret= ch.fastCheck((*i)->aclList); debugs(93, 5, HERE << "Check for header name: " << key << ": " << (*i)->value <<", HttpRequest: " << request << " HttpReply: " << reply << " matched: " << ret); - if (ret == ACCESS_ALLOWED) { + if (ret.allowed()) { if (al != NULL && (*i)->valueFormat != NULL) { static MemBuf mb; mb.reset(); diff -u -r -N squid-4.0.20/src/parser/Makefile.in squid-4.0.21/src/parser/Makefile.in --- squid-4.0.20/src/parser/Makefile.in 2017-06-02 01:00:53.000000000 +1200 +++ squid-4.0.21/src/parser/Makefile.in 2017-07-02 20:41:27.000000000 +1200 @@ -1,7 +1,7 @@ -# Makefile.in generated by automake 1.15 from Makefile.am. +# Makefile.in generated by automake 1.15.1 from Makefile.am. # @configure_input@ -# Copyright (C) 1994-2014 Free Software Foundation, Inc. +# Copyright (C) 1994-2017 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, diff -u -r -N squid-4.0.20/src/peer_digest.cc squid-4.0.21/src/peer_digest.cc --- squid-4.0.20/src/peer_digest.cc 2017-06-02 00:49:17.000000000 +1200 +++ squid-4.0.21/src/peer_digest.cc 2017-07-02 20:41:18.000000000 +1200 @@ -319,7 +319,8 @@ else url = xstrdup(internalRemoteUri(p->host, p->http_port, "/squid-internal-periodic/", SBuf(StoreDigestFileName))); - req = HttpRequest::CreateFromUrl(url); + const MasterXaction::Pointer mx = new MasterXaction(XactionInitiator::initCacheDigest); + req = HttpRequest::FromUrl(url, mx); assert(req); diff -u -r -N squid-4.0.20/src/PeerPoolMgr.cc squid-4.0.21/src/PeerPoolMgr.cc --- squid-4.0.20/src/PeerPoolMgr.cc 2017-06-02 00:49:17.000000000 +1200 +++ squid-4.0.21/src/PeerPoolMgr.cc 2017-07-02 20:41:18.000000000 +1200 @@ -18,6 +18,7 @@ #include "FwdState.h" #include "globals.h" #include "HttpRequest.h" +#include "MasterXaction.h" #include "neighbors.h" #include "pconn.h" #include "PeerPoolMgr.h" @@ -59,9 +60,10 @@ { AsyncJob::start(); + const MasterXaction::Pointer mx = new MasterXaction(XactionInitiator::initPeerPool); // ErrorState, getOutgoingAddress(), and other APIs may require a request. // We fake one. TODO: Optionally send this request to peers? - request = new HttpRequest(Http::METHOD_OPTIONS, AnyP::PROTO_HTTP, "http", "*"); + request = new HttpRequest(Http::METHOD_OPTIONS, AnyP::PROTO_HTTP, "http", "*", mx); request->url.host(peer->host); checkpoint("peer initialized"); diff -u -r -N squid-4.0.20/src/redirect.cc squid-4.0.21/src/redirect.cc --- squid-4.0.20/src/redirect.cc 2017-06-02 00:49:17.000000000 +1200 +++ squid-4.0.21/src/redirect.cc 2017-07-02 20:41:18.000000000 +1200 @@ -108,9 +108,9 @@ // if we still have anything in other() after all that // parse it into status=, url= and rewrite-url= keys if (replySize) { - /* 2012-06-28: This cast is due to urlParse() truncating too-long URLs itself. + /* 2012-06-28: This cast is due to URL::parse() truncating too-long URLs itself. * At this point altering the helper buffer in that way is not harmful, but annoying. - * When Bug 1961 is resolved and urlParse has a const API, this needs to die. + * When Bug 1961 is resolved and URL::parse has a const API, this needs to die. */ MemBuf replyBuffer; replyBuffer.init(replySize, replySize); diff -u -r -N squid-4.0.20/src/repl/Makefile.in squid-4.0.21/src/repl/Makefile.in --- squid-4.0.20/src/repl/Makefile.in 2017-06-02 01:00:57.000000000 +1200 +++ squid-4.0.21/src/repl/Makefile.in 2017-07-02 20:41:27.000000000 +1200 @@ -1,7 +1,7 @@ -# Makefile.in generated by automake 1.15 from Makefile.am. +# Makefile.in generated by automake 1.15.1 from Makefile.am. # @configure_input@ -# Copyright (C) 1994-2014 Free Software Foundation, Inc. +# Copyright (C) 1994-2017 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, diff -u -r -N squid-4.0.20/src/RequestFlags.h squid-4.0.21/src/RequestFlags.h --- squid-4.0.20/src/RequestFlags.h 2017-06-02 00:49:17.000000000 +1200 +++ squid-4.0.21/src/RequestFlags.h 2017-07-02 20:41:18.000000000 +1200 @@ -72,9 +72,6 @@ bool spoofClientIp = false; /** set if the request is internal (\see ClientHttpRequest::flags.internal)*/ bool internal = false; - //XXX this is set in in clientBeginRequest, but never tested. - /** set for internally-generated requests */ - bool internalClient = false; /** if set, request to try very hard to keep the connection alive */ bool mustKeepalive = false; /** set if the rquest wants connection oriented auth */ diff -u -r -N squid-4.0.20/src/sbuf/Makefile.in squid-4.0.21/src/sbuf/Makefile.in --- squid-4.0.20/src/sbuf/Makefile.in 2017-06-02 01:00:59.000000000 +1200 +++ squid-4.0.21/src/sbuf/Makefile.in 2017-07-02 20:41:27.000000000 +1200 @@ -1,7 +1,7 @@ -# Makefile.in generated by automake 1.15 from Makefile.am. +# Makefile.in generated by automake 1.15.1 from Makefile.am. # @configure_input@ -# Copyright (C) 1994-2014 Free Software Foundation, Inc. +# Copyright (C) 1994-2017 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, diff -u -r -N squid-4.0.20/src/security/cert_generators/file/Makefile.in squid-4.0.21/src/security/cert_generators/file/Makefile.in --- squid-4.0.20/src/security/cert_generators/file/Makefile.in 2017-06-02 01:01:04.000000000 +1200 +++ squid-4.0.21/src/security/cert_generators/file/Makefile.in 2017-07-02 20:41:27.000000000 +1200 @@ -1,7 +1,7 @@ -# Makefile.in generated by automake 1.15 from Makefile.am. +# Makefile.in generated by automake 1.15.1 from Makefile.am. # @configure_input@ -# Copyright (C) 1994-2014 Free Software Foundation, Inc. +# Copyright (C) 1994-2017 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, diff -u -r -N squid-4.0.20/src/security/cert_generators/Makefile.in squid-4.0.21/src/security/cert_generators/Makefile.in --- squid-4.0.20/src/security/cert_generators/Makefile.in 2017-06-02 01:01:03.000000000 +1200 +++ squid-4.0.21/src/security/cert_generators/Makefile.in 2017-07-02 20:41:27.000000000 +1200 @@ -1,7 +1,7 @@ -# Makefile.in generated by automake 1.15 from Makefile.am. +# Makefile.in generated by automake 1.15.1 from Makefile.am. # @configure_input@ -# Copyright (C) 1994-2014 Free Software Foundation, Inc. +# Copyright (C) 1994-2017 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, diff -u -r -N squid-4.0.20/src/security/cert_validators/fake/Makefile.in squid-4.0.21/src/security/cert_validators/fake/Makefile.in --- squid-4.0.20/src/security/cert_validators/fake/Makefile.in 2017-06-02 01:01:07.000000000 +1200 +++ squid-4.0.21/src/security/cert_validators/fake/Makefile.in 2017-07-02 20:41:27.000000000 +1200 @@ -1,7 +1,7 @@ -# Makefile.in generated by automake 1.15 from Makefile.am. +# Makefile.in generated by automake 1.15.1 from Makefile.am. # @configure_input@ -# Copyright (C) 1994-2014 Free Software Foundation, Inc. +# Copyright (C) 1994-2017 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, diff -u -r -N squid-4.0.20/src/security/cert_validators/fake/security_fake_certverify.8 squid-4.0.21/src/security/cert_validators/fake/security_fake_certverify.8 --- squid-4.0.20/src/security/cert_validators/fake/security_fake_certverify.8 2017-06-02 09:59:08.000000000 +1200 +++ squid-4.0.21/src/security/cert_validators/fake/security_fake_certverify.8 2017-07-02 20:57:36.000000000 +1200 @@ -1,4 +1,4 @@ -.\" Automatically generated by Pod::Man 4.08 (Pod::Simple 3.32) +.\" Automatically generated by Pod::Man 4.07 (Pod::Simple 3.32) .\" .\" Standard preamble: .\" ======================================================================== @@ -129,7 +129,7 @@ .\" ======================================================================== .\" .IX Title "SECURITY_FAKE_CERTVERIFY 8" -.TH SECURITY_FAKE_CERTVERIFY 8 "2017-06-01" "perl v5.24.1" "User Contributed Perl Documentation" +.TH SECURITY_FAKE_CERTVERIFY 8 "2017-07-02" "perl v5.24.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-4.0.20/src/security/cert_validators/Makefile.in squid-4.0.21/src/security/cert_validators/Makefile.in --- squid-4.0.20/src/security/cert_validators/Makefile.in 2017-06-02 01:01:05.000000000 +1200 +++ squid-4.0.21/src/security/cert_validators/Makefile.in 2017-07-02 20:41:27.000000000 +1200 @@ -1,7 +1,7 @@ -# Makefile.in generated by automake 1.15 from Makefile.am. +# Makefile.in generated by automake 1.15.1 from Makefile.am. # @configure_input@ -# Copyright (C) 1994-2014 Free Software Foundation, Inc. +# Copyright (C) 1994-2017 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, diff -u -r -N squid-4.0.20/src/security/Makefile.in squid-4.0.21/src/security/Makefile.in --- squid-4.0.20/src/security/Makefile.in 2017-06-02 01:01:01.000000000 +1200 +++ squid-4.0.21/src/security/Makefile.in 2017-07-02 20:41:27.000000000 +1200 @@ -1,7 +1,7 @@ -# Makefile.in generated by automake 1.15 from Makefile.am. +# Makefile.in generated by automake 1.15.1 from Makefile.am. # @configure_input@ -# Copyright (C) 1994-2014 Free Software Foundation, Inc. +# Copyright (C) 1994-2017 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, diff -u -r -N squid-4.0.20/src/security/PeerConnector.cc squid-4.0.21/src/security/PeerConnector.cc --- squid-4.0.20/src/security/PeerConnector.cc 2017-06-02 00:49:17.000000000 +1200 +++ squid-4.0.21/src/security/PeerConnector.cc 2017-07-02 20:41:18.000000000 +1200 @@ -338,7 +338,7 @@ bool allowed = false; if (check) { check->sslErrors = new Security::CertErrors(Security::CertError(i->error_no, i->cert, i->error_depth)); - if (check->fastCheck() == ACCESS_ALLOWED) + if (check->fastCheck().allowed()) allowed = true; } // else the Config.ssl_client.cert_error access list is not defined @@ -633,7 +633,7 @@ PeerConnectorCertDownloaderDialer(&Security::PeerConnector::certDownloadingDone, this)); const Downloader *csd = (request ? dynamic_cast(request->downloader.valid()) : nullptr); - Downloader *dl = new Downloader(url, certCallback, csd ? csd->nestedLevel() + 1 : 1); + Downloader *dl = new Downloader(url, certCallback, XactionInitiator::initCertFetcher, csd ? csd->nestedLevel() + 1 : 1); AsyncJob::Start(dl); } diff -u -r -N squid-4.0.20/src/security/Session.cc squid-4.0.21/src/security/Session.cc --- squid-4.0.20/src/security/Session.cc 2017-06-02 00:49:17.000000000 +1200 +++ squid-4.0.21/src/security/Session.cc 2017-07-02 20:41:18.000000000 +1200 @@ -23,6 +23,11 @@ #define SSL_SESSION_ID_SIZE 32 #define SSL_SESSION_MAX_SIZE 10*1024 +#if USE_OPENSSL +static Ipc::MemMap *SessionCache = nullptr; +static const char *SessionCacheName = "tls_session_cache"; +#endif + #if USE_OPENSSL || USE_GNUTLS static int tls_read_method(int fd, char *buf, int len) @@ -274,6 +279,113 @@ return false; } +#if USE_OPENSSL +static int +store_session_cb(SSL *ssl, SSL_SESSION *session) +{ + if (!SessionCache) + return 0; + + debugs(83, 5, "Request to store SSL_SESSION"); + + SSL_SESSION_set_timeout(session, Config.SSL.session_ttl); + +#if HAVE_LIBSSL_SSL_SESSION_GET_ID + unsigned int idlen; + const unsigned char *id = SSL_SESSION_get_id(session, &idlen); +#else + unsigned char *id = session->session_id; + unsigned int idlen = session->session_id_length; +#endif + // XXX: the other calls [to openForReading()] do not copy the sessionId to a char buffer, does this really have to? + unsigned char key[MEMMAP_SLOT_KEY_SIZE]; + // Session ids are of size 32bytes. They should always fit to a + // MemMap::Slot::key + assert(idlen <= MEMMAP_SLOT_KEY_SIZE); + memset(key, 0, sizeof(key)); + memcpy(key, id, idlen); + int pos; + if (auto slotW = SessionCache->openForWriting(static_cast(key), pos)) { + int lenRequired = i2d_SSL_SESSION(session, nullptr); + if (lenRequired < MEMMAP_SLOT_DATA_SIZE) { + unsigned char *p = static_cast(slotW->p); + lenRequired = i2d_SSL_SESSION(session, &p); + slotW->set(key, nullptr, lenRequired, squid_curtime + Config.SSL.session_ttl); + } + SessionCache->closeForWriting(pos); + debugs(83, 5, "wrote an SSL_SESSION entry of size " << lenRequired << " at pos " << pos); + } + return 0; +} + +static void +remove_session_cb(SSL_CTX *, SSL_SESSION *sessionID) +{ + if (!SessionCache) + return; + + debugs(83, 5, "Request to remove corrupted or not valid SSL_SESSION"); + int pos; + if (SessionCache->openForReading(reinterpret_cast(sessionID), pos)) { + SessionCache->closeForReading(pos); + // TODO: + // What if we are not able to remove the session? + // Maybe schedule a job to remove it later? + // For now we just have an invalid entry in cache until will be expired + // The OpenSSL library will reject it when we try to use it + SessionCache->free(pos); + } +} + +static SSL_SESSION * +#if SQUID_USE_CONST_SSL_SESSION_CBID +get_session_cb(SSL *, const unsigned char *sessionID, int len, int *copy) +#else +get_session_cb(SSL *, unsigned char *sessionID, int len, int *copy) +#endif +{ + if (!SessionCache) + return nullptr; + + const unsigned int *p = reinterpret_cast(sessionID); + debugs(83, 5, "Request to search for SSL_SESSION of len: " << + len << p[0] << ":" << p[1]); + + SSL_SESSION *session = nullptr; + int pos; + if (const auto slot = SessionCache->openForReading(static_cast(sessionID), pos)) { + if (slot->expire > squid_curtime) { + const unsigned char *ptr = slot->p; + session = d2i_SSL_SESSION(nullptr, &ptr, slot->pSize); + debugs(83, 5, "SSL_SESSION retrieved from cache at pos " << pos); + } else + debugs(83, 5, "SSL_SESSION in cache expired"); + SessionCache->closeForReading(pos); + } + + if (!session) + debugs(83, 5, "Failed to retrieve SSL_SESSION from cache\n"); + + // With the parameter copy the callback can require the SSL engine + // to increment the reference count of the SSL_SESSION object, Normally + // the reference count is not incremented and therefore the session must + // not be explicitly freed with SSL_SESSION_free(3). + *copy = 0; + return session; +} + +void +Security::SetSessionCacheCallbacks(Security::ContextPointer &ctx) +{ + if (SessionCache) { + SSL_CTX_set_session_cache_mode(ctx.get(), SSL_SESS_CACHE_SERVER|SSL_SESS_CACHE_NO_INTERNAL); + SSL_CTX_sess_set_new_cb(ctx.get(), store_session_cb); + SSL_CTX_sess_set_remove_cb(ctx.get(), remove_session_cb); + SSL_CTX_sess_set_get_cb(ctx.get(), get_session_cb); + } +} +#endif /* USE_OPENSSL */ + void initializeSessionCache() { @@ -285,15 +397,15 @@ int configuredItems = ::Config.SSL.sessionCacheSize / sizeof(Ipc::MemMap::Slot); if (IamWorkerProcess() && configuredItems) - Ssl::SessionCache = new Ipc::MemMap(Ssl::SessionCacheName); + SessionCache = new Ipc::MemMap(SessionCacheName); else { - Ssl::SessionCache = nullptr; + SessionCache = nullptr; return; } for (AnyP::PortCfgPointer s = HttpPortList; s != nullptr; s = s->next) { if (s->secure.staticContext) - Ssl::SetSessionCallbacks(s->secure.staticContext); + Security::SetSessionCacheCallbacks(s->secure.staticContext); } #endif } @@ -319,8 +431,8 @@ void SharedSessionCacheRr::useConfig() { -#if USE_OPENSSL // while Ssl:: bits in use - if (Ssl::SessionCache || !isTlsServer()) //no need to configure ssl session cache. +#if USE_OPENSSL + if (SessionCache || !isTlsServer()) // no need to configure SSL_SESSION* cache. return; Ipc::Mem::RegisteredRunner::useConfig(); @@ -331,19 +443,19 @@ void SharedSessionCacheRr::create() { - if (!isTlsServer()) //no need to configure ssl session cache. + if (!isTlsServer()) // no need to configure SSL_SESSION* cache. return; -#if USE_OPENSSL // while Ssl:: bits in use +#if USE_OPENSSL if (int items = Config.SSL.sessionCacheSize / sizeof(Ipc::MemMap::Slot)) - owner = Ipc::MemMap::Init(Ssl::SessionCacheName, items); + owner = Ipc::MemMap::Init(SessionCacheName, items); #endif } SharedSessionCacheRr::~SharedSessionCacheRr() { // XXX: Enable after testing to reduce at-exit memory "leaks". - // delete Ssl::SessionCache; + // delete SessionCache; delete owner; } diff -u -r -N squid-4.0.20/src/security/Session.h squid-4.0.21/src/security/Session.h --- squid-4.0.20/src/security/Session.h 2017-06-02 00:49:17.000000000 +1200 +++ squid-4.0.21/src/security/Session.h 2017-07-02 20:41:18.000000000 +1200 @@ -78,6 +78,10 @@ void SetSessionResumeData(const Security::SessionPointer &, const Security::SessionStatePointer &); #if USE_OPENSSL +// TODO: remove from public API. It is only public because of configureSslContext() in ssl/support.cc +/// Setup the given TLS context with callbacks used to manage the session cache +void SetSessionCacheCallbacks(Security::ContextPointer &); + /// Helper function to retrieve a (non-locked) ContextPointer from a SessionPointer inline Security::ContextPointer GetFrom(Security::SessionPointer &s) diff -u -r -N squid-4.0.20/src/servers/FtpServer.cc squid-4.0.21/src/servers/FtpServer.cc --- squid-4.0.20/src/servers/FtpServer.cc 2017-06-02 00:49:17.000000000 +1200 +++ squid-4.0.21/src/servers/FtpServer.cc 2017-07-02 20:41:18.000000000 +1200 @@ -303,12 +303,8 @@ Must(http != NULL); HttpRequest *const request = http->request; Must(request != NULL); - - // this is not an idle connection, so we do not want I/O monitoring - const bool monitor = false; - // make FTP peer connection exclusive to our request - pinConnection(conn, request, conn->getPeer(), false, monitor); + pinBusyConnection(conn, request); } void @@ -728,7 +724,9 @@ ¶ms : NULL; calcUri(path); char *newUri = xstrdup(uri.c_str()); - HttpRequest *const request = HttpRequest::CreateFromUrl(newUri, method); + MasterXaction::Pointer mx = new MasterXaction(XactionInitiator::initClient); + mx->tcpClient = clientConnection; + HttpRequest *const request = HttpRequest::FromUrl(newUri, mx, method); if (!request) { debugs(33, 5, "Invalid FTP URL: " << uri); uri.clear(); @@ -1545,7 +1543,7 @@ ClientHttpRequest *http = pipeline.front()->http; HttpRequest *request = http->request; ACLFilledChecklist bodyContinuationCheck(Config.accessList.forceRequestBodyContinuation, request, NULL); - if (bodyContinuationCheck.fastCheck() == ACCESS_ALLOWED) { + if (bodyContinuationCheck.fastCheck().allowed()) { request->forcedBodyContinuation = true; if (checkDataConnPost()) { // Write control Msg diff -u -r -N squid-4.0.20/src/servers/Http1Server.cc squid-4.0.21/src/servers/Http1Server.cc --- squid-4.0.20/src/servers/Http1Server.cc 2017-06-02 00:49:17.000000000 +1200 +++ squid-4.0.21/src/servers/Http1Server.cc 2017-07-02 20:41:18.000000000 +1200 @@ -132,7 +132,9 @@ return false; } - if ((request = HttpRequest::CreateFromUrl(http->uri, parser_->method())) == NULL) { + MasterXaction::Pointer mx = new MasterXaction(XactionInitiator::initClient); + mx->tcpClient = clientConnection; + if ((request = HttpRequest::FromUrl(http->uri, mx, parser_->method())) == NULL) { debugs(33, 5, "Invalid URL: " << http->uri); // setLogUri should called before repContext->setReplyToError setLogUri(http, http->uri, true); @@ -248,7 +250,7 @@ if (Config.accessList.forceRequestBodyContinuation) { ACLFilledChecklist bodyContinuationCheck(Config.accessList.forceRequestBodyContinuation, request.getRaw(), NULL); - if (bodyContinuationCheck.fastCheck() == ACCESS_ALLOWED) { + if (bodyContinuationCheck.fastCheck().allowed()) { debugs(33, 5, "Body Continuation forced"); request->forcedBodyContinuation = true; //sendControlMsg diff -u -r -N squid-4.0.20/src/servers/Makefile.in squid-4.0.21/src/servers/Makefile.in --- squid-4.0.20/src/servers/Makefile.in 2017-06-02 01:01:09.000000000 +1200 +++ squid-4.0.21/src/servers/Makefile.in 2017-07-02 20:41:27.000000000 +1200 @@ -1,7 +1,7 @@ -# Makefile.in generated by automake 1.15 from Makefile.am. +# Makefile.in generated by automake 1.15.1 from Makefile.am. # @configure_input@ -# Copyright (C) 1994-2014 Free Software Foundation, Inc. +# Copyright (C) 1994-2017 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, diff -u -r -N squid-4.0.20/src/servers/Server.h squid-4.0.21/src/servers/Server.h --- squid-4.0.20/src/servers/Server.h 2017-06-02 00:49:17.000000000 +1200 +++ squid-4.0.21/src/servers/Server.h 2017-07-02 20:41:18.000000000 +1200 @@ -19,6 +19,7 @@ #include "CommCalls.h" #include "Pipeline.h" #include "sbuf/SBuf.h" +#include "servers/forward.h" /** * Common base for all Server classes used @@ -27,7 +28,7 @@ class Server : virtual public AsyncJob, public BodyProducer { public: - Server(const MasterXaction::Pointer &xact); + Server(const MasterXactionPointer &xact); virtual ~Server() {} /* AsyncJob API */ diff -u -r -N squid-4.0.20/src/snmp/Makefile.in squid-4.0.21/src/snmp/Makefile.in --- squid-4.0.20/src/snmp/Makefile.in 2017-06-02 01:01:11.000000000 +1200 +++ squid-4.0.21/src/snmp/Makefile.in 2017-07-02 20:41:27.000000000 +1200 @@ -1,7 +1,7 @@ -# Makefile.in generated by automake 1.15 from Makefile.am. +# Makefile.in generated by automake 1.15.1 from Makefile.am. # @configure_input@ -# Copyright (C) 1994-2014 Free Software Foundation, Inc. +# Copyright (C) 1994-2017 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, diff -u -r -N squid-4.0.20/src/snmp_core.cc squid-4.0.21/src/snmp_core.cc --- squid-4.0.20/src/snmp_core.cc 2017-06-02 00:49:17.000000000 +1200 +++ squid-4.0.21/src/snmp_core.cc 2017-07-02 20:41:18.000000000 +1200 @@ -383,7 +383,6 @@ u_char *Community; u_char *buf = rq->buf; int len = rq->len; - allow_t allow = ACCESS_DENIED; if (!Config.accessList.snmp) { debugs(49, DBG_IMPORTANT, "WARNING: snmp_access not configured. agent query DENIED from : " << rq->from); @@ -402,9 +401,8 @@ ACLFilledChecklist checklist(Config.accessList.snmp, NULL, NULL); checklist.src_addr = rq->from; checklist.snmp_community = (char *) Community; - allow = checklist.fastCheck(); - if (allow == ACCESS_ALLOWED && (snmp_coexist_V2toV1(PDU))) { + if (checklist.fastCheck().allowed() && (snmp_coexist_V2toV1(PDU))) { rq->community = Community; rq->PDU = PDU; debugs(49, 5, "snmpAgentParse: reqid=[" << PDU->reqid << "]"); @@ -1130,51 +1128,9 @@ addr = i6addr; } -/* SNMP checklists */ -#include "acl/Strategised.h" -#include "acl/Strategy.h" -#include "acl/StringData.h" - -class ACLSNMPCommunityStrategy : public ACLStrategy -{ - -public: - virtual int match (ACLData * &, ACLFilledChecklist *, ACLFlags &); - static ACLSNMPCommunityStrategy *Instance(); - /* Not implemented to prevent copies of the instance. */ - /* Not private to prevent brain dead g++ warnings about - * private constructors with no friends */ - ACLSNMPCommunityStrategy(ACLSNMPCommunityStrategy const &); - -private: - static ACLSNMPCommunityStrategy Instance_; - ACLSNMPCommunityStrategy() {} - - ACLSNMPCommunityStrategy&operator=(ACLSNMPCommunityStrategy const &); -}; - -class ACLSNMPCommunity -{ - -private: - static ACL::Prototype RegistryProtoype; - static ACLStrategised RegistryEntry_; -}; - -ACL::Prototype ACLSNMPCommunity::RegistryProtoype(&ACLSNMPCommunity::RegistryEntry_, "snmp_community"); -ACLStrategised ACLSNMPCommunity::RegistryEntry_(new ACLStringData, ACLSNMPCommunityStrategy::Instance(), "snmp_community"); - int -ACLSNMPCommunityStrategy::match (ACLData * &data, ACLFilledChecklist *checklist, ACLFlags &) +ACLSNMPCommunityStrategy::match (ACLData * &data, ACLFilledChecklist *checklist) { return data->match (checklist->snmp_community); } -ACLSNMPCommunityStrategy * -ACLSNMPCommunityStrategy::Instance() -{ - return &Instance_; -} - -ACLSNMPCommunityStrategy ACLSNMPCommunityStrategy::Instance_; - diff -u -r -N squid-4.0.20/src/snmp_core.h squid-4.0.21/src/snmp_core.h --- squid-4.0.20/src/snmp_core.h 2017-06-02 00:49:17.000000000 +1200 +++ squid-4.0.21/src/snmp_core.h 2017-07-02 20:41:18.000000000 +1200 @@ -11,6 +11,7 @@ #ifndef SQUID_SNMP_CORE_H #define SQUID_SNMP_CORE_H +#include "acl/Strategy.h" #include "cache_snmp.h" #include "comm/forward.h" #include "ip/forward.h" @@ -51,5 +52,11 @@ void addr2oid(Ip::Address &addr, oid *Dest); void oid2addr(oid *Dest, Ip::Address &addr, u_int code); +class ACLSNMPCommunityStrategy: public ACLStrategy +{ +public: + virtual int match (ACLData *&data, ACLFilledChecklist *checklist) override; +}; + #endif /* SQUID_SNMP_CORE_H */ diff -u -r -N squid-4.0.20/src/squid.8.in squid-4.0.21/src/squid.8.in --- squid-4.0.20/src/squid.8.in 2017-06-02 00:49:17.000000000 +1200 +++ squid-4.0.21/src/squid.8.in 2017-07-02 20:41:18.000000000 +1200 @@ -271,11 +271,11 @@ .SH SEE ALSO .if !'po4a'hide' .B cachemgr.cgi "(8), " .if !'po4a'hide' .B squidclient "(1), " -.if !'po4a'hide' .B pam_auth "(8), " -.if !'po4a'hide' .B squid_ldap_auth "(8), " -.if !'po4a'hide' .B squid_ldap_group "(8), " +.if !'po4a'hide' .B basic_pam_auth "(8), " +.if !'po4a'hide' .B basic_ldap_auth "(8), " +.if !'po4a'hide' .B ext_ldap_group_acl "(8), " .if !'po4a'hide' .B ext_session_acl "(8), " -.if !'po4a'hide' .B squid_unix_group "(8), " +.if !'po4a'hide' .B ext_unix_group_acl "(8), " .br The Squid FAQ wiki .if !'po4a'hide' http://wiki.squid-cache.org/SquidFaq diff -u -r -N squid-4.0.20/src/ssl/helper.cc squid-4.0.21/src/ssl/helper.cc --- squid-4.0.20/src/ssl/helper.cc 2017-06-02 00:49:17.000000000 +1200 +++ squid-4.0.21/src/ssl/helper.cc 2017-07-02 20:41:18.000000000 +1200 @@ -7,13 +7,13 @@ */ #include "squid.h" -#include "../helper.h" #include "anyp/PortCfg.h" #include "fs_io.h" #include "helper/Reply.h" #include "SquidConfig.h" #include "SquidString.h" #include "SquidTime.h" +#include "src/helper.h" #include "ssl/cert_validate_message.h" #include "ssl/Config.h" #include "ssl/helper.h" @@ -22,6 +22,51 @@ Ssl::CertValidationHelper::LruCache *Ssl::CertValidationHelper::HelperCache = nullptr; #if USE_SSL_CRTD + +namespace Ssl { + +/// Initiator of an Ssl::Helper query. +class GeneratorRequestor { +public: + GeneratorRequestor(HLPCB *aCallback, void *aData): callback(aCallback), data(aData) {} + HLPCB *callback; + CallbackData data; +}; + +/// A pending Ssl::Helper request, combining the original and collapsed queries. +class GeneratorRequest { + CBDATA_CLASS(GeneratorRequest); + +public: + /// adds a GeneratorRequestor + void emplace(HLPCB *callback, void *data) { requestors.emplace_back(callback, data); } + + SBuf query; ///< Ssl::Helper request message (GeneratorRequests key) + + /// Ssl::Helper request initiators waiting for the same answer (FIFO). + typedef std::vector GeneratorRequestors; + GeneratorRequestors requestors; +}; + +/// Ssl::Helper query:GeneratorRequest map +typedef std::unordered_map GeneratorRequests; + +static void HandleGeneratorReply(void *data, const ::Helper::Reply &reply); + +} // namespace Ssl + +CBDATA_NAMESPACED_CLASS_INIT(Ssl, GeneratorRequest); + +/// prints Ssl::GeneratorRequest for debugging +static std::ostream & +operator <<(std::ostream &os, const Ssl::GeneratorRequest &gr) +{ + return os << "crtGenRq" << gr.query.id.value << "/" << gr.requestors.size(); +} + +/// pending Ssl::Helper requests (to all certificate generator helpers combined) +static Ssl::GeneratorRequests TheGeneratorRequests; + Ssl::Helper * Ssl::Helper::GetInstance() { static Ssl::Helper sslHelper; @@ -82,14 +127,44 @@ { assert(ssl_crtd); - std::string msg = message.compose(); - msg += '\n'; - if (!ssl_crtd->trySubmit(msg.c_str(), callback, data)) { - ::Helper::Reply failReply(::Helper::BrokenHelper); - failReply.notes.add("message", "error 45 Temporary network problem, please retry later"); - callback(data, failReply); + SBuf rawMessage(message.compose().c_str()); // XXX: helpers cannot use SBuf + rawMessage.append("\n", 1); + + const auto pending = TheGeneratorRequests.find(rawMessage); + if (pending != TheGeneratorRequests.end()) { + pending->second->emplace(callback, data); + debugs(83, 5, "collapsed request from " << data << " onto " << *pending->second); return; } + + GeneratorRequest *request = new GeneratorRequest; + request->query = rawMessage; + request->emplace(callback, data); + TheGeneratorRequests.emplace(request->query, request); + debugs(83, 5, "request from " << data << " as " << *request); + if (ssl_crtd->trySubmit(request->query.c_str(), HandleGeneratorReply, request)) + return; + + ::Helper::Reply failReply(::Helper::BrokenHelper); + failReply.notes.add("message", "error 45 Temporary network problem, please retry later"); + HandleGeneratorReply(request, failReply); +} + +/// receives helper response +static void +Ssl::HandleGeneratorReply(void *data, const ::Helper::Reply &reply) +{ + const std::unique_ptr request(static_cast(data)); + assert(request); + const auto erased = TheGeneratorRequests.erase(request->query); + assert(erased); + + for (auto &requestor: request->requestors) { + if (void *cbdata = requestor.data.validDone()) { + debugs(83, 5, "to " << cbdata << " in " << *request); + requestor.callback(cbdata, reply); + } + } } #endif //USE_SSL_CRTD diff -u -r -N squid-4.0.20/src/ssl/Makefile.in squid-4.0.21/src/ssl/Makefile.in --- squid-4.0.20/src/ssl/Makefile.in 2017-06-02 01:01:13.000000000 +1200 +++ squid-4.0.21/src/ssl/Makefile.in 2017-07-02 20:41:27.000000000 +1200 @@ -1,7 +1,7 @@ -# Makefile.in generated by automake 1.15 from Makefile.am. +# Makefile.in generated by automake 1.15.1 from Makefile.am. # @configure_input@ -# Copyright (C) 1994-2014 Free Software Foundation, Inc. +# Copyright (C) 1994-2017 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, diff -u -r -N squid-4.0.20/src/ssl/PeekingPeerConnector.cc squid-4.0.21/src/ssl/PeekingPeerConnector.cc --- squid-4.0.20/src/ssl/PeekingPeerConnector.cc 2017-06-02 00:49:17.000000000 +1200 +++ squid-4.0.21/src/ssl/PeekingPeerConnector.cc 2017-07-02 20:41:18.000000000 +1200 @@ -36,7 +36,7 @@ void Ssl::PeekingPeerConnector::checkForPeekAndSpliceDone(allow_t answer) { - const Ssl::BumpMode finalAction = (answer.code == ACCESS_ALLOWED) ? + const Ssl::BumpMode finalAction = answer.allowed() ? static_cast(answer.kind): checkForPeekAndSpliceGuess(); checkForPeekAndSpliceMatched(finalAction); diff -u -r -N squid-4.0.20/src/ssl/ServerBump.h squid-4.0.21/src/ssl/ServerBump.h --- squid-4.0.20/src/ssl/ServerBump.h 2017-06-02 00:49:17.000000000 +1200 +++ squid-4.0.21/src/ssl/ServerBump.h 2017-07-02 20:41:18.000000000 +1200 @@ -47,7 +47,6 @@ Ssl::BumpMode step3; ///< The SSL bump mode at step3 } act; ///< bumping actions at various bumping steps Ssl::BumpStep step; ///< The SSL bumping step - SBuf clientSni; ///< the SSL client SNI name private: Security::SessionPointer serverSession; ///< The TLS session object on server side. diff -u -r -N squid-4.0.20/src/ssl/support.cc squid-4.0.21/src/ssl/support.cc --- squid-4.0.20/src/ssl/support.cc 2017-06-02 00:49:17.000000000 +1200 +++ squid-4.0.21/src/ssl/support.cc 2017-07-02 20:41:18.000000000 +1200 @@ -38,9 +38,6 @@ // TODO: Move ssl_ex_index_* global variables from global.cc here. int ssl_ex_index_ssl_untrusted_chain = -1; -Ipc::MemMap *Ssl::SessionCache = NULL; -const char *Ssl::SessionCacheName = "ssl_session_cache"; - static Ssl::CertsIndexedList SquidUntrustedCerts; const EVP_MD *Ssl::DefaultSignHash = NULL; @@ -332,7 +329,7 @@ assert(!filledCheck->sslErrors); filledCheck->sslErrors = new Security::CertErrors(Security::CertError(error_no, broken_cert)); filledCheck->serverCert = peer_cert; - if (check->fastCheck() == ACCESS_ALLOWED) { + if (check->fastCheck().allowed()) { debugs(83, 3, "bypassing SSL error " << error_no << " in " << buffer); ok = 1; } else { @@ -472,6 +469,7 @@ #if HAVE_OPENSSL_ENGINE_H if (::Config.SSL.ssl_engine) { + ENGINE_load_builtin_engines(); ENGINE *e; if (!(e = ENGINE_by_id(::Config.SSL.ssl_engine))) fatalf("Unable to find SSL engine '%s'\n", ::Config.SSL.ssl_engine); @@ -564,7 +562,7 @@ if (port.secure.parsedFlags & SSL_FLAG_DONT_VERIFY_DOMAIN) SSL_CTX_set_ex_data(ctx.get(), ssl_ctx_ex_index_dont_verify_domain, (void *) -1); - Ssl::SetSessionCallbacks(ctx); + Security::SetSessionCacheCallbacks(ctx); return true; } @@ -1381,113 +1379,5 @@ return Ssl::generateSslCertificate(untrustedCert, untrustedPkey, certProperties); } -static int -store_session_cb(SSL *ssl, SSL_SESSION *session) -{ - if (!Ssl::SessionCache) - return 0; - - debugs(83, 5, "Request to store SSL Session "); - - SSL_SESSION_set_timeout(session, Config.SSL.session_ttl); - -#if HAVE_LIBSSL_SSL_SESSION_GET_ID - unsigned int idlen; - const unsigned char *id = SSL_SESSION_get_id(session, &idlen); -#else - unsigned char *id = session->session_id; - unsigned int idlen = session->session_id_length; -#endif - unsigned char key[MEMMAP_SLOT_KEY_SIZE]; - // Session ids are of size 32bytes. They should always fit to a - // MemMap::Slot::key - assert(idlen <= MEMMAP_SLOT_KEY_SIZE); - memset(key, 0, sizeof(key)); - memcpy(key, id, idlen); - int pos; - Ipc::MemMap::Slot *slotW = Ssl::SessionCache->openForWriting((const cache_key*)key, pos); - if (slotW) { - int lenRequired = i2d_SSL_SESSION(session, NULL); - if (lenRequired < MEMMAP_SLOT_DATA_SIZE) { - unsigned char *p = (unsigned char *)slotW->p; - lenRequired = i2d_SSL_SESSION(session, &p); - slotW->set(key, NULL, lenRequired, squid_curtime + Config.SSL.session_ttl); - } - Ssl::SessionCache->closeForWriting(pos); - debugs(83, 5, "wrote an ssl session entry of size " << lenRequired << " at pos " << pos); - } - return 0; -} - -static void -remove_session_cb(SSL_CTX *, SSL_SESSION *sessionID) -{ - if (!Ssl::SessionCache) - return ; - - debugs(83, 5, "Request to remove corrupted or not valid SSL Session "); - int pos; - Ipc::MemMap::Slot const *slot = Ssl::SessionCache->openForReading((const cache_key*)sessionID, pos); - if (slot == NULL) - return; - Ssl::SessionCache->closeForReading(pos); - // TODO: - // What if we are not able to remove the session? - // Maybe schedule a job to remove it later? - // For now we just have an invalid entry in cache until will be expired - // The openSSL will reject it when we try to use it - Ssl::SessionCache->free(pos); -} - -static SSL_SESSION * -#if SQUID_USE_CONST_SSL_SESSION_CBID -get_session_cb(SSL *, const unsigned char *sessionID, int len, int *copy) -#else -get_session_cb(SSL *, unsigned char *sessionID, int len, int *copy) -#endif -{ - if (!Ssl::SessionCache) - return NULL; - - SSL_SESSION *session = NULL; - const unsigned int *p; - p = (unsigned int *)sessionID; - debugs(83, 5, "Request to search for SSL Session of len:" << - len << p[0] << ":" << p[1]); - - int pos; - Ipc::MemMap::Slot const *slot = Ssl::SessionCache->openForReading((const cache_key*)sessionID, pos); - if (slot != NULL) { - if (slot->expire > squid_curtime) { - const unsigned char *ptr = slot->p; - session = d2i_SSL_SESSION(NULL, &ptr, slot->pSize); - debugs(83, 5, "Session retrieved from cache at pos " << pos); - } else - debugs(83, 5, "Session in cache expired"); - Ssl::SessionCache->closeForReading(pos); - } - - if (!session) - debugs(83, 5, "Failed to retrieved from cache\n"); - - // With the parameter copy the callback can require the SSL engine - // to increment the reference count of the SSL_SESSION object, Normally - // the reference count is not incremented and therefore the session must - // not be explicitly freed with SSL_SESSION_free(3). - *copy = 0; - return session; -} - -void -Ssl::SetSessionCallbacks(Security::ContextPointer &ctx) -{ - if (Ssl::SessionCache) { - SSL_CTX_set_session_cache_mode(ctx.get(), SSL_SESS_CACHE_SERVER|SSL_SESS_CACHE_NO_INTERNAL); - SSL_CTX_sess_set_new_cb(ctx.get(), store_session_cb); - SSL_CTX_sess_set_remove_cb(ctx.get(), remove_session_cb); - SSL_CTX_sess_set_get_cb(ctx.get(), get_session_cb); - } -} - #endif /* USE_OPENSSL */ diff -u -r -N squid-4.0.20/src/ssl/support.h squid-4.0.21/src/ssl/support.h --- squid-4.0.20/src/ssl/support.h 2017-06-02 00:49:17.000000000 +1200 +++ squid-4.0.21/src/ssl/support.h 2017-07-02 20:41:18.000000000 +1200 @@ -73,10 +73,6 @@ class CertValidationResponse; typedef RefCount CertValidationResponsePointer; -void SetSessionCallbacks(Security::ContextPointer &); -extern Ipc::MemMap *SessionCache; -extern const char *SessionCacheName; - /// initialize a TLS server context with OpenSSL specific settings bool InitServerContext(Security::ContextPointer &, AnyP::PortCfg &); diff -u -r -N squid-4.0.20/src/store/id_rewriters/file/Makefile.in squid-4.0.21/src/store/id_rewriters/file/Makefile.in --- squid-4.0.20/src/store/id_rewriters/file/Makefile.in 2017-06-02 01:01:17.000000000 +1200 +++ squid-4.0.21/src/store/id_rewriters/file/Makefile.in 2017-07-02 20:41:28.000000000 +1200 @@ -1,7 +1,7 @@ -# Makefile.in generated by automake 1.15 from Makefile.am. +# Makefile.in generated by automake 1.15.1 from Makefile.am. # @configure_input@ -# Copyright (C) 1994-2014 Free Software Foundation, Inc. +# Copyright (C) 1994-2017 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, diff -u -r -N squid-4.0.20/src/store/id_rewriters/file/storeid_file_rewrite.8 squid-4.0.21/src/store/id_rewriters/file/storeid_file_rewrite.8 --- squid-4.0.20/src/store/id_rewriters/file/storeid_file_rewrite.8 2017-06-02 09:54:12.000000000 +1200 +++ squid-4.0.21/src/store/id_rewriters/file/storeid_file_rewrite.8 2017-07-02 20:57:34.000000000 +1200 @@ -1,4 +1,4 @@ -.\" Automatically generated by Pod::Man 4.08 (Pod::Simple 3.32) +.\" Automatically generated by Pod::Man 4.07 (Pod::Simple 3.32) .\" .\" Standard preamble: .\" ======================================================================== @@ -129,7 +129,7 @@ .\" ======================================================================== .\" .IX Title "STOREID_FILE_REWRITE 8" -.TH STOREID_FILE_REWRITE 8 "2017-06-01" "perl v5.24.1" "User Contributed Perl Documentation" +.TH STOREID_FILE_REWRITE 8 "2017-07-02" "perl v5.24.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 @@ -209,7 +209,7 @@ Report ideas for new improvements to the \fISquid Developers mailing list .SH "SEE ALSO" .IX Header "SEE ALSO" -squid (8), \s-1GPL\s0 (7), +squid (8), \s-1GPL \\fIs0\fR\|(7), .PP The Squid wiki http://wiki.squid\-cache.org/Features/StoreID .PP diff -u -r -N squid-4.0.20/src/store/id_rewriters/Makefile.in squid-4.0.21/src/store/id_rewriters/Makefile.in --- squid-4.0.20/src/store/id_rewriters/Makefile.in 2017-06-02 01:01:16.000000000 +1200 +++ squid-4.0.21/src/store/id_rewriters/Makefile.in 2017-07-02 20:41:28.000000000 +1200 @@ -1,7 +1,7 @@ -# Makefile.in generated by automake 1.15 from Makefile.am. +# Makefile.in generated by automake 1.15.1 from Makefile.am. # @configure_input@ -# Copyright (C) 1994-2014 Free Software Foundation, Inc. +# Copyright (C) 1994-2017 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, diff -u -r -N squid-4.0.20/src/store/Makefile.in squid-4.0.21/src/store/Makefile.in --- squid-4.0.20/src/store/Makefile.in 2017-06-02 01:01:15.000000000 +1200 +++ squid-4.0.21/src/store/Makefile.in 2017-07-02 20:41:28.000000000 +1200 @@ -1,7 +1,7 @@ -# Makefile.in generated by automake 1.15 from Makefile.am. +# Makefile.in generated by automake 1.15.1 from Makefile.am. # @configure_input@ -# Copyright (C) 1994-2014 Free Software Foundation, Inc. +# Copyright (C) 1994-2017 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, diff -u -r -N squid-4.0.20/src/store.cc squid-4.0.21/src/store.cc --- squid-4.0.20/src/store.cc 2017-06-02 00:49:17.000000000 +1200 +++ squid-4.0.21/src/store.cc 2017-07-02 20:41:18.000000000 +1200 @@ -147,11 +147,18 @@ } void -StoreEntry::makePrivate() +StoreEntry::makePrivate(const bool shareable) { /* This object should never be cached at all */ expireNow(); - releaseRequest(); /* delete object when not used */ + releaseRequest(shareable); /* delete object when not used */ +} + +void +StoreEntry::clearPrivate() +{ + EBIT_CLR(flags, KEY_PRIVATE); + shareableWhenPrivate = false; } void @@ -327,7 +334,8 @@ ping_status(PING_NONE), store_status(STORE_PENDING), swap_status(SWAPOUT_NONE), - lock_count(0) + lock_count(0), + shareableWhenPrivate(false) { debugs(20, 5, "StoreEntry constructed, this=" << this); } @@ -463,14 +471,14 @@ } void -StoreEntry::releaseRequest() +StoreEntry::releaseRequest(const bool shareable) { if (EBIT_TEST(flags, RELEASE_REQUEST)) return; setReleaseFlag(); // makes validToSend() false, preventing future hits - setPrivateKey(); + setPrivateKey(shareable); } int @@ -582,10 +590,14 @@ * concept'. */ void -StoreEntry::setPrivateKey() +StoreEntry::setPrivateKey(const bool shareable) { - if (key && EBIT_TEST(flags, KEY_PRIVATE)) - return; /* is already private */ + if (key && EBIT_TEST(flags, KEY_PRIVATE)) { + // The entry is already private, but it may be still shareable. + if (!shareable) + shareableWhenPrivate = false; + return; + } if (key) { setReleaseFlag(); // will markForUnlink(); all caches/workers will know @@ -603,6 +615,7 @@ assert(hash_lookup(store_table, newkey) == NULL); EBIT_SET(flags, KEY_PRIVATE); + shareableWhenPrivate = shareable; hashInsert(newkey); } @@ -659,14 +672,17 @@ if (StoreEntry *e2 = (StoreEntry *)hash_lookup(store_table, newkey)) { assert(e2 != this); debugs(20, 3, "Making old " << *e2 << " private."); - e2->setPrivateKey(); - e2->release(); + + // TODO: check whether there is any sense in keeping old entry + // shareable here. Leaving it non-shareable for now. + e2->setPrivateKey(false); + e2->release(false); } if (key) hashDelete(); - EBIT_CLR(flags, KEY_PRIVATE); + clearPrivate(); hashInsert(newkey); @@ -788,7 +804,7 @@ e->lock("storeCreateEntry"); if (neighbors_do_private_keys || !flags.hierarchical) - e->setPrivateKey(); + e->setPrivateKey(false); else e->setPublicKey(); @@ -1232,7 +1248,7 @@ /* release an object from a cache */ void -StoreEntry::release() +StoreEntry::release(const bool shareable) { PROF_start(storeRelease); debugs(20, 3, "releasing " << *this << ' ' << getMD5Text()); @@ -1242,7 +1258,7 @@ if (locked()) { expireNow(); debugs(20, 3, "storeRelease: Only setting RELEASE_REQUEST bit"); - releaseRequest(); + releaseRequest(shareable); PROF_stop(storeRelease); return; } @@ -1252,7 +1268,7 @@ Store::Root().memoryUnlink(*this); - setPrivateKey(); + setPrivateKey(shareable); // lock the entry until rebuilding is done lock("storeLateRelease"); @@ -2103,7 +2119,11 @@ if (EBIT_TEST(e.flags, RELEASE_REQUEST)) os << 'X'; if (EBIT_TEST(e.flags, REFRESH_REQUEST)) os << 'F'; if (EBIT_TEST(e.flags, ENTRY_REVALIDATE_STALE)) os << 'E'; - if (EBIT_TEST(e.flags, ENTRY_DISPATCHED)) os << 'D'; + if (EBIT_TEST(e.flags, KEY_PRIVATE)) { + os << 'I'; + if (e.shareableWhenPrivate) + os << 'H'; + } if (EBIT_TEST(e.flags, KEY_PRIVATE)) os << 'I'; if (EBIT_TEST(e.flags, ENTRY_FWD_HDR_WAIT)) os << 'W'; if (EBIT_TEST(e.flags, ENTRY_NEGCACHED)) os << 'N'; diff -u -r -N squid-4.0.20/src/store_digest.cc squid-4.0.21/src/store_digest.cc --- squid-4.0.20/src/store_digest.cc 2017-06-02 00:49:17.000000000 +1200 +++ squid-4.0.21/src/store_digest.cc 2017-07-02 20:41:18.000000000 +1200 @@ -421,7 +421,8 @@ assert(e); sd_state.rewrite_lock = e; debugs(71, 3, "storeDigestRewrite: url: " << url << " key: " << e->getMD5Text()); - HttpRequest *req = HttpRequest::CreateFromUrl(url); + const MasterXaction::Pointer mx = new MasterXaction(XactionInitiator::initCacheDigest); + HttpRequest *req = HttpRequest::FromUrl(url, mx); e->mem_obj->request = req; HTTPMSGLOCK(e->mem_obj->request); /* wait for rebuild (if any) to finish */ diff -u -r -N squid-4.0.20/src/Store.h squid-4.0.21/src/Store.h --- squid-4.0.20/src/Store.h 2017-06-02 00:49:17.000000000 +1200 +++ squid-4.0.21/src/Store.h 2017-07-02 20:41:18.000000000 +1200 @@ -83,15 +83,19 @@ void abort(); void makePublic(const KeyScope keyScope = ksDefault); - void makePrivate(); + void makePrivate(const bool shareable); + /// A low-level method just resetting "private key" flags. + /// To avoid key inconsistency please use forcePublicKey() + /// or similar instead. + void clearPrivate(); void setPublicKey(const KeyScope keyScope = ksDefault); /// Resets existing public key to a public key with default scope, /// releasing the old default-scope entry (if any). /// Does nothing if the existing public key already has default scope. void clearPublicKeyScope(); - void setPrivateKey(); + void setPrivateKey(const bool shareable); void expireNow(); - void releaseRequest(); + void releaseRequest(const bool shareable = false); void negativeCache(); void cacheNegatively(); /** \todo argh, why both? */ void invokeHandlers(); @@ -212,7 +216,13 @@ /// update last reference timestamp and related Store metadata void touch(); - virtual void release(); + virtual void release(const bool shareable = false); + + /// May the caller commit to treating this [previously locked] + /// entry as a cache hit? + bool mayStartHitting() const { + return !EBIT_TEST(flags, KEY_PRIVATE) || shareableWhenPrivate; + } #if USE_ADAPTATION /// call back producer when more buffer space is available @@ -240,6 +250,13 @@ unsigned short lock_count; /* Assume < 65536! */ + /// Nobody can find/lock KEY_PRIVATE entries, but some transactions + /// (e.g., collapsed requests) find/lock a public entry before it becomes + /// private. May such transactions start using the now-private entry + /// they previously locked? This member should not affect transactions + /// that already started reading from the entry. + bool shareableWhenPrivate; + #if USE_ADAPTATION /// producer callback registered with deferProducer AsyncCall::Pointer deferredProducer; @@ -247,6 +264,8 @@ bool validLength() const; bool hasOneOfEtags(const String &reqETags, const bool allowWeakMatch) const; + + friend std::ostream &operator <<(std::ostream &os, const StoreEntry &e); }; std::ostream &operator <<(std::ostream &os, const StoreEntry &e); diff -u -r -N squid-4.0.20/src/tests/stub_client_side.cc squid-4.0.21/src/tests/stub_client_side.cc --- squid-4.0.20/src/tests/stub_client_side.cc 2017-06-02 00:49:17.000000000 +1200 +++ squid-4.0.21/src/tests/stub_client_side.cc 2017-07-02 20:41:18.000000000 +1200 @@ -31,7 +31,8 @@ void ConnStateData::noteBodyConsumerAborted(BodyPipe::Pointer) STUB bool ConnStateData::handleReadData() STUB_RETVAL(false) bool ConnStateData::handleRequestBodyData() STUB_RETVAL(false) -void ConnStateData::pinConnection(const Comm::ConnectionPointer &, HttpRequest *, CachePeer *, bool, bool) STUB +void ConnStateData::pinBusyConnection(const Comm::ConnectionPointer &, const HttpRequest::Pointer &) STUB +void ConnStateData::notePinnedConnectionBecameIdle(PinnedIdleContext) STUB void ConnStateData::unpinConnection(const bool) STUB const Comm::ConnectionPointer ConnStateData::validatePinnedConnection(HttpRequest *, const CachePeer *) STUB_RETVAL(NULL) void ConnStateData::clientPinnedConnectionClosed(const CommCloseCbParams &) STUB @@ -40,7 +41,7 @@ void ConnStateData::swanSong() STUB void ConnStateData::quitAfterError(HttpRequest *) STUB #if USE_OPENSSL -void ConnStateData::httpsPeeked(Comm::ConnectionPointer) STUB +void ConnStateData::httpsPeeked(PinnedIdleContext) STUB void ConnStateData::getSslContextStart() STUB void ConnStateData::getSslContextDone(Security::ContextPointer &, bool) STUB void ConnStateData::sslCrtdHandleReplyWrapper(void *, const Helper::Reply &) STUB diff -u -r -N squid-4.0.20/src/tests/stub_HttpRequest.cc squid-4.0.21/src/tests/stub_HttpRequest.cc --- squid-4.0.20/src/tests/stub_HttpRequest.cc 2017-06-02 00:49:17.000000000 +1200 +++ squid-4.0.21/src/tests/stub_HttpRequest.cc 2017-07-02 20:41:18.000000000 +1200 @@ -15,8 +15,8 @@ // void httpRequestPack(void *obj, Packable *p); -HttpRequest::HttpRequest() : HttpMsg(hoRequest) {STUB} -HttpRequest::HttpRequest(const HttpRequestMethod &, AnyP::ProtocolType, const char *, const char *) : HttpMsg(hoRequest) {STUB} +HttpRequest::HttpRequest(const MasterXaction::Pointer&) : HttpMsg(hoRequest) {STUB} +HttpRequest::HttpRequest(const HttpRequestMethod &, AnyP::ProtocolType, const char *, const char *, const MasterXaction::Pointer &) : HttpMsg(hoRequest) {STUB} HttpRequest::~HttpRequest() STUB void HttpRequest::reset() STUB void HttpRequest::initHTTP(const HttpRequestMethod &, AnyP::ProtocolType, const char *, const char *) STUB @@ -47,7 +47,7 @@ void HttpRequest::swapOut(StoreEntry *) STUB void HttpRequest::pack(Packable *) const STUB void HttpRequest::httpRequestPack(void *, Packable *) STUB -HttpRequest * HttpRequest::CreateFromUrl(char *, const HttpRequestMethod &) STUB_RETVAL(NULL) +HttpRequest * HttpRequest::FromUrl(char *, const MasterXaction::Pointer &, const HttpRequestMethod &) STUB_RETVAL(NULL) ConnStateData *HttpRequest::pinnedConnection() STUB_RETVAL(NULL) const SBuf HttpRequest::storeId() STUB_RETVAL(SBuf(".")) void HttpRequest::ignoreRange(const char *) STUB diff -u -r -N squid-4.0.20/src/tests/stub_libauth_acls.cc squid-4.0.21/src/tests/stub_libauth_acls.cc --- squid-4.0.20/src/tests/stub_libauth_acls.cc 2017-06-02 00:49:17.000000000 +1200 +++ squid-4.0.21/src/tests/stub_libauth_acls.cc 2017-07-02 20:41:18.000000000 +1200 @@ -20,8 +20,6 @@ #include "auth/AclMaxUserIp.h" ACL * ACLMaxUserIP::clone() const STUB_RETVAL(NULL) ACLMaxUserIP::ACLMaxUserIP (char const *) STUB -ACLMaxUserIP::ACLMaxUserIP (ACLMaxUserIP const &) STUB -ACLMaxUserIP::~ACLMaxUserIP() STUB char const * ACLMaxUserIP::typeString() const STUB_RETVAL(NULL) bool ACLMaxUserIP::empty () const STUB_RETVAL(false) bool ACLMaxUserIP::valid () const STUB_RETVAL(false) @@ -29,6 +27,7 @@ int ACLMaxUserIP::match(Auth::UserRequest::Pointer, Ip::Address const &) STUB_RETVAL(0) int ACLMaxUserIP::match(ACLChecklist *) STUB_RETVAL(0) SBufList ACLMaxUserIP::dump() const STUB_RETVAL(SBufList()) +const Acl::Options &ACLMaxUserIP::options() STUB_RETVAL(Acl::NoOptions()) #include "auth/AclProxyAuth.h" ACLProxyAuth::~ACLProxyAuth() STUB @@ -47,6 +46,7 @@ ACL * ACLProxyAuth::clone() const STUB_RETVAL(NULL) int ACLProxyAuth::matchForCache(ACLChecklist *) STUB_RETVAL(0) int ACLProxyAuth::matchProxyAuth(ACLChecklist *) STUB_RETVAL(0) +void ACLProxyAuth::parseFlags() STUB #endif /* USE_AUTH */ diff -u -r -N squid-4.0.20/src/tests/stub_libmgr.cc squid-4.0.21/src/tests/stub_libmgr.cc --- squid-4.0.20/src/tests/stub_libmgr.cc 2017-06-02 00:49:17.000000000 +1200 +++ squid-4.0.21/src/tests/stub_libmgr.cc 2017-07-02 20:41:18.000000000 +1200 @@ -100,7 +100,6 @@ void Mgr::Forwarder::handleError() STUB void Mgr::Forwarder::handleTimeout() STUB void Mgr::Forwarder::handleException(const std::exception& e) STUB -void Mgr::Forwarder::handleRemoteAck() STUB #include "mgr/FunAction.h" Mgr::Action::Pointer Mgr::FunAction::Create(const CommandPointer &cmd, OBJH *aHandler) STUB_RETVAL(dummyAction) diff -u -r -N squid-4.0.20/src/tests/stub_libsecurity.cc squid-4.0.21/src/tests/stub_libsecurity.cc --- squid-4.0.20/src/tests/stub_libsecurity.cc 2017-06-02 00:49:17.000000000 +1200 +++ squid-4.0.21/src/tests/stub_libsecurity.cc 2017-07-02 20:41:18.000000000 +1200 @@ -102,6 +102,7 @@ void MaybeGetSessionResumeData(const Security::SessionPointer &, Security::SessionStatePointer &) STUB void SetSessionResumeData(const Security::SessionPointer &, const Security::SessionStatePointer &) STUB #if USE_OPENSSL +void SetSessionCacheCallbacks(Security::ContextPointer &) STUB Security::SessionPointer NewSessionObject(const Security::ContextPointer &) STUB_RETVAL(nullptr) #endif } // namespace Security diff -u -r -N squid-4.0.20/src/tests/stub_SBuf.cc squid-4.0.21/src/tests/stub_SBuf.cc --- squid-4.0.20/src/tests/stub_SBuf.cc 2017-06-02 00:49:17.000000000 +1200 +++ squid-4.0.21/src/tests/stub_SBuf.cc 2017-07-02 20:41:18.000000000 +1200 @@ -7,6 +7,7 @@ */ #include "squid.h" +#include "sbuf/DetailedStats.h" #define STUB_API "SBuf.cc" #include "tests/STUB.h" diff -u -r -N squid-4.0.20/src/tests/stub_store.cc squid-4.0.21/src/tests/stub_store.cc --- squid-4.0.20/src/tests/stub_store.cc 2017-06-02 00:49:17.000000000 +1200 +++ squid-4.0.21/src/tests/stub_store.cc 2017-07-02 20:41:18.000000000 +1200 @@ -38,11 +38,11 @@ void StoreEntry::trimMemory(const bool preserveSwappable) STUB void StoreEntry::abort() STUB void StoreEntry::makePublic(const KeyScope scope) STUB -void StoreEntry::makePrivate() STUB +void StoreEntry::makePrivate(const bool shareable) STUB void StoreEntry::setPublicKey(const KeyScope scope) STUB -void StoreEntry::setPrivateKey() STUB +void StoreEntry::setPrivateKey(const bool shareable) STUB void StoreEntry::expireNow() STUB -void StoreEntry::releaseRequest() STUB +void StoreEntry::releaseRequest(const bool shareable) STUB void StoreEntry::negativeCache() STUB void StoreEntry::cacheNegatively() STUB void StoreEntry::purgeMem() STUB @@ -93,7 +93,7 @@ int64_t StoreEntry::contentLen() const STUB_RETVAL(0) void StoreEntry::lock(const char *) STUB void StoreEntry::touch() STUB -void StoreEntry::release() STUB +void StoreEntry::release(const bool shareable) STUB void StoreEntry::append(char const *, int) STUB void StoreEntry::vappendf(const char *, va_list) STUB diff -u -r -N squid-4.0.20/src/tests/testACLMaxUserIP.cc squid-4.0.21/src/tests/testACLMaxUserIP.cc --- squid-4.0.20/src/tests/testACLMaxUserIP.cc 2017-06-02 00:49:17.000000000 +1200 +++ squid-4.0.21/src/tests/testACLMaxUserIP.cc 2017-07-02 20:41:18.000000000 +1200 @@ -10,7 +10,9 @@ #if USE_AUTH +#include "acl/Acl.h" #include "auth/AclMaxUserIp.h" +#include "auth/UserRequest.h" #include "ConfigParser.h" #include "testACLMaxUserIP.h" #include "unitTestMain.h" @@ -26,13 +28,17 @@ /* 0 is not a valid maximum, so we start at 0 */ CPPUNIT_ASSERT_EQUAL(0,anACL.getMaximum()); /* and we have no option to turn strict OFF, so start ON. */ - CPPUNIT_ASSERT_EQUAL(false,anACL.getStrict()); + CPPUNIT_ASSERT_EQUAL(false, static_cast(anACL.beStrict)); /* an unparsed acl must not be valid - there is no sane default */ CPPUNIT_ASSERT_EQUAL(false,anACL.valid()); } -ACL::Prototype ACLMaxUserIP::RegistryProtoype(&ACLMaxUserIP::RegistryEntry_, "max_user_ip"); -ACLMaxUserIP ACLMaxUserIP::RegistryEntry_("max_user_ip"); +void +testACLMaxUserIP::setUp() +{ + CPPUNIT_NS::TestFixture::setUp(); + Acl::RegisterMaker("max_user_ip", [](Acl::TypeName name)->ACL* { return new ACLMaxUserIP(name); }); +} void testACLMaxUserIP::testParseLine() @@ -49,7 +55,7 @@ if (maxUserIpACL) { /* we want a maximum of one, and strict to be true */ CPPUNIT_ASSERT_EQUAL(1, maxUserIpACL->getMaximum()); - CPPUNIT_ASSERT_EQUAL(true, maxUserIpACL->getStrict()); + CPPUNIT_ASSERT_EQUAL(true, static_cast(maxUserIpACL->beStrict)); /* the acl must be vaid */ CPPUNIT_ASSERT_EQUAL(true, maxUserIpACL->valid()); } diff -u -r -N squid-4.0.20/src/tests/testACLMaxUserIP.h squid-4.0.21/src/tests/testACLMaxUserIP.h --- squid-4.0.20/src/tests/testACLMaxUserIP.h 2017-06-02 00:49:17.000000000 +1200 +++ squid-4.0.21/src/tests/testACLMaxUserIP.h 2017-07-02 20:41:18.000000000 +1200 @@ -27,6 +27,7 @@ CPPUNIT_TEST_SUITE_END(); public: + virtual void setUp() override; protected: void testDefaults(); diff -u -r -N squid-4.0.20/src/tests/testHttpRequest.cc squid-4.0.21/src/tests/testHttpRequest.cc --- squid-4.0.20/src/tests/testHttpRequest.cc 2017-06-02 00:49:17.000000000 +1200 +++ squid-4.0.21/src/tests/testHttpRequest.cc 2017-07-02 20:41:18.000000000 +1200 @@ -12,6 +12,7 @@ #include "HttpHeader.h" #include "HttpRequest.h" +#include "MasterXaction.h" #include "mime_header.h" #include "testHttpRequest.h" #include "unitTestMain.h" @@ -22,6 +23,7 @@ class PrivateHttpRequest : public HttpRequest { public: + PrivateHttpRequest(const MasterXaction::Pointer &mx) : HttpRequest(mx) {} bool doSanityCheckStartLine(const char *b, const size_t h, Http::StatusCode *e) { return sanityCheckStartLine(b,h,e); }; }; @@ -44,7 +46,8 @@ /* vanilla url, implict method */ unsigned short expected_port; char * url = xstrdup("http://foo:90/bar"); - HttpRequest *aRequest = HttpRequest::CreateFromUrl(url); + const MasterXaction::Pointer mx = new MasterXaction(XactionInitiator::initClient); + HttpRequest *aRequest = HttpRequest::FromUrl(url, mx); expected_port = 90; CPPUNIT_ASSERT_EQUAL(expected_port, aRequest->url.port()); CPPUNIT_ASSERT(aRequest->method == Http::METHOD_GET); @@ -56,7 +59,7 @@ /* vanilla url */ url = xstrdup("http://foo:90/bar"); - aRequest = HttpRequest::CreateFromUrl(url, Http::METHOD_GET); + aRequest = HttpRequest::FromUrl(url, mx, Http::METHOD_GET); expected_port = 90; CPPUNIT_ASSERT_EQUAL(expected_port, aRequest->url.port()); CPPUNIT_ASSERT(aRequest->method == Http::METHOD_GET); @@ -68,7 +71,7 @@ /* vanilla url, different method */ url = xstrdup("http://foo/bar"); - aRequest = HttpRequest::CreateFromUrl(url, Http::METHOD_PUT); + aRequest = HttpRequest::FromUrl(url, mx, Http::METHOD_PUT); expected_port = 80; CPPUNIT_ASSERT_EQUAL(expected_port, aRequest->url.port()); CPPUNIT_ASSERT(aRequest->method == Http::METHOD_PUT); @@ -81,13 +84,13 @@ /* a connect url with non-CONNECT data */ HttpRequest *nullRequest = nullptr; url = xstrdup(":foo/bar"); - aRequest = HttpRequest::CreateFromUrl(url, Http::METHOD_CONNECT); + aRequest = HttpRequest::FromUrl(url, mx, Http::METHOD_CONNECT); xfree(url); CPPUNIT_ASSERT_EQUAL(nullRequest, aRequest); /* a CONNECT url with CONNECT data */ url = xstrdup("foo:45"); - aRequest = HttpRequest::CreateFromUrl(url, Http::METHOD_CONNECT); + aRequest = HttpRequest::FromUrl(url, mx, Http::METHOD_CONNECT); expected_port = 45; CPPUNIT_ASSERT_EQUAL(expected_port, aRequest->url.port()); CPPUNIT_ASSERT(aRequest->method == Http::METHOD_CONNECT); @@ -112,7 +115,8 @@ /* valid IPv6 address without port */ url = xstrdup("http://[2000:800::45]/foo"); - aRequest = HttpRequest::CreateFromUrl(url, Http::METHOD_GET); + const MasterXaction::Pointer mx = new MasterXaction(XactionInitiator::initClient); + aRequest = HttpRequest::FromUrl(url, mx, Http::METHOD_GET); expected_port = 80; CPPUNIT_ASSERT_EQUAL(expected_port, aRequest->url.port()); CPPUNIT_ASSERT(aRequest->method == Http::METHOD_GET); @@ -124,7 +128,7 @@ /* valid IPv6 address with port */ url = xstrdup("http://[2000:800::45]:90/foo"); - aRequest = HttpRequest::CreateFromUrl(url, Http::METHOD_GET); + aRequest = HttpRequest::FromUrl(url, mx, Http::METHOD_GET); expected_port = 90; CPPUNIT_ASSERT_EQUAL(expected_port, aRequest->url.port()); CPPUNIT_ASSERT(aRequest->method == Http::METHOD_GET); @@ -136,7 +140,7 @@ /* IPv6 address as invalid (bug trigger) */ url = xstrdup("http://2000:800::45/foo"); - aRequest = HttpRequest::CreateFromUrl(url, Http::METHOD_GET); + aRequest = HttpRequest::FromUrl(url, mx, Http::METHOD_GET); expected_port = 80; CPPUNIT_ASSERT_EQUAL(expected_port, aRequest->url.port()); CPPUNIT_ASSERT(aRequest->method == Http::METHOD_GET); @@ -151,7 +155,8 @@ testHttpRequest::testSanityCheckStartLine() { MemBuf input; - PrivateHttpRequest engine; + const MasterXaction::Pointer mx = new MasterXaction(XactionInitiator::initClient); + PrivateHttpRequest engine(mx); Http::StatusCode error = Http::scNone; size_t hdr_len; input.init(); diff -u -r -N squid-4.0.20/src/tests/testStoreController.cc squid-4.0.21/src/tests/testStoreController.cc --- squid-4.0.20/src/tests/testStoreController.cc 2017-06-02 00:49:17.000000000 +1200 +++ squid-4.0.21/src/tests/testStoreController.cc 2017-07-02 20:41:18.000000000 +1200 @@ -114,7 +114,7 @@ e->lastModified(squid_curtime); e->refcount = 1; EBIT_CLR(e->flags, RELEASE_REQUEST); - EBIT_CLR(e->flags, KEY_PRIVATE); + e->clearPrivate(); e->ping_status = PING_NONE; EBIT_CLR(e->flags, ENTRY_VALIDATED); e->hashInsert((const cache_key *)name.termedBuf()); /* do it after we clear KEY_PRIVATE */ diff -u -r -N squid-4.0.20/src/tests/testStoreHashIndex.cc squid-4.0.21/src/tests/testStoreHashIndex.cc --- squid-4.0.20/src/tests/testStoreHashIndex.cc 2017-06-02 00:49:17.000000000 +1200 +++ squid-4.0.21/src/tests/testStoreHashIndex.cc 2017-07-02 20:41:18.000000000 +1200 @@ -92,7 +92,7 @@ e->lastModified(squid_curtime); e->refcount = 1; EBIT_CLR(e->flags, RELEASE_REQUEST); - EBIT_CLR(e->flags, KEY_PRIVATE); + e->clearPrivate(); e->ping_status = PING_NONE; EBIT_CLR(e->flags, ENTRY_VALIDATED); e->hashInsert((const cache_key *)name.termedBuf()); /* do it after we clear KEY_PRIVATE */ diff -u -r -N squid-4.0.20/src/tunnel.cc squid-4.0.21/src/tunnel.cc --- squid-4.0.20/src/tunnel.cc 2017-06-02 00:49:17.000000000 +1200 +++ squid-4.0.21/src/tunnel.cc 2017-07-02 20:41:18.000000000 +1200 @@ -1084,7 +1084,7 @@ ACLFilledChecklist ch(Config.accessList.miss, request, NULL); ch.src_addr = request->client_addr; ch.my_addr = request->my_addr; - if (ch.fastCheck() == ACCESS_DENIED) { + if (ch.fastCheck().denied()) { debugs(26, 4, HERE << "MISS access forbidden."); err = new ErrorState(ERR_FORWARDING_DENIED, Http::scForbidden, request); http->al->http.code = Http::scForbidden; diff -u -r -N squid-4.0.20/src/url.cc squid-4.0.21/src/url.cc --- squid-4.0.20/src/url.cc 2017-06-02 00:49:17.000000000 +1200 +++ squid-4.0.21/src/url.cc 2017-07-02 20:41:18.000000000 +1200 @@ -16,15 +16,6 @@ #include "SquidString.h" #include "URL.h" -static HttpRequest *urlParseFinish(const HttpRequestMethod& method, - const AnyP::ProtocolType protocol, - const char *const protoStr, - const char *const urlpath, - const char *const host, - const SBuf &login, - const int port, - HttpRequest *request); -static HttpRequest *urnParse(const HttpRequestMethod& method, char *urn, HttpRequest *request); static const char valid_hostname_chars_u[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ" "abcdefghijklmnopqrstuvwxyz" @@ -179,8 +170,7 @@ /* * Parse a URI/URL. * - * If the 'request' arg is non-NULL, put parsed values there instead - * of allocating a new HttpRequest. + * Stores parsed values in the `request` argument. * * This abuses HttpRequest as a way of representing the parsed url * and its components. @@ -197,43 +187,54 @@ * its partial or not (ie, it handles the case of no trailing slash as * being "end of host with implied path of /". */ -HttpRequest * -urlParse(const HttpRequestMethod& method, char *url, HttpRequest *request) +bool +URL::parse(const HttpRequestMethod& method, char *url) { LOCAL_ARRAY(char, proto, MAX_URL); LOCAL_ARRAY(char, login, MAX_URL); - LOCAL_ARRAY(char, host, MAX_URL); + LOCAL_ARRAY(char, foundHost, MAX_URL); LOCAL_ARRAY(char, urlpath, MAX_URL); char *t = NULL; char *q = NULL; - int port; + int foundPort; AnyP::ProtocolType protocol = AnyP::PROTO_NONE; int l; int i; const char *src; char *dst; - proto[0] = host[0] = urlpath[0] = login[0] = '\0'; + proto[0] = foundHost[0] = urlpath[0] = login[0] = '\0'; if ((l = strlen(url)) + Config.appendDomainLen > (MAX_URL - 1)) { /* terminate so it doesn't overflow other buffers */ *(url + (MAX_URL >> 1)) = '\0'; - debugs(23, DBG_IMPORTANT, "urlParse: URL too large (" << l << " bytes)"); - return NULL; + debugs(23, DBG_IMPORTANT, MYNAME << "URL too large (" << l << " bytes)"); + return false; } if (method == Http::METHOD_CONNECT) { - port = CONNECT_PORT; + /* + * RFC 7230 section 5.3.3: authority-form = authority + * "excluding any userinfo and its "@" delimiter" + * + * RFC 3986 section 3.2: authority = [ userinfo "@" ] host [ ":" port ] + * + * As an HTTP(S) proxy we assume HTTPS (443) if no port provided. + */ + foundPort = 443; - if (sscanf(url, "[%[^]]]:%d", host, &port) < 1) - if (sscanf(url, "%[^:]:%d", host, &port) < 1) - return NULL; + if (sscanf(url, "[%[^]]]:%d", foundHost, &foundPort) < 1) + if (sscanf(url, "%[^:]:%d", foundHost, &foundPort) < 1) + return false; } else if ((method == Http::METHOD_OPTIONS || method == Http::METHOD_TRACE) && URL::Asterisk().cmp(url) == 0) { - protocol = AnyP::PROTO_HTTP; - port = 80; // or the slow way ... AnyP::UriScheme(protocol,"http").defaultPort(); - return urlParseFinish(method, protocol, "http", url, host, SBuf(), port, request); - } else if (!strncmp(url, "urn:", 4)) { - return urnParse(method, url, request); + parseFinish(AnyP::PROTO_HTTP, nullptr, url, foundHost, SBuf(), 80 /* HTTP default port */); + return true; + } else if (strncmp(url, "urn:", 4) == 0) { + debugs(23, 3, "Split URI '" << url << "' into proto='urn', path='" << (url+4) << "'"); + debugs(50, 5, "urn=" << (url+4)); + setScheme(AnyP::PROTO_URN, nullptr); + path(url + 4); + return true; } else { /* Parse the URL: */ src = url; @@ -243,12 +244,12 @@ *dst = *src; } if (i >= l) - return NULL; + return false; *dst = '\0'; /* Then its :// */ if ((i+3) > l || *src != ':' || *(src + 1) != '/' || *(src + 2) != '/') - return NULL; + return false; i += 3; src += 3; @@ -256,7 +257,7 @@ // bug 1881: If we don't get a "/" then we imply it was there // bug 3074: We could just be given a "?" or "#". These also imply "/" // bug 3233: whitespace is also a hostname delimiter. - for (dst = host; i < l && *src != '/' && *src != '?' && *src != '#' && *src != '\0' && !xisspace(*src); ++i, ++src, ++dst) { + for (dst = foundHost; i < l && *src != '/' && *src != '?' && *src != '#' && *src != '\0' && !xisspace(*src); ++i, ++src, ++dst) { *dst = *src; } @@ -266,7 +267,7 @@ * been -given- a valid URL and the path is just '/'. */ if (i > l) - return NULL; + return false; *dst = '\0'; // bug 3074: received 'path' starting with '?', '#', or '\0' implies '/' @@ -283,7 +284,7 @@ /* We -could- be at the end of the buffer here */ if (i > l) - return NULL; + return false; /* If the URL path is empty we set it to be "/" */ if (dst == urlpath) { *dst = '/'; @@ -292,29 +293,29 @@ *dst = '\0'; protocol = urlParseProtocol(proto); - port = AnyP::UriScheme(protocol).defaultPort(); + foundPort = AnyP::UriScheme(protocol).defaultPort(); /* Is there any login information? (we should eventually parse it above) */ - t = strrchr(host, '@'); + t = strrchr(foundHost, '@'); if (t != NULL) { - strncpy((char *) login, (char *) host, sizeof(login)-1); + strncpy((char *) login, (char *) foundHost, sizeof(login)-1); login[sizeof(login)-1] = '\0'; t = strrchr(login, '@'); *t = 0; - strncpy((char *) host, t + 1, sizeof(host)-1); - host[sizeof(host)-1] = '\0'; + strncpy((char *) foundHost, t + 1, sizeof(foundHost)-1); + foundHost[sizeof(foundHost)-1] = '\0'; // Bug 4498: URL-unescape the login info after extraction rfc1738_unescape(login); } /* Is there any host information? (we should eventually parse it above) */ - if (*host == '[') { + if (*foundHost == '[') { /* strip any IPA brackets. valid under IPv6. */ - dst = host; + dst = foundHost; /* only for IPv6 sadly, pre-IPv6/URL code can't handle the clean result properly anyway. */ - src = host; + src = foundHost; ++src; - l = strlen(host); + l = strlen(foundHost); i = 1; for (; i < l && *src != ']' && *src != '\0'; ++i, ++src, ++dst) { *dst = *src; @@ -329,9 +330,9 @@ ++dst; t = dst; } else { - t = strrchr(host, ':'); + t = strrchr(foundHost, ':'); - if (t != strchr(host,':') ) { + if (t != strchr(foundHost,':') ) { /* RFC 2732 states IPv6 "SHOULD" be bracketed. allowing for times when its not. */ /* RFC 3986 'update' simply modifies this to an "is" with no emphasis at all! */ /* therefore we MUST accept the case where they are not bracketed at all. */ @@ -340,24 +341,24 @@ } // Bug 3183 sanity check: If scheme is present, host must be too. - if (protocol != AnyP::PROTO_NONE && host[0] == '\0') { + if (protocol != AnyP::PROTO_NONE && foundHost[0] == '\0') { debugs(23, DBG_IMPORTANT, "SECURITY ALERT: Missing hostname in URL '" << url << "'. see access.log for details."); - return NULL; + return false; } if (t && *t == ':') { *t = '\0'; ++t; - port = atoi(t); + foundPort = atoi(t); } } - for (t = host; *t; ++t) + for (t = foundHost; *t; ++t) *t = xtolower(*t); - if (stringHasWhitespace(host)) { + if (stringHasWhitespace(foundHost)) { if (URI_WHITESPACE_STRIP == Config.uri_whitespace) { - t = q = host; + t = q = foundHost; while (*t) { if (!xisspace(*t)) { *q = *t; @@ -369,48 +370,49 @@ } } - debugs(23, 3, "urlParse: Split URL '" << url << "' into proto='" << proto << "', host='" << host << "', port='" << port << "', path='" << urlpath << "'"); + debugs(23, 3, "Split URL '" << url << "' into proto='" << proto << "', host='" << foundHost << "', port='" << foundPort << "', path='" << urlpath << "'"); - if (Config.onoff.check_hostnames && strspn(host, Config.onoff.allow_underscore ? valid_hostname_chars_u : valid_hostname_chars) != strlen(host)) { - debugs(23, DBG_IMPORTANT, "urlParse: Illegal character in hostname '" << host << "'"); - return NULL; + if (Config.onoff.check_hostnames && + strspn(foundHost, Config.onoff.allow_underscore ? valid_hostname_chars_u : valid_hostname_chars) != strlen(foundHost)) { + debugs(23, DBG_IMPORTANT, MYNAME << "Illegal character in hostname '" << foundHost << "'"); + return false; } /* For IPV6 addresses also check for a colon */ - if (Config.appendDomain && !strchr(host, '.') && !strchr(host, ':')) - strncat(host, Config.appendDomain, SQUIDHOSTNAMELEN - strlen(host) - 1); + if (Config.appendDomain && !strchr(foundHost, '.') && !strchr(foundHost, ':')) + strncat(foundHost, Config.appendDomain, SQUIDHOSTNAMELEN - strlen(foundHost) - 1); /* remove trailing dots from hostnames */ - while ((l = strlen(host)) > 0 && host[--l] == '.') - host[l] = '\0'; + while ((l = strlen(foundHost)) > 0 && foundHost[--l] == '.') + foundHost[l] = '\0'; /* reject duplicate or leading dots */ - if (strstr(host, "..") || *host == '.') { - debugs(23, DBG_IMPORTANT, "urlParse: Illegal hostname '" << host << "'"); - return NULL; + if (strstr(foundHost, "..") || *foundHost == '.') { + debugs(23, DBG_IMPORTANT, MYNAME << "Illegal hostname '" << foundHost << "'"); + return false; } - if (port < 1 || port > 65535) { - debugs(23, 3, "urlParse: Invalid port '" << port << "'"); - return NULL; + if (foundPort < 1 || foundPort > 65535) { + debugs(23, 3, "Invalid port '" << foundPort << "'"); + return false; } #if HARDCODE_DENY_PORTS /* These ports are filtered in the default squid.conf, but * maybe someone wants them hardcoded... */ - if (port == 7 || port == 9 || port == 19) { - debugs(23, DBG_CRITICAL, "urlParse: Deny access to port " << port); - return NULL; + if (foundPort == 7 || foundPort == 9 || foundPort == 19) { + debugs(23, DBG_CRITICAL, MYNAME << "Deny access to port " << foundPort); + return false; } #endif if (stringHasWhitespace(urlpath)) { - debugs(23, 2, "urlParse: URI has whitespace: {" << url << "}"); + debugs(23, 2, "URI has whitespace: {" << url << "}"); switch (Config.uri_whitespace) { case URI_WHITESPACE_DENY: - return NULL; + return false; case URI_WHITESPACE_ALLOW: break; @@ -438,46 +440,24 @@ } } - return urlParseFinish(method, protocol, proto, urlpath, host, SBuf(login), port, request); -} - -/** - * Update request with parsed URI data. If the request arg is - * non-NULL, put parsed values there instead of allocating a new - * HttpRequest. - */ -static HttpRequest * -urlParseFinish(const HttpRequestMethod& method, - const AnyP::ProtocolType protocol, - const char *const protoStr, // for unknown protocols - const char *const urlpath, - const char *const host, - const SBuf &login, - const int port, - HttpRequest *request) -{ - if (NULL == request) - request = new HttpRequest(method, protocol, protoStr, urlpath); - else { - request->initHTTP(method, protocol, protoStr, urlpath); - } - - request->url.host(host); - request->url.userInfo(login); - request->url.port(port); - return request; + parseFinish(protocol, proto, urlpath, foundHost, SBuf(login), foundPort); + return true; } -static HttpRequest * -urnParse(const HttpRequestMethod& method, char *urn, HttpRequest *request) +/// Update the URL object with parsed URI data. +void +URL::parseFinish(const AnyP::ProtocolType protocol, + const char *const protoStr, // for unknown protocols + const char *const aUrlPath, + const char *const aHost, + const SBuf &aLogin, + const int aPort) { - debugs(50, 5, "urnParse: " << urn); - if (request) { - request->initHTTP(method, AnyP::PROTO_URN, "urn", urn + 4); - return request; - } - - return new HttpRequest(method, AnyP::PROTO_URN, "urn", urn + 4); + setScheme(protocol, protoStr); + path(aUrlPath); + host(aHost); + userInfo(aLogin); + port(aPort); } void diff -u -r -N squid-4.0.20/src/URL.h squid-4.0.21/src/URL.h --- squid-4.0.20/src/URL.h 2017-06-02 00:49:17.000000000 +1200 +++ squid-4.0.21/src/URL.h 2017-07-02 20:41:18.000000000 +1200 @@ -53,6 +53,8 @@ } void touch(); ///< clear the cached URI display forms + bool parse(const HttpRequestMethod &, char *url); + AnyP::UriScheme const & getScheme() const {return scheme_;} /// convert the URL scheme to that given @@ -104,6 +106,8 @@ SBuf &absolute() const; private: + void parseFinish(const AnyP::ProtocolType, const char *const, const char *const, const char *const, const SBuf &, const int); + /** \par * The scheme of this URL. This has the 'type code' smell about it. @@ -166,7 +170,7 @@ class HttpRequestMethod; void urlInitialize(void); -HttpRequest *urlParse(const HttpRequestMethod&, char *, HttpRequest *request = NULL); +bool urlParse(const HttpRequestMethod&, char *, HttpRequest &request); char *urlCanonicalClean(const HttpRequest *); const char *urlCanonicalFakeHttps(const HttpRequest * request); bool urlIsRelative(const char *); diff -u -r -N squid-4.0.20/src/urn.cc squid-4.0.21/src/urn.cc --- squid-4.0.20/src/urn.cc 2017-06-02 00:49:17.000000000 +1200 +++ squid-4.0.21/src/urn.cc 2017-07-02 20:41:18.000000000 +1200 @@ -151,7 +151,7 @@ safe_free(host); safe_free(urlres); urlres = xstrdup(local_urlres); - urlres_r = HttpRequest::CreateFromUrl(urlres); + urlres_r = HttpRequest::FromUrl(urlres, r->masterXaction); if (urlres_r == NULL) { debugs(52, 3, "urnStart: Bad uri-res URL " << urlres); diff -u -r -N squid-4.0.20/src/XactionInitiator.cc squid-4.0.21/src/XactionInitiator.cc --- squid-4.0.20/src/XactionInitiator.cc 1970-01-01 12:00:00.000000000 +1200 +++ squid-4.0.21/src/XactionInitiator.cc 2017-07-02 20:41:18.000000000 +1200 @@ -0,0 +1,47 @@ +/* + * Copyright (C) 1996-2017 The Squid Software Foundation and contributors + * + * Squid software is distributed under GPLv2+ license and includes + * contributions from numerous individuals and organizations. + * Please see the COPYING and CONTRIBUTORS files for details. + */ + +#include "squid.h" +#include "cache_cf.h" +#include "Debug.h" +#include "XactionInitiator.h" + +#include +#include + +XactionInitiator::Initiators +XactionInitiator::ParseInitiators(const char *name) +{ + typedef std::map InitiatorsMap; + static InitiatorsMap SupportedInitiators = { + {"client", initClient}, + {"peer-pool", initPeerPool}, + {"certificate-fetching", initCertFetcher}, + {"esi", initEsi}, + {"cache-digest", initCacheDigest}, + {"server", initServer}, + {"htcp", initHtcp}, + {"icp", initIcp}, + {"icmp", initIcmp}, + {"asn", initAsn}, + {"ipc", initIpc}, + {"adaptation", initAdaptation}, + {"icon", initIcon}, + {"peer-mcast", initPeerMcast}, + {"internal", InternalInitiators()}, + {"all", AllInitiators()} + }; + const auto it = SupportedInitiators.find(name); + if (it != SupportedInitiators.cend()) + return it->second; + + debugs(28, DBG_CRITICAL, "FATAL: Invalid transaction_initiator value near " << name); + self_destruct(); + return 0; +} + diff -u -r -N squid-4.0.20/src/XactionInitiator.h squid-4.0.21/src/XactionInitiator.h --- squid-4.0.20/src/XactionInitiator.h 1970-01-01 12:00:00.000000000 +1200 +++ squid-4.0.21/src/XactionInitiator.h 2017-07-02 20:41:18.000000000 +1200 @@ -0,0 +1,68 @@ +/* + * Copyright (C) 1996-2017 The Squid Software Foundation and contributors + * + * Squid software is distributed under GPLv2+ license and includes + * contributions from numerous individuals and organizations. + * Please see the COPYING and CONTRIBUTORS files for details. + */ + +#ifndef SQUID_SRC_XACTION_INITIATOR_H +#define SQUID_SRC_XACTION_INITIATOR_H + +/// identifies a protocol agent or Squid feature initiating transactions +class XactionInitiator { +public: + /// transaction triggers + enum Initiator { + initUnknown = 0, + initClient = 1 << 0, ///< HTTP or FTP client + initPeerPool = 1 << 1, ///< PeerPool manager + initCertFetcher = 1 << 2, ///< Missing intermediate certificates fetching code + initEsi = 1 << 3, ///< ESI processing code + initCacheDigest = 1 << 4, ///< Cache Digest fetching code + initHtcp = 1<< 5, ///< HTCP client + initIcp = 1 << 6, ///< the ICP/neighbors subsystem + initIcmp = 1 << 7, ///< the ICMP RTT database (NetDB) neighbors exchange subsystem + initAsn = 1 << 8, ///< the ASN db subsystem + initIpc = 1 << 9, ///< the IPC subsystem + initAdaptation = 1 << 10, ///< ICAP/ECAP requests generated by Squid + initIcon = 1 << 11, ///< internal icons + initPeerMcast = 1 << 12, ///< neighbor multicast + initServer = 1 << 13, ///< HTTP/2 push request (not yet supported by Squid) + + initAdaptationOrphan_ = 1 << 31 ///< eCAP-created HTTP message w/o an associated HTTP transaction (not ACL-detectable) + }; + + typedef uint32_t Initiators; ///< Initiator set + + // this class is a just a trivial wrapper so we allow explicit conversions + XactionInitiator(Initiator i) : initiator(i) {} + + /// whether this initiator belongs to the given set + bool in(Initiators setOfInitiators) const {return (initiator & setOfInitiators) != 0;} + + /// whether the transaction was initiated by an internal subsystem + bool internalClient() const { + return (initiator & InternalInitiators()) != 0; + } + + /// internally generated requests + static Initiators InternalInitiators() { + return initPeerPool | initCertFetcher | initEsi | initCacheDigest | initIcp | initIcmp | initIpc | initAdaptation | initIcon | initPeerMcast; + } + + /// all initiators + static Initiators AllInitiators() { + return 0xFFFFFFFF; + } + + static Initiators ParseInitiators(const char *name); + +private: + XactionInitiator() {} + + Initiator initiator; +}; + +#endif // SQUID_SRC_XACTION_INITIATOR_H + diff -u -r -N squid-4.0.20/test-suite/Makefile.in squid-4.0.21/test-suite/Makefile.in --- squid-4.0.20/test-suite/Makefile.in 2017-06-02 01:01:20.000000000 +1200 +++ squid-4.0.21/test-suite/Makefile.in 2017-07-02 20:41:28.000000000 +1200 @@ -1,7 +1,7 @@ -# Makefile.in generated by automake 1.15 from Makefile.am. +# Makefile.in generated by automake 1.15.1 from Makefile.am. # @configure_input@ -# Copyright (C) 1994-2014 Free Software Foundation, Inc. +# Copyright (C) 1994-2017 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, diff -u -r -N squid-4.0.20/test-suite/squidconf/regressions-4.0.18 squid-4.0.21/test-suite/squidconf/regressions-4.0.18 --- squid-4.0.20/test-suite/squidconf/regressions-4.0.18 2017-06-02 00:49:17.000000000 +1200 +++ squid-4.0.21/test-suite/squidconf/regressions-4.0.18 2017-07-02 20:41:18.000000000 +1200 @@ -1,4 +1,13 @@ +## Copyright (C) 1996-2017 The Squid Software Foundation and contributors +## +## Squid software is distributed under GPLv2+ license and includes +## contributions from numerous individuals and organizations. +## Please see the COPYING and CONTRIBUTORS files for details. +## + +# # see Bug 4674 +# delay_pools 5 delay_class 1 1 64000/64000 diff -u -r -N squid-4.0.20/test-suite/stub_SBuf.cc squid-4.0.21/test-suite/stub_SBuf.cc --- squid-4.0.20/test-suite/stub_SBuf.cc 2017-06-02 09:59:52.000000000 +1200 +++ squid-4.0.21/test-suite/stub_SBuf.cc 2017-07-02 20:57:36.000000000 +1200 @@ -7,6 +7,7 @@ */ #include "squid.h" +#include "sbuf/DetailedStats.h" #define STUB_API "SBuf.cc" #include "tests/STUB.h" diff -u -r -N squid-4.0.20/tools/apparmor/Makefile.am squid-4.0.21/tools/apparmor/Makefile.am --- squid-4.0.20/tools/apparmor/Makefile.am 1970-01-01 12:00:00.000000000 +1200 +++ squid-4.0.21/tools/apparmor/Makefile.am 2017-07-02 20:41:18.000000000 +1200 @@ -0,0 +1,8 @@ +## Copyright (C) 1996-2017 The Squid Software Foundation and contributors +## +## Squid software is distributed under GPLv2+ license and includes +## contributions from numerous individuals and organizations. +## Please see the COPYING and CONTRIBUTORS files for details. +## + +EXTRA_DIST = usr.sbin.squid diff -u -r -N squid-4.0.20/tools/apparmor/Makefile.in squid-4.0.21/tools/apparmor/Makefile.in --- squid-4.0.20/tools/apparmor/Makefile.in 1970-01-01 12:00:00.000000000 +1200 +++ squid-4.0.21/tools/apparmor/Makefile.in 2017-07-02 20:41:28.000000000 +1200 @@ -0,0 +1,603 @@ +# Makefile.in generated by automake 1.15.1 from Makefile.am. +# @configure_input@ + +# Copyright (C) 1994-2017 Free Software Foundation, Inc. + +# This Makefile.in is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + +@SET_MAKE@ +VPATH = @srcdir@ +am__is_gnu_make = { \ + if test -z '$(MAKELEVEL)'; then \ + false; \ + elif test -n '$(MAKE_HOST)'; then \ + true; \ + elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ + true; \ + else \ + false; \ + fi; \ +} +am__make_running_with_option = \ + case $${target_option-} in \ + ?) ;; \ + *) echo "am__make_running_with_option: internal error: invalid" \ + "target option '$${target_option-}' specified" >&2; \ + exit 1;; \ + esac; \ + has_opt=no; \ + sane_makeflags=$$MAKEFLAGS; \ + if $(am__is_gnu_make); then \ + sane_makeflags=$$MFLAGS; \ + else \ + case $$MAKEFLAGS in \ + *\\[\ \ ]*) \ + bs=\\; \ + sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ + | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ + esac; \ + fi; \ + skip_next=no; \ + strip_trailopt () \ + { \ + flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ + }; \ + for flg in $$sane_makeflags; do \ + test $$skip_next = yes && { skip_next=no; continue; }; \ + case $$flg in \ + *=*|--*) continue;; \ + -*I) strip_trailopt 'I'; skip_next=yes;; \ + -*I?*) strip_trailopt 'I';; \ + -*O) strip_trailopt 'O'; skip_next=yes;; \ + -*O?*) strip_trailopt 'O';; \ + -*l) strip_trailopt 'l'; skip_next=yes;; \ + -*l?*) strip_trailopt 'l';; \ + -[dEDm]) skip_next=yes;; \ + -[JT]) skip_next=yes;; \ + esac; \ + case $$flg in \ + *$$target_option*) has_opt=yes; break;; \ + esac; \ + done; \ + test $$has_opt = yes +am__make_dryrun = (target_option=n; $(am__make_running_with_option)) +am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) +pkgdatadir = $(datadir)/@PACKAGE@ +pkgincludedir = $(includedir)/@PACKAGE@ +pkglibdir = $(libdir)/@PACKAGE@ +pkglibexecdir = $(libexecdir)/@PACKAGE@ +am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd +install_sh_DATA = $(install_sh) -c -m 644 +install_sh_PROGRAM = $(install_sh) -c +install_sh_SCRIPT = $(install_sh) -c +INSTALL_HEADER = $(INSTALL_DATA) +transform = $(program_transform_name) +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +build_triplet = @build@ +host_triplet = @host@ +subdir = tools/apparmor +ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 +am__aclocal_m4_deps = $(top_srcdir)/acinclude/ax_with_prog.m4 \ + $(top_srcdir)/acinclude/init.m4 \ + $(top_srcdir)/acinclude/squid-util.m4 \ + $(top_srcdir)/acinclude/compiler-flags.m4 \ + $(top_srcdir)/acinclude/os-deps.m4 \ + $(top_srcdir)/acinclude/krb5.m4 $(top_srcdir)/acinclude/pam.m4 \ + $(top_srcdir)/acinclude/pkg.m4 \ + $(top_srcdir)/acinclude/lib-checks.m4 \ + $(top_srcdir)/acinclude/ax_cxx_compile_stdcxx_11.m4 \ + $(top_srcdir)/acinclude/ax_cxx_0x_types.m4 \ + $(top_srcdir)/src/auth/basic/helpers.m4 \ + $(top_srcdir)/src/auth/basic/DB/required.m4 \ + $(top_srcdir)/src/auth/basic/LDAP/required.m4 \ + $(top_srcdir)/src/auth/basic/NCSA/required.m4 \ + $(top_srcdir)/src/auth/basic/NIS/required.m4 \ + $(top_srcdir)/src/auth/basic/PAM/required.m4 \ + $(top_srcdir)/src/auth/basic/POP3/required.m4 \ + $(top_srcdir)/src/auth/basic/RADIUS/required.m4 \ + $(top_srcdir)/src/auth/basic/SASL/required.m4 \ + $(top_srcdir)/src/auth/basic/SMB/required.m4 \ + $(top_srcdir)/src/auth/basic/SMB_LM/required.m4 \ + $(top_srcdir)/src/auth/basic/SSPI/required.m4 \ + $(top_srcdir)/src/auth/basic/fake/required.m4 \ + $(top_srcdir)/src/auth/basic/getpwnam/required.m4 \ + $(top_srcdir)/src/auth/digest/helpers.m4 \ + $(top_srcdir)/src/auth/digest/eDirectory/required.m4 \ + $(top_srcdir)/src/auth/digest/file/required.m4 \ + $(top_srcdir)/src/auth/digest/LDAP/required.m4 \ + $(top_srcdir)/src/auth/negotiate/helpers.m4 \ + $(top_srcdir)/src/auth/negotiate/SSPI/required.m4 \ + $(top_srcdir)/src/auth/negotiate/kerberos/required.m4 \ + $(top_srcdir)/src/auth/negotiate/wrapper/required.m4 \ + $(top_srcdir)/src/auth/ntlm/helpers.m4 \ + $(top_srcdir)/src/auth/ntlm/fake/required.m4 \ + $(top_srcdir)/src/auth/ntlm/SMB_LM/required.m4 \ + $(top_srcdir)/src/auth/ntlm/SSPI/required.m4 \ + $(top_srcdir)/src/log/helpers.m4 \ + $(top_srcdir)/src/log/DB/required.m4 \ + $(top_srcdir)/src/log/file/required.m4 \ + $(top_srcdir)/src/acl/external/helpers.m4 \ + $(top_srcdir)/src/acl/external/AD_group/required.m4 \ + $(top_srcdir)/src/acl/external/LDAP_group/required.m4 \ + $(top_srcdir)/src/acl/external/LM_group/required.m4 \ + $(top_srcdir)/src/acl/external/delayer/required.m4 \ + $(top_srcdir)/src/acl/external/SQL_session/required.m4 \ + $(top_srcdir)/src/acl/external/eDirectory_userip/required.m4 \ + $(top_srcdir)/src/acl/external/file_userip/required.m4 \ + $(top_srcdir)/src/acl/external/kerberos_ldap_group/required.m4 \ + $(top_srcdir)/src/acl/external/session/required.m4 \ + $(top_srcdir)/src/acl/external/time_quota/required.m4 \ + $(top_srcdir)/src/acl/external/unix_group/required.m4 \ + $(top_srcdir)/src/acl/external/wbinfo_group/required.m4 \ + $(top_srcdir)/src/http/url_rewriters/helpers.m4 \ + $(top_srcdir)/src/http/url_rewriters/fake/required.m4 \ + $(top_srcdir)/src/http/url_rewriters/LFS/required.m4 \ + $(top_srcdir)/src/security/cert_validators/helpers.m4 \ + $(top_srcdir)/src/security/cert_validators/fake/required.m4 \ + $(top_srcdir)/src/security/cert_generators/helpers.m4 \ + $(top_srcdir)/src/security/cert_generators/file/required.m4 \ + $(top_srcdir)/src/store/id_rewriters/helpers.m4 \ + $(top_srcdir)/src/store/id_rewriters/file/required.m4 \ + $(top_srcdir)/configure.ac +am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ + $(ACLOCAL_M4) +DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON) +mkinstalldirs = $(install_sh) -d +CONFIG_HEADER = $(top_builddir)/include/autoconf.h +CONFIG_CLEAN_FILES = +CONFIG_CLEAN_VPATH_FILES = +AM_V_P = $(am__v_P_@AM_V@) +am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) +am__v_P_0 = false +am__v_P_1 = : +AM_V_GEN = $(am__v_GEN_@AM_V@) +am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) +am__v_GEN_0 = @echo " GEN " $@; +am__v_GEN_1 = +AM_V_at = $(am__v_at_@AM_V@) +am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) +am__v_at_0 = @ +am__v_at_1 = +SOURCES = +DIST_SOURCES = +am__can_run_installinfo = \ + case $$AM_UPDATE_INFO_DIR in \ + n|no|NO) false;; \ + *) (install-info --version) >/dev/null 2>&1;; \ + esac +am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) +am__DIST_COMMON = $(srcdir)/Makefile.in +DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) +ACLOCAL = @ACLOCAL@ +ADAPTATION_LIBS = @ADAPTATION_LIBS@ +AIOLIB = @AIOLIB@ +ALLOCA = @ALLOCA@ +AMTAR = @AMTAR@ +AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ +AR = @AR@ +AR_R = @AR_R@ +ATOMICLIB = @ATOMICLIB@ +AUTH_LIBS_TO_BUILD = @AUTH_LIBS_TO_BUILD@ +AUTH_MODULES = @AUTH_MODULES@ +AUTOCONF = @AUTOCONF@ +AUTOHEADER = @AUTOHEADER@ +AUTOMAKE = @AUTOMAKE@ +AWK = @AWK@ +BASIC_AUTH_HELPERS = @BASIC_AUTH_HELPERS@ +BUILDCXX = @BUILDCXX@ +BUILDCXXFLAGS = @BUILDCXXFLAGS@ +BZR = @BZR@ +CACHE_EFFECTIVE_USER = @CACHE_EFFECTIVE_USER@ +CC = @CC@ +CCDEPMODE = @CCDEPMODE@ +CFLAGS = @CFLAGS@ +CGIEXT = @CGIEXT@ +CHMOD = @CHMOD@ +CPP = @CPP@ +CPPFLAGS = @CPPFLAGS@ +CRYPTLIB = @CRYPTLIB@ +CXX = @CXX@ +CXXCPP = @CXXCPP@ +CXXDEPMODE = @CXXDEPMODE@ +CXXFLAGS = @CXXFLAGS@ +CYGPATH_W = @CYGPATH_W@ +DEFAULT_HOSTS = @DEFAULT_HOSTS@ +DEFAULT_LOG_DIR = @DEFAULT_LOG_DIR@ +DEFAULT_PID_FILE = @DEFAULT_PID_FILE@ +DEFAULT_SWAP_DIR = @DEFAULT_SWAP_DIR@ +DEFS = @DEFS@ +DEPDIR = @DEPDIR@ +DIGEST_AUTH_HELPERS = @DIGEST_AUTH_HELPERS@ +DISK_LIBS = @DISK_LIBS@ +DISK_MODULES = @DISK_MODULES@ +DLLTOOL = @DLLTOOL@ +DSYMUTIL = @DSYMUTIL@ +DUMPBIN = @DUMPBIN@ +ECHO_C = @ECHO_C@ +ECHO_N = @ECHO_N@ +ECHO_T = @ECHO_T@ +EGREP = @EGREP@ +EPOLL_LIBS = @EPOLL_LIBS@ +EUILIB = @EUILIB@ +EXEEXT = @EXEEXT@ +EXPATLIB = @EXPATLIB@ +EXTERNAL_ACL_HELPERS = @EXTERNAL_ACL_HELPERS@ +EXT_LIBECAP_CFLAGS = @EXT_LIBECAP_CFLAGS@ +EXT_LIBECAP_LIBS = @EXT_LIBECAP_LIBS@ +FALSE = @FALSE@ +FGREP = @FGREP@ +GREP = @GREP@ +HAVE_CXX11 = @HAVE_CXX11@ +INCLTDL = @INCLTDL@ +INSTALL = @INSTALL@ +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ +KRB5INCS = @KRB5INCS@ +KRB5LIBS = @KRB5LIBS@ +LBERLIB = @LBERLIB@ +LD = @LD@ +LDAPLIB = @LDAPLIB@ +LDFLAGS = @LDFLAGS@ +LIBADD_DL = @LIBADD_DL@ +LIBADD_DLD_LINK = @LIBADD_DLD_LINK@ +LIBADD_DLOPEN = @LIBADD_DLOPEN@ +LIBADD_SHL_LOAD = @LIBADD_SHL_LOAD@ +LIBCPPUNIT_CFLAGS = @LIBCPPUNIT_CFLAGS@ +LIBCPPUNIT_LIBS = @LIBCPPUNIT_LIBS@ +LIBGNUTLS_CFLAGS = @LIBGNUTLS_CFLAGS@ +LIBGNUTLS_LIBS = @LIBGNUTLS_LIBS@ +LIBLTDL = @LIBLTDL@ +LIBOBJS = @LIBOBJS@ +LIBOPENSSL_CFLAGS = @LIBOPENSSL_CFLAGS@ +LIBOPENSSL_LIBS = @LIBOPENSSL_LIBS@ +LIBPTHREADS = @LIBPTHREADS@ +LIBS = @LIBS@ +LIBSASL = @LIBSASL@ +LIBTOOL = @LIBTOOL@ +LIB_KRB5_CFLAGS = @LIB_KRB5_CFLAGS@ +LIB_KRB5_LIBS = @LIB_KRB5_LIBS@ +LINUXDOC = @LINUXDOC@ +LIPO = @LIPO@ +LN = @LN@ +LN_S = @LN_S@ +LOG_DAEMON_HELPERS = @LOG_DAEMON_HELPERS@ +LTDLDEPS = @LTDLDEPS@ +LTDLINCL = @LTDLINCL@ +LTDLOPEN = @LTDLOPEN@ +LTLIBOBJS = @LTLIBOBJS@ +LT_ARGZ_H = @LT_ARGZ_H@ +LT_CONFIG_H = @LT_CONFIG_H@ +LT_DLLOADERS = @LT_DLLOADERS@ +LT_DLPREOPEN = @LT_DLPREOPEN@ +LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ +MAINT = @MAINT@ +MAKEINFO = @MAKEINFO@ +MANIFEST_TOOL = @MANIFEST_TOOL@ +MINGW_LIBS = @MINGW_LIBS@ +MKDIR = @MKDIR@ +MKDIR_P = @MKDIR_P@ +MV = @MV@ +NEGOTIATE_AUTH_HELPERS = @NEGOTIATE_AUTH_HELPERS@ +NETTLELIB = @NETTLELIB@ +NM = @NM@ +NMEDIT = @NMEDIT@ +NTLM_AUTH_HELPERS = @NTLM_AUTH_HELPERS@ +OBJDUMP = @OBJDUMP@ +OBJEXT = @OBJEXT@ +OTOOL = @OTOOL@ +OTOOL64 = @OTOOL64@ +PACKAGE = @PACKAGE@ +PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ +PACKAGE_NAME = @PACKAGE_NAME@ +PACKAGE_STRING = @PACKAGE_STRING@ +PACKAGE_TARNAME = @PACKAGE_TARNAME@ +PACKAGE_URL = @PACKAGE_URL@ +PACKAGE_VERSION = @PACKAGE_VERSION@ +PATH_SEPARATOR = @PATH_SEPARATOR@ +PERL = @PERL@ +PKG_CONFIG = @PKG_CONFIG@ +PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ +PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ +PO2HTML = @PO2HTML@ +PO2TEXT = @PO2TEXT@ +POD2MAN = @POD2MAN@ +RANLIB = @RANLIB@ +REGEXLIB = @REGEXLIB@ +REPL_LIBS = @REPL_LIBS@ +REPL_OBJS = @REPL_OBJS@ +REPL_POLICIES = @REPL_POLICIES@ +RM = @RM@ +SECURITY_CERTGEN_HELPERS = @SECURITY_CERTGEN_HELPERS@ +SECURITY_CERTV_HELPERS = @SECURITY_CERTV_HELPERS@ +SED = @SED@ +SET_MAKE = @SET_MAKE@ +SH = @SH@ +SHELL = @SHELL@ +SMBCLIENT = @SMBCLIENT@ +SNMPLIB = @SNMPLIB@ +SQUID_CFLAGS = @SQUID_CFLAGS@ +SQUID_CXXFLAGS = @SQUID_CXXFLAGS@ +SSLLIB = @SSLLIB@ +STOREID_REWRITE_HELPERS = @STOREID_REWRITE_HELPERS@ +STORE_LIBS_TO_ADD = @STORE_LIBS_TO_ADD@ +STORE_LIBS_TO_BUILD = @STORE_LIBS_TO_BUILD@ +STORE_TESTS = @STORE_TESTS@ +STRIP = @STRIP@ +TR = @TR@ +TRUE = @TRUE@ +URL_REWRITE_HELPERS = @URL_REWRITE_HELPERS@ +VERSION = @VERSION@ +WBINFO = @WBINFO@ +WIN32_PSAPI = @WIN32_PSAPI@ +XMLLIB = @XMLLIB@ +XTRA_LIBS = @XTRA_LIBS@ +XTRA_OBJS = @XTRA_OBJS@ +abs_builddir = @abs_builddir@ +abs_srcdir = @abs_srcdir@ +abs_top_builddir = @abs_top_builddir@ +abs_top_srcdir = @abs_top_srcdir@ +ac_ct_AR = @ac_ct_AR@ +ac_ct_CC = @ac_ct_CC@ +ac_ct_CXX = @ac_ct_CXX@ +ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ +am__include = @am__include@ +am__leading_dot = @am__leading_dot@ +am__quote = @am__quote@ +am__tar = @am__tar@ +am__untar = @am__untar@ +bindir = @bindir@ +build = @build@ +build_alias = @build_alias@ +build_cpu = @build_cpu@ +build_os = @build_os@ +build_vendor = @build_vendor@ +builddir = @builddir@ +datadir = @datadir@ +datarootdir = @datarootdir@ +docdir = @docdir@ +dvidir = @dvidir@ +exec_prefix = @exec_prefix@ +host = @host@ +host_alias = @host_alias@ +host_cpu = @host_cpu@ +host_os = @host_os@ +host_vendor = @host_vendor@ +htmldir = @htmldir@ +includedir = @includedir@ +infodir = @infodir@ +install_sh = @install_sh@ +krb5_config = @krb5_config@ +libdir = @libdir@ +libexecdir = @libexecdir@ +localedir = @localedir@ +localstatedir = @localstatedir@ +ltdl_LIBOBJS = @ltdl_LIBOBJS@ +ltdl_LTLIBOBJS = @ltdl_LTLIBOBJS@ +mandir = @mandir@ +mkdir_p = @mkdir_p@ +oldincludedir = @oldincludedir@ +pdfdir = @pdfdir@ +prefix = @prefix@ +program_transform_name = @program_transform_name@ +psdir = @psdir@ +runstatedir = @runstatedir@ +sbindir = @sbindir@ +sharedstatedir = @sharedstatedir@ +srcdir = @srcdir@ +subdirs = @subdirs@ +sys_symbol_underscore = @sys_symbol_underscore@ +sysconfdir = @sysconfdir@ +target_alias = @target_alias@ +top_build_prefix = @top_build_prefix@ +top_builddir = @top_builddir@ +top_srcdir = @top_srcdir@ +EXTRA_DIST = usr.sbin.squid +all: all-am + +.SUFFIXES: +$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps) + @for dep in $?; do \ + case '$(am__configure_deps)' in \ + *$$dep*) \ + ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ + && { if test -f $@; then exit 0; else break; fi; }; \ + exit 1;; \ + esac; \ + done; \ + echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign tools/apparmor/Makefile'; \ + $(am__cd) $(top_srcdir) && \ + $(AUTOMAKE) --foreign tools/apparmor/Makefile +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status + @case '$?' in \ + *config.status*) \ + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ + *) \ + echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ + cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ + esac; + +$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh + +$(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(am__aclocal_m4_deps): + +mostlyclean-libtool: + -rm -f *.lo + +clean-libtool: + -rm -rf .libs _libs +tags TAGS: + +ctags CTAGS: + +cscope cscopelist: + + +distdir: $(DISTFILES) + @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + list='$(DISTFILES)'; \ + dist_files=`for file in $$list; do echo $$file; done | \ + sed -e "s|^$$srcdirstrip/||;t" \ + -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ + case $$dist_files in \ + */*) $(MKDIR_P) `echo "$$dist_files" | \ + sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ + sort -u` ;; \ + esac; \ + for file in $$dist_files; do \ + if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ + if test -d $$d/$$file; then \ + dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ + if test -d "$(distdir)/$$file"; then \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ + cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ + else \ + test -f "$(distdir)/$$file" \ + || cp -p $$d/$$file "$(distdir)/$$file" \ + || exit 1; \ + fi; \ + done +check-am: all-am +check: check-am +all-am: Makefile +installdirs: +install: install-am +install-exec: install-exec-am +install-data: install-data-am +uninstall: uninstall-am + +install-am: all-am + @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am + +installcheck: installcheck-am +install-strip: + if test -z '$(STRIP)'; then \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + install; \ + else \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ + fi +mostlyclean-generic: + +clean-generic: + +distclean-generic: + -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) + -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) + +maintainer-clean-generic: + @echo "This command is intended for maintainers to use" + @echo "it deletes files that may require special tools to rebuild." +clean: clean-am + +clean-am: clean-generic clean-libtool mostlyclean-am + +distclean: distclean-am + -rm -f Makefile +distclean-am: clean-am distclean-generic + +dvi: dvi-am + +dvi-am: + +html: html-am + +html-am: + +info: info-am + +info-am: + +install-data-am: + +install-dvi: install-dvi-am + +install-dvi-am: + +install-exec-am: + +install-html: install-html-am + +install-html-am: + +install-info: install-info-am + +install-info-am: + +install-man: + +install-pdf: install-pdf-am + +install-pdf-am: + +install-ps: install-ps-am + +install-ps-am: + +installcheck-am: + +maintainer-clean: maintainer-clean-am + -rm -f Makefile +maintainer-clean-am: distclean-am maintainer-clean-generic + +mostlyclean: mostlyclean-am + +mostlyclean-am: mostlyclean-generic mostlyclean-libtool + +pdf: pdf-am + +pdf-am: + +ps: ps-am + +ps-am: + +uninstall-am: + +.MAKE: install-am install-strip + +.PHONY: all all-am check check-am clean clean-generic clean-libtool \ + cscopelist-am ctags-am distclean distclean-generic \ + distclean-libtool distdir dvi dvi-am html html-am info info-am \ + install install-am install-data install-data-am install-dvi \ + install-dvi-am install-exec install-exec-am install-html \ + install-html-am install-info install-info-am install-man \ + install-pdf install-pdf-am install-ps install-ps-am \ + install-strip installcheck installcheck-am installdirs \ + maintainer-clean maintainer-clean-generic mostlyclean \ + mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ + tags-am uninstall uninstall-am + +.PRECIOUS: Makefile + + +# Tell versions [3.59,3.63) of GNU make to not export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: diff -u -r -N squid-4.0.20/tools/apparmor/usr.sbin.squid squid-4.0.21/tools/apparmor/usr.sbin.squid --- squid-4.0.20/tools/apparmor/usr.sbin.squid 1970-01-01 12:00:00.000000000 +1200 +++ squid-4.0.21/tools/apparmor/usr.sbin.squid 2017-07-02 20:41:18.000000000 +1200 @@ -0,0 +1,47 @@ +## Copyright (C) 1996-2017 The Squid Software Foundation and contributors +## +## Squid software is distributed under GPLv2+ license and includes +## contributions from numerous individuals and organizations. +## Please see the COPYING and CONTRIBUTORS files for details. + +# Author: Simon Deziel +# Jamie Strandboge +# vim:syntax=apparmor +#include + +/usr/sbin/squid { + #include + #include + #include + + capability net_raw, + capability setuid, + capability setgid, + capability sys_chroot, + + # allow child processes to run execvp(argv[0], [kidname, ...]) + /usr/sbin/squid ix, + + # pinger + network inet raw, + network inet6 raw, + + /etc/mtab r, + @{PROC}/[0-9]*/mounts r, + @{PROC}/mounts r, + + # squid configuration + /etc/squid/** r, + /{,var/}run/squid.pid rwk, + /var/spool/squid/ r, + /var/spool/squid/** rwk, + /usr/lib/squid/* rmix, + /usr/share/squid/** r, + /var/log/squid/* rw, + + # allow SMP device access for kids + owner /dev/shm/** rmw, + + # Site-specific additions and overrides. See local/README for details. + #include +} diff -u -r -N squid-4.0.20/tools/helper-mux/helper-mux.8 squid-4.0.21/tools/helper-mux/helper-mux.8 --- squid-4.0.20/tools/helper-mux/helper-mux.8 2017-06-02 10:00:07.000000000 +1200 +++ squid-4.0.21/tools/helper-mux/helper-mux.8 2017-07-02 20:57:36.000000000 +1200 @@ -1,4 +1,4 @@ -.\" Automatically generated by Pod::Man 4.08 (Pod::Simple 3.32) +.\" Automatically generated by Pod::Man 4.07 (Pod::Simple 3.32) .\" .\" Standard preamble: .\" ======================================================================== @@ -129,7 +129,7 @@ .\" ======================================================================== .\" .IX Title "HELPER-MUX 8" -.TH HELPER-MUX 8 "2017-06-01" "perl v5.24.1" "User Contributed Perl Documentation" +.TH HELPER-MUX 8 "2017-07-02" "perl v5.24.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-4.0.20/tools/helper-mux/Makefile.in squid-4.0.21/tools/helper-mux/Makefile.in --- squid-4.0.20/tools/helper-mux/Makefile.in 2017-06-02 01:01:24.000000000 +1200 +++ squid-4.0.21/tools/helper-mux/Makefile.in 2017-07-02 20:41:28.000000000 +1200 @@ -1,7 +1,7 @@ -# Makefile.in generated by automake 1.15 from Makefile.am. +# Makefile.in generated by automake 1.15.1 from Makefile.am. # @configure_input@ -# Copyright (C) 1994-2014 Free Software Foundation, Inc. +# Copyright (C) 1994-2017 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, diff -u -r -N squid-4.0.20/tools/Makefile.am squid-4.0.21/tools/Makefile.am --- squid-4.0.20/tools/Makefile.am 2017-06-02 00:49:17.000000000 +1200 +++ squid-4.0.21/tools/Makefile.am 2017-07-02 20:41:18.000000000 +1200 @@ -10,7 +10,7 @@ ## we need our local files too (but avoid -I. at all costs) AM_CPPFLAGS += -I$(srcdir) -SUBDIRS= helper-mux purge squidclient systemd sysvinit +SUBDIRS= apparmor helper-mux purge squidclient systemd sysvinit EXTRA_DIST= man_MANS= DISTCLEANFILES= diff -u -r -N squid-4.0.20/tools/Makefile.in squid-4.0.21/tools/Makefile.in --- squid-4.0.20/tools/Makefile.in 2017-06-02 01:01:23.000000000 +1200 +++ squid-4.0.21/tools/Makefile.in 2017-07-02 20:41:28.000000000 +1200 @@ -1,7 +1,7 @@ -# Makefile.in generated by automake 1.15 from Makefile.am. +# Makefile.in generated by automake 1.15.1 from Makefile.am. # @configure_input@ -# Copyright (C) 1994-2014 Free Software Foundation, Inc. +# Copyright (C) 1994-2017 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -776,7 +776,7 @@ @ENABLE_XPROF_STATS_TRUE@LIBPROFILER = $(top_builddir)/lib/profiler/libprofiler.la COMPAT_LIB = $(top_builddir)/compat/libcompatsquid.la $(LIBPROFILER) subst_perlshell = sed -e 's,[@]PERL[@],$(PERL),g' <$(srcdir)/$@.pl.in >$@ || ($(RM) -f $@ ; exit 1) -SUBDIRS = helper-mux purge squidclient systemd sysvinit +SUBDIRS = apparmor helper-mux purge squidclient systemd sysvinit EXTRA_DIST = helper-ok-dying.pl helper-ok.pl cachemgr.conf \ cachemgr.cgi.8 cachemgr.cgi.8.in man_MANS = cachemgr.cgi.8 diff -u -r -N squid-4.0.20/tools/purge/Makefile.in squid-4.0.21/tools/purge/Makefile.in --- squid-4.0.20/tools/purge/Makefile.in 2017-06-02 01:01:26.000000000 +1200 +++ squid-4.0.21/tools/purge/Makefile.in 2017-07-02 20:41:28.000000000 +1200 @@ -1,7 +1,7 @@ -# Makefile.in generated by automake 1.15 from Makefile.am. +# Makefile.in generated by automake 1.15.1 from Makefile.am. # @configure_input@ -# Copyright (C) 1994-2014 Free Software Foundation, Inc. +# Copyright (C) 1994-2017 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, diff -u -r -N squid-4.0.20/tools/purge/purge.1 squid-4.0.21/tools/purge/purge.1 --- squid-4.0.20/tools/purge/purge.1 2017-06-02 00:49:17.000000000 +1200 +++ squid-4.0.21/tools/purge/purge.1 2017-07-02 20:41:18.000000000 +1200 @@ -258,7 +258,7 @@ .PP Based on original squidpurge README. . -..SH COPYRIGHT +.SH COPYRIGHT .PP * Copyright (C) 1996-2017 The Squid Software Foundation and contributors * diff -u -r -N squid-4.0.20/tools/squidclient/Makefile.in squid-4.0.21/tools/squidclient/Makefile.in --- squid-4.0.20/tools/squidclient/Makefile.in 2017-06-02 01:01:28.000000000 +1200 +++ squid-4.0.21/tools/squidclient/Makefile.in 2017-07-02 20:41:28.000000000 +1200 @@ -1,7 +1,7 @@ -# Makefile.in generated by automake 1.15 from Makefile.am. +# Makefile.in generated by automake 1.15.1 from Makefile.am. # @configure_input@ -# Copyright (C) 1994-2014 Free Software Foundation, Inc. +# Copyright (C) 1994-2017 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, diff -u -r -N squid-4.0.20/tools/systemd/Makefile.in squid-4.0.21/tools/systemd/Makefile.in --- squid-4.0.20/tools/systemd/Makefile.in 2017-06-02 01:01:29.000000000 +1200 +++ squid-4.0.21/tools/systemd/Makefile.in 2017-07-02 20:41:28.000000000 +1200 @@ -1,7 +1,7 @@ -# Makefile.in generated by automake 1.15 from Makefile.am. +# Makefile.in generated by automake 1.15.1 from Makefile.am. # @configure_input@ -# Copyright (C) 1994-2014 Free Software Foundation, Inc. +# Copyright (C) 1994-2017 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, diff -u -r -N squid-4.0.20/tools/sysvinit/Makefile.in squid-4.0.21/tools/sysvinit/Makefile.in --- squid-4.0.20/tools/sysvinit/Makefile.in 2017-06-02 01:01:30.000000000 +1200 +++ squid-4.0.21/tools/sysvinit/Makefile.in 2017-07-02 20:41:28.000000000 +1200 @@ -1,7 +1,7 @@ -# Makefile.in generated by automake 1.15 from Makefile.am. +# Makefile.in generated by automake 1.15.1 from Makefile.am. # @configure_input@ -# Copyright (C) 1994-2014 Free Software Foundation, Inc. +# Copyright (C) 1994-2017 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it,