diff -u -r -N squid-3.5.1/ChangeLog squid-3.5.2/ChangeLog --- squid-3.5.1/ChangeLog 2015-01-13 04:52:01.000000000 -0800 +++ squid-3.5.2/ChangeLog 2015-02-18 04:17:02.000000000 -0800 @@ -1,3 +1,21 @@ +Changes to squid-3.5.2 (18 Feb 2015): + + - Regression Bug 4176: Digest auth too many helper lookups + - Regression Bug 4180: not-fully-initialized data member in ACLUserData + - Bug 4172: Solaris broken krb5-config + - Bug 4073: Cygwin compile errors + - Bug 3919: remove several never-true / never-false comparisons + - HTTPS: Add missing root CAs when validating chains that passed internal checks + - Fix some cbdataFree related memory leaks + - Quieten CBDATA 'leak' messages + - Set SNI information in transparent bumping mode + - negotiate_kerberos_auth: fix krb5.conf backward compatibility + - Fix memory leaks in cachemgr.cgi URL parser + - Fix sslproxy_options in peek-and-splice mode + - ... and fix several portability and build issues + - ... and some documentation updates + - ... and all fixes from squid 3.4.11 + Changes to squid-3.5.1 (13 Jan 2015): - Fix handling of invalid SSL server certificates when splicing connections @@ -100,6 +118,18 @@ - ... and many error page translation updates - ... and much code cleanup and polishing +Changes to squid-3.4.12 (18 Feb 2015): + + - Bug 4066: Digest auth nonce indefinite rollover + - Bug 3997: Excessive NTLM or Negotiate auth helper annotations + - Fix several crashes when debugging enabled + - Fix silent SSL/TLS failure on split-stack operating systems + - HTTP/1.1: Stop emitting (Proxy-)Authentication-Info for Negotiate + - HTTPS: Add TLS/SSL option NO_TICKET to http[s]_port + - Remove dst ACL dependency on HTTP request message existence + - Set cap_net_admin when Squid sets TOS/Diffserv packet values + - ... and some documentation updates + Changes to squid-3.4.11 (13 Jan 2015): - Bug 4164: SEGFAULT when %W formating code used in errorpages diff -u -r -N squid-3.5.1/compat/Makefile.in squid-3.5.2/compat/Makefile.in --- squid-3.5.1/compat/Makefile.in 2015-01-13 04:53:10.000000000 -0800 +++ squid-3.5.2/compat/Makefile.in 2015-02-18 04:18:03.000000000 -0800 @@ -83,8 +83,8 @@ build_triplet = @build@ host_triplet = @host@ DIST_COMMON = $(top_srcdir)/src/Common.am $(srcdir)/Makefile.in \ - $(srcdir)/Makefile.am tempnam.c initgroups.c drand48.c \ - psignal.c strtoll.c strerror.c $(top_srcdir)/cfgaux/depcomp \ + $(srcdir)/Makefile.am strtoll.c strerror.c initgroups.c \ + drand48.c tempnam.c psignal.c $(top_srcdir)/cfgaux/depcomp \ $(top_srcdir)/cfgaux/test-driver check_PROGRAMS = testPreCompiler$(EXEEXT) TESTS = testPreCompiler$(EXEEXT) testHeaders diff -u -r -N squid-3.5.1/compat/osdetect.h squid-3.5.2/compat/osdetect.h --- squid-3.5.1/compat/osdetect.h 2015-01-13 04:52:01.000000000 -0800 +++ squid-3.5.2/compat/osdetect.h 2015-02-18 04:17:02.000000000 -0800 @@ -72,9 +72,8 @@ #elif defined(__DragonFly__) #define _SQUID_DRAGONFLY_ 1 -#elif defined(__CYGWIN32__) || defined(__CYGWIN__) +#elif defined(__CYGWIN__) #define _SQUID_CYGWIN_ 1 -#define _SQUID_WINDOWS_ 1 #elif defined(__MINGW32__) || defined(__MINGW__) #define _SQUID_MINGW_ 1 diff -u -r -N squid-3.5.1/configure squid-3.5.2/configure --- squid-3.5.1/configure 2015-01-13 04:54:26.000000000 -0800 +++ squid-3.5.2/configure 2015-02-18 04:18:57.000000000 -0800 @@ -1,7 +1,7 @@ #! /bin/sh # From configure.ac Revision. # Guess values for system-dependent variables and create Makefiles. -# Generated by GNU Autoconf 2.69 for Squid Web Proxy 3.5.1. +# Generated by GNU Autoconf 2.69 for Squid Web Proxy 3.5.2. # # Report bugs to . # @@ -595,8 +595,8 @@ # Identity of this package. PACKAGE_NAME='Squid Web Proxy' PACKAGE_TARNAME='squid' -PACKAGE_VERSION='3.5.1' -PACKAGE_STRING='Squid Web Proxy 3.5.1' +PACKAGE_VERSION='3.5.2' +PACKAGE_STRING='Squid Web Proxy 3.5.2' PACKAGE_BUGREPORT='http://bugs.squid-cache.org/' PACKAGE_URL='' @@ -1617,7 +1617,7 @@ # Omit some internal or obsolete options to make the list less imposing. # This message is too long to be a string in the A/UX 3.1 sh. cat <<_ACEOF -\`configure' configures Squid Web Proxy 3.5.1 to adapt to many kinds of systems. +\`configure' configures Squid Web Proxy 3.5.2 to adapt to many kinds of systems. Usage: $0 [OPTION]... [VAR=VALUE]... @@ -1687,7 +1687,7 @@ if test -n "$ac_init_help"; then case $ac_init_help in - short | recursive ) echo "Configuration of Squid Web Proxy 3.5.1:";; + short | recursive ) echo "Configuration of Squid Web Proxy 3.5.2:";; esac cat <<\_ACEOF @@ -2094,7 +2094,7 @@ test -n "$ac_init_help" && exit $ac_status if $ac_init_version; then cat <<\_ACEOF -Squid Web Proxy configure 3.5.1 +Squid Web Proxy configure 3.5.2 generated by GNU Autoconf 2.69 Copyright (C) 2012 Free Software Foundation, Inc. @@ -3198,7 +3198,7 @@ This file contains any messages produced by compilers while running configure, to aid debugging if configure makes a mistake. -It was created by Squid Web Proxy $as_me 3.5.1, which was +It was created by Squid Web Proxy $as_me 3.5.2, which was generated by GNU Autoconf 2.69. Invocation command line was $ $0 $@ @@ -4065,7 +4065,7 @@ # Define the identity of the package. PACKAGE='squid' - VERSION='3.5.1' + VERSION='3.5.2' cat >>confdefs.h <<_ACEOF @@ -6748,15 +6748,143 @@ fi +# Guess the compiler type (sets squid_cv_compiler) + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking what kind of compiler we're using" >&5 +$as_echo_n "checking what kind of compiler we're using... " >&6; } +if ${squid_cv_compiler+:} false; then : + $as_echo_n "(cached) " >&6 +else + + + if test -z "$squid_cv_compiler" ; then + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + + +#if !defined(__SUNPRO_C) && !defined(__SUNPRO_CC) +#error "not sunpro c" +#endif + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_cxx_try_compile "$LINENO"; then : + squid_cv_compiler="sunstudio" +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + fi + if test -z "$squid_cv_compiler" ; then + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + + +#if !defined(__ICC) +#error "not Intel(R) C++ Compiler" +#endif + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_cxx_try_compile "$LINENO"; then : + squid_cv_compiler="icc" +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + fi + if test -z "$squid_cv_compiler" ; then + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + + +#if !defined(__clang__) +#error "not clang" +#endif + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_cxx_try_compile "$LINENO"; then : + squid_cv_compiler="clang" +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + fi + if test -z "$squid_cv_compiler" ; then + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + + +#if !defined(_MSC_VER) +#error "not Microsoft VC++" +#endif + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_cxx_try_compile "$LINENO"; then : + squid_cv_compiler="msvc" +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + fi + if test -z "$squid_cv_compiler" ; then + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + + +#if !defined(__GNUC__) +#error "not gcc" +#endif + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_cxx_try_compile "$LINENO"; then : + squid_cv_compiler="gcc" +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + fi + if test -z "$squid_cv_compiler" ; then + squid_cv_compiler="none" + fi + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $squid_cv_compiler" >&5 +$as_echo "$squid_cv_compiler" >&6; } + # Check for C++11 compiler support -if test "x$squid_host_os" != "xmingw" ; then - #BUG 3613: when clang -std=c++0x is used, it activates a "strict mode" - # in the system libraries, which makes some c99 methods unavailable - # (e.g. strtoll), yet configure detects them as avilable. - case "$CXX" in - *clang++*) ;; #do nothing - *) - ax_cxx_compile_cxx11_required=false +# +# BUG 3613: when clang -std=c++0x is used, it activates a "strict mode" +# in the system libraries, which makes some c99 methods unavailable +# (e.g. strtoll), yet configure detects them as avilable. +# +# Similar POSIX issues on MinGW 32-bit and Cygwin +# +if ! test "x$squid_host_os" = "xmingw" -o "x$squid_host_os" = "xcygwin" -o "x$squid_cv_compiler" = "xclang"; then + ax_cxx_compile_cxx11_required=false ac_ext=cpp ac_cpp='$CXXCPP $CPPFLAGS' ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' @@ -6894,7 +7022,6 @@ fi - esac fi # test for programs @@ -19575,131 +19702,6 @@ fi - { $as_echo "$as_me:${as_lineno-$LINENO}: checking what kind of compiler we're using" >&5 -$as_echo_n "checking what kind of compiler we're using... " >&6; } -if ${squid_cv_compiler+:} false; then : - $as_echo_n "(cached) " >&6 -else - - - if test -z "$squid_cv_compiler" ; then - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - - -#if !defined(__SUNPRO_C) && !defined(__SUNPRO_CC) -#error "not sunpro c" -#endif - -int -main () -{ - - ; - return 0; -} -_ACEOF -if ac_fn_cxx_try_compile "$LINENO"; then : - squid_cv_compiler="sunstudio" -fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext - fi - if test -z "$squid_cv_compiler" ; then - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - - -#if !defined(__ICC) -#error "not Intel(R) C++ Compiler" -#endif - -int -main () -{ - - ; - return 0; -} -_ACEOF -if ac_fn_cxx_try_compile "$LINENO"; then : - squid_cv_compiler="icc" -fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext - fi - if test -z "$squid_cv_compiler" ; then - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - - -#if !defined(__clang__) -#error "not clang" -#endif - -int -main () -{ - - ; - return 0; -} -_ACEOF -if ac_fn_cxx_try_compile "$LINENO"; then : - squid_cv_compiler="clang" -fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext - fi - if test -z "$squid_cv_compiler" ; then - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - - -#if !defined(_MSC_VER) -#error "not Microsoft VC++" -#endif - -int -main () -{ - - ; - return 0; -} -_ACEOF -if ac_fn_cxx_try_compile "$LINENO"; then : - squid_cv_compiler="msvc" -fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext - fi - if test -z "$squid_cv_compiler" ; then - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - - -#if !defined(__GNUC__) -#error "not gcc" -#endif - -int -main () -{ - - ; - return 0; -} -_ACEOF -if ac_fn_cxx_try_compile "$LINENO"; then : - squid_cv_compiler="gcc" -fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext - fi - if test -z "$squid_cv_compiler" ; then - squid_cv_compiler="none" - fi - -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $squid_cv_compiler" >&5 -$as_echo "$squid_cv_compiler" >&6; } - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for compiler variant" >&5 $as_echo_n "checking for compiler variant... " >&6; } @@ -19755,7 +19757,7 @@ fi - if test "x$squid_host_os" = "xmingw" -o "x$squid_host_os" = "xcygwin"; then + if test "x$squid_host_os" = "xmingw"; then ENABLE_WIN32SPECIFIC_TRUE= ENABLE_WIN32SPECIFIC_FALSE='#' else @@ -21969,10 +21971,10 @@ if test "x${enable_eui:=yes}" = "xyes" ; then case "$squid_host_os" in - linux|solaris|freebsd|openbsd|netbsd) + linux|solaris|freebsd|openbsd|netbsd|cygwin) ${TRUE} ;; - cygwin|mingw) + mingw) EUILIB="-liphlpapi" ;; *) @@ -25511,8 +25513,12 @@ $as_echo "$as_me: Use krb5-config to get CXXFLAGS and LIBS" >&6;} LIB_KRB5_CFLAGS="`$ac_krb5_config --cflags krb5 2>/dev/null`" LIB_KRB5_LIBS="`$ac_krb5_config --libs krb5 2>/dev/null`" - LIB_KRB5_CFLAGS="`$ac_krb5_config --cflags gssapi 2>/dev/null` $LIB_KRB5_CFLAGS" - LIB_KRB5_LIBS="`$ac_krb5_config --libs gssapi 2>/dev/null` $LIB_KRB5_LIBS" + # Solaris 10 Update 11 patches the krb5-config tool to produce stderr messages on stdout. + SOLARIS_BROKEN_KRB5CONFIG_GSSAPI="`$ac_krb5_config --libs gssapi 2>/dev/null | grep "krb5-config"`" + if test "x$SOLARIS_BROKEN_KRB5CONFIG_GSSAPI" = "x"; then + LIB_KRB5_CFLAGS="`$ac_krb5_config --cflags gssapi 2>/dev/null` $LIB_KRB5_CFLAGS" + LIB_KRB5_LIBS="`$ac_krb5_config --libs gssapi 2>/dev/null` $LIB_KRB5_LIBS" + fi else ## For some OS pkg-config is broken or unavailable. ## Detect libraries the hard way. @@ -40707,7 +40713,7 @@ # report actual input values of CONFIG_FILES etc. instead of their # values after options handling. ac_log=" -This file was extended by Squid Web Proxy $as_me 3.5.1, which was +This file was extended by Squid Web Proxy $as_me 3.5.2, which was generated by GNU Autoconf 2.69. Invocation command line was CONFIG_FILES = $CONFIG_FILES @@ -40773,7 +40779,7 @@ cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`" ac_cs_version="\\ -Squid Web Proxy config.status 3.5.1 +Squid Web Proxy config.status 3.5.2 configured by $0, generated by GNU Autoconf 2.69, with options \\"\$ac_cs_config\\" diff -u -r -N squid-3.5.1/configure.ac squid-3.5.2/configure.ac --- squid-3.5.1/configure.ac 2015-01-13 04:54:25.000000000 -0800 +++ squid-3.5.2/configure.ac 2015-02-18 04:18:57.000000000 -0800 @@ -5,7 +5,7 @@ ## Please see the COPYING and CONTRIBUTORS files for details. ## -AC_INIT([Squid Web Proxy],[3.5.1],[http://bugs.squid-cache.org/],[squid]) +AC_INIT([Squid Web Proxy],[3.5.2],[http://bugs.squid-cache.org/],[squid]) AC_PREREQ(2.61) AC_CONFIG_HEADERS([include/autoconf.h]) AC_CONFIG_AUX_DIR(cfgaux) @@ -92,16 +92,19 @@ AC_USE_SYSTEM_EXTENSIONS fi +# Guess the compiler type (sets squid_cv_compiler) +SQUID_CC_GUESS_VARIANT + # Check for C++11 compiler support -if test "x$squid_host_os" != "xmingw" ; then - #BUG 3613: when clang -std=c++0x is used, it activates a "strict mode" - # in the system libraries, which makes some c99 methods unavailable - # (e.g. strtoll), yet configure detects them as avilable. - case "$CXX" in - *clang++*) ;; #do nothing - *) - AX_CXX_COMPILE_STDCXX_11([noext],[optional]) - esac +# +# BUG 3613: when clang -std=c++0x is used, it activates a "strict mode" +# in the system libraries, which makes some c99 methods unavailable +# (e.g. strtoll), yet configure detects them as avilable. +# +# Similar POSIX issues on MinGW 32-bit and Cygwin +# +if ! test "x$squid_host_os" = "xmingw" -o "x$squid_host_os" = "xcygwin" -o "x$squid_cv_compiler" = "xclang"; then + AX_CXX_COMPILE_STDCXX_11([noext],[optional]) fi # test for programs @@ -198,7 +201,6 @@ AC_SUBST([LIBADD_DL]) fi -SQUID_CC_GUESS_VARIANT SQUID_CC_GUESS_OPTIONS dnl find out the exe extension for this platform. @@ -214,8 +216,7 @@ fi AC_SUBST(CGIEXT) -AM_CONDITIONAL(ENABLE_WIN32SPECIFIC, - [test "x$squid_host_os" = "xmingw" -o "x$squid_host_os" = "xcygwin"]) +AM_CONDITIONAL(ENABLE_WIN32SPECIFIC,[test "x$squid_host_os" = "xmingw"]) AM_CONDITIONAL(ENABLE_WIN32_IPC,[test "x$squid_host_os" = "xmingw"]) case "$squid_host_os" in @@ -1132,10 +1133,10 @@ ]) if test "x${enable_eui:=yes}" = "xyes" ; then case "$squid_host_os" in - linux|solaris|freebsd|openbsd|netbsd) + linux|solaris|freebsd|openbsd|netbsd|cygwin) ${TRUE} ;; - cygwin|mingw) + mingw) EUILIB="-liphlpapi" ;; *) @@ -1583,8 +1584,12 @@ AC_MSG_NOTICE([Use krb5-config to get CXXFLAGS and LIBS]) LIB_KRB5_CFLAGS="`$ac_krb5_config --cflags krb5 2>/dev/null`" LIB_KRB5_LIBS="`$ac_krb5_config --libs krb5 2>/dev/null`" - LIB_KRB5_CFLAGS="`$ac_krb5_config --cflags gssapi 2>/dev/null` $LIB_KRB5_CFLAGS" - LIB_KRB5_LIBS="`$ac_krb5_config --libs gssapi 2>/dev/null` $LIB_KRB5_LIBS" + # Solaris 10 Update 11 patches the krb5-config tool to produce stderr messages on stdout. + SOLARIS_BROKEN_KRB5CONFIG_GSSAPI="`$ac_krb5_config --libs gssapi 2>/dev/null | grep "krb5-config"`" + if test "x$SOLARIS_BROKEN_KRB5CONFIG_GSSAPI" = "x"; then + LIB_KRB5_CFLAGS="`$ac_krb5_config --cflags gssapi 2>/dev/null` $LIB_KRB5_CFLAGS" + LIB_KRB5_LIBS="`$ac_krb5_config --libs gssapi 2>/dev/null` $LIB_KRB5_LIBS" + fi else ## For some OS pkg-config is broken or unavailable. ## Detect libraries the hard way. diff -u -r -N squid-3.5.1/helpers/basic_auth/DB/basic_db_auth.8 squid-3.5.2/helpers/basic_auth/DB/basic_db_auth.8 --- squid-3.5.1/helpers/basic_auth/DB/basic_db_auth.8 2015-01-13 05:43:16.000000000 -0800 +++ squid-3.5.2/helpers/basic_auth/DB/basic_db_auth.8 2015-02-18 04:55:55.000000000 -0800 @@ -133,7 +133,7 @@ .\" ======================================================================== .\" .IX Title "BASIC_DB_AUTH 1" -.TH BASIC_DB_AUTH 1 "2015-01-13" "perl v5.20.1" "User Contributed Perl Documentation" +.TH BASIC_DB_AUTH 1 "2015-02-18" "perl v5.20.1" "User Contributed Perl Documentation" .\" For nroff, turn off justification. Always turn off hyphenation; it makes .\" way too many mistakes in technical documents. .if n .ad l diff -u -r -N squid-3.5.1/helpers/basic_auth/MSNT-multi-domain/basic_msnt_multi_domain_auth.8 squid-3.5.2/helpers/basic_auth/MSNT-multi-domain/basic_msnt_multi_domain_auth.8 --- squid-3.5.1/helpers/basic_auth/MSNT-multi-domain/basic_msnt_multi_domain_auth.8 2015-01-13 05:43:22.000000000 -0800 +++ squid-3.5.2/helpers/basic_auth/MSNT-multi-domain/basic_msnt_multi_domain_auth.8 2015-02-18 04:55:58.000000000 -0800 @@ -133,7 +133,7 @@ .\" ======================================================================== .\" .IX Title "BASIC_MSNT_MULTI_DOMAIN_AUTH 1" -.TH BASIC_MSNT_MULTI_DOMAIN_AUTH 1 "2015-01-13" "perl v5.20.1" "User Contributed Perl Documentation" +.TH BASIC_MSNT_MULTI_DOMAIN_AUTH 1 "2015-02-18" "perl v5.20.1" "User Contributed Perl Documentation" .\" For nroff, turn off justification. Always turn off hyphenation; it makes .\" way too many mistakes in technical documents. .if n .ad l diff -u -r -N squid-3.5.1/helpers/basic_auth/POP3/basic_pop3_auth.8 squid-3.5.2/helpers/basic_auth/POP3/basic_pop3_auth.8 --- squid-3.5.1/helpers/basic_auth/POP3/basic_pop3_auth.8 2015-01-13 05:43:28.000000000 -0800 +++ squid-3.5.2/helpers/basic_auth/POP3/basic_pop3_auth.8 2015-02-18 04:56:01.000000000 -0800 @@ -133,7 +133,7 @@ .\" ======================================================================== .\" .IX Title "BASIC_POP3_AUTH 1" -.TH BASIC_POP3_AUTH 1 "2015-01-13" "perl v5.20.1" "User Contributed Perl Documentation" +.TH BASIC_POP3_AUTH 1 "2015-02-18" "perl v5.20.1" "User Contributed Perl Documentation" .\" For nroff, turn off justification. Always turn off hyphenation; it makes .\" way too many mistakes in technical documents. .if n .ad l diff -u -r -N squid-3.5.1/helpers/external_acl/delayer/ext_delayer_acl.8 squid-3.5.2/helpers/external_acl/delayer/ext_delayer_acl.8 --- squid-3.5.1/helpers/external_acl/delayer/ext_delayer_acl.8 2015-01-13 05:43:44.000000000 -0800 +++ squid-3.5.2/helpers/external_acl/delayer/ext_delayer_acl.8 2015-02-18 04:56:11.000000000 -0800 @@ -133,7 +133,7 @@ .\" ======================================================================== .\" .IX Title "EXT_DELAYER_ACL 1" -.TH EXT_DELAYER_ACL 1 "2015-01-13" "perl v5.20.1" "User Contributed Perl Documentation" +.TH EXT_DELAYER_ACL 1 "2015-02-18" "perl v5.20.1" "User Contributed Perl Documentation" .\" For nroff, turn off justification. Always turn off hyphenation; it makes .\" way too many mistakes in technical documents. .if n .ad l diff -u -r -N squid-3.5.1/helpers/external_acl/LDAP_group/ext_ldap_group_acl.8 squid-3.5.2/helpers/external_acl/LDAP_group/ext_ldap_group_acl.8 --- squid-3.5.1/helpers/external_acl/LDAP_group/ext_ldap_group_acl.8 2015-01-13 04:52:01.000000000 -0800 +++ squid-3.5.2/helpers/external_acl/LDAP_group/ext_ldap_group_acl.8 2015-02-18 04:17:02.000000000 -0800 @@ -7,19 +7,19 @@ . .SH SYNOPSIS .if !'po4a'hide' .B ext_ldap_group_acl -.if !'po4a'hide' .B "\-b \"" -base DN -.if !'po4a'hide' .B "\" \-f \"" -LDAP search filter -.if !'po4a'hide' .B "\" [" +.if !'po4a'hide' .B \-b +base\-DN +.if !'po4a'hide' .B \-f +filter +.if !'po4a'hide' .B "[" options .if !'po4a'hide' .B "] [" -LDAP server name -.if !'po4a'hide' .B "[:" +server +.if !'po4a'hide' .B "[ ':' " port -.if !'po4a'hide' .B "]|" +.if !'po4a'hide' .B "] |" URI -.if !'po4a'hide' .B "]..." +.if !'po4a'hide' .B "] ..." . .SH DESCRIPTION .B ext_ldap_group_acl @@ -100,7 +100,7 @@ configuration file without getting the secretfile. . .if !'po4a'hide' .TP -.if !'po4a'hide' .BI \-E certpath +.if !'po4a'hide' .BI "\-E " certpath Enable LDAP over SSL (requires Netscape LDAP API libraries) . .if !'po4a'hide' .TP diff -u -r -N squid-3.5.1/helpers/external_acl/SQL_session/ext_sql_session_acl.8 squid-3.5.2/helpers/external_acl/SQL_session/ext_sql_session_acl.8 --- squid-3.5.1/helpers/external_acl/SQL_session/ext_sql_session_acl.8 2015-01-13 05:43:55.000000000 -0800 +++ squid-3.5.2/helpers/external_acl/SQL_session/ext_sql_session_acl.8 2015-02-18 04:56:18.000000000 -0800 @@ -133,7 +133,7 @@ .\" ======================================================================== .\" .IX Title "EXT_SQL_SESSION_ACL 1" -.TH EXT_SQL_SESSION_ACL 1 "2015-01-13" "perl v5.20.1" "User Contributed Perl Documentation" +.TH EXT_SQL_SESSION_ACL 1 "2015-02-18" "perl v5.20.1" "User Contributed Perl Documentation" .\" For nroff, turn off justification. Always turn off hyphenation; it makes .\" way too many mistakes in technical documents. .if n .ad l diff -u -r -N squid-3.5.1/helpers/external_acl/wbinfo_group/ext_wbinfo_group_acl.8 squid-3.5.2/helpers/external_acl/wbinfo_group/ext_wbinfo_group_acl.8 --- squid-3.5.1/helpers/external_acl/wbinfo_group/ext_wbinfo_group_acl.8 2015-01-13 05:43:59.000000000 -0800 +++ squid-3.5.2/helpers/external_acl/wbinfo_group/ext_wbinfo_group_acl.8 2015-02-18 04:56:21.000000000 -0800 @@ -133,7 +133,7 @@ .\" ======================================================================== .\" .IX Title "EXT_WBINFO_GROUP_ACL 1" -.TH EXT_WBINFO_GROUP_ACL 1 "2015-01-13" "perl v5.20.1" "User Contributed Perl Documentation" +.TH EXT_WBINFO_GROUP_ACL 1 "2015-02-18" "perl v5.20.1" "User Contributed Perl Documentation" .\" For nroff, turn off justification. Always turn off hyphenation; it makes .\" way too many mistakes in technical documents. .if n .ad l diff -u -r -N squid-3.5.1/helpers/log_daemon/DB/log_db_daemon.8 squid-3.5.2/helpers/log_daemon/DB/log_db_daemon.8 --- squid-3.5.1/helpers/log_daemon/DB/log_db_daemon.8 2015-01-13 05:44:02.000000000 -0800 +++ squid-3.5.2/helpers/log_daemon/DB/log_db_daemon.8 2015-02-18 04:56:23.000000000 -0800 @@ -133,7 +133,7 @@ .\" ======================================================================== .\" .IX Title "LOG_DB_DAEMON 1" -.TH LOG_DB_DAEMON 1 "2015-01-13" "perl v5.20.1" "User Contributed Perl Documentation" +.TH LOG_DB_DAEMON 1 "2015-02-18" "perl v5.20.1" "User Contributed Perl Documentation" .\" For nroff, turn off justification. Always turn off hyphenation; it makes .\" way too many mistakes in technical documents. .if n .ad l diff -u -r -N squid-3.5.1/helpers/negotiate_auth/kerberos/negotiate_kerberos_auth.cc squid-3.5.2/helpers/negotiate_auth/kerberos/negotiate_kerberos_auth.cc --- squid-3.5.1/helpers/negotiate_auth/kerberos/negotiate_kerberos_auth.cc 2015-01-13 04:52:01.000000000 -0800 +++ squid-3.5.2/helpers/negotiate_auth/kerberos/negotiate_kerberos_auth.cc 2015-02-18 04:17:02.000000000 -0800 @@ -105,7 +105,7 @@ return NULL; } rc = getaddrinfo(hostname, NULL, NULL, &hres); - if (rc != 0) { + if (rc != 0 || hres == NULL ) { debug((char *) "%s| %s: ERROR: resolving hostname with getaddrinfo: %s failed\n", LogTime(), PROGRAM, gai_strerror(rc)); fprintf(stderr, @@ -339,10 +339,8 @@ gss_buffer_desc type_id = GSS_C_EMPTY_BUFFER; #endif #endif -#if HAVE_PAC_SUPPORT || HAVE_KRB5_MEMORY_KEYTAB krb5_context context = NULL; krb5_error_code ret; -#endif long length = 0; static int err = 0; int opt, log = 0, norealm = 0; @@ -352,6 +350,7 @@ char *service_principal = NULL; char *keytab_name = NULL; char *keytab_name_env = NULL; + char default_keytab[MAXPATHLEN]; #if HAVE_KRB5_MEMORY_KEYTAB char *memory_keytab_name = NULL; #endif @@ -536,9 +535,14 @@ putenv(keytab_name_env); } else { keytab_name_env = getenv("KRB5_KTNAME"); - if (!keytab_name_env) - keytab_name = xstrdup("/etc/krb5.keytab"); - else + if (!keytab_name_env) { + ret = krb5_init_context(&context); + if (!check_k5_err(context, "krb5_init_context", ret)) { + krb5_kt_default_name(context, default_keytab, MAXPATHLEN); + } + keytab_name = default_keytab; + krb5_free_context(context); + } else keytab_name = xstrdup(keytab_name_env); } debug((char *) "%s| %s: INFO: Setting keytab to %s\n", LogTime(), PROGRAM, keytab_name); diff -u -r -N squid-3.5.1/helpers/negotiate_auth/kerberos/negotiate_kerberos_pac.cc squid-3.5.2/helpers/negotiate_auth/kerberos/negotiate_kerberos_pac.cc --- squid-3.5.1/helpers/negotiate_auth/kerberos/negotiate_kerberos_pac.cc 2015-01-13 04:52:01.000000000 -0800 +++ squid-3.5.2/helpers/negotiate_auth/kerberos/negotiate_kerberos_pac.cc 2015-02-18 04:17:02.000000000 -0800 @@ -40,7 +40,7 @@ #include "negotiate_kerberos.h" -#if HAVE_PAC_SUPPORT +#if HAVE_GSSAPI && HAVE_PAC_SUPPORT static int bpos; static krb5_data *ad_data; @@ -141,9 +141,9 @@ int checkustr(RPC_UNICODE_STRING *string) { - uint32_t size,off,len; if (string->pointer != 0) { + uint32_t size,off,len; align(4); size = (uint32_t)((p[bpos]<<0) | (p[bpos+1]<<8) | (p[bpos+2]<<16) | (p[bpos+3]<<24)); bpos = bpos+4; @@ -168,7 +168,6 @@ { if (GroupIds!= 0) { uint32_t ngroup; - uint32_t sauth; int l; align(4); @@ -182,6 +181,7 @@ Rids=(char **)xcalloc(GroupCount*sizeof(char*),1); for ( l=0; l<(int)GroupCount; l++) { + uint32_t sauth; Rids[l]=(char *)xcalloc(4*sizeof(char),1); memcpy((void *)Rids[l],(void *)&p[bpos],4); sauth = get4byt(); @@ -196,11 +196,16 @@ char * getdomaingids(char *ad_groups, uint32_t DomainLogonId, char **Rids, uint32_t GroupCount) { + if (!ad_groups) { + debug((char *) "%s| %s: ERR: No space to store groups\n", + LogTime(), PROGRAM); + return NULL; + } + if (DomainLogonId!= 0) { uint32_t nauth; uint8_t rev; uint64_t idauth; - uint32_t sauth; char dli[256]; char *ag; size_t length; @@ -244,6 +249,7 @@ snprintf(dli,sizeof(dli),"S-%d-%lu",rev,(long unsigned int)idauth); for ( l=0; l<(int)nauth; l++ ) { + uint32_t sauth; sauth = get4byt(); snprintf((char *)&dli[strlen(dli)],sizeof(dli)-strlen(dli),"-%u",sauth); } @@ -279,23 +285,23 @@ for ( l=0; l<(int)SidCount; l++ ) { char es[256]; - uint32_t nauth; - uint8_t rev; - uint64_t idauth; - uint32_t sauth; - int k; if (pa[l] != 0) { + uint32_t nauth; + uint8_t rev; + uint64_t idauth; + nauth = get4byt(); length = 1+1+6+nauth*4; ag = (char *)xcalloc((length)*sizeof(char),1); memcpy((void *)ag,(const void*)&p[bpos],length); if (!ad_groups) { - if (!pstrcpy(ad_groups,"group=")) { - debug((char *) "%s| %s: WARN: Too many groups ! size > %d : %s\n", - LogTime(), PROGRAM, MAX_PAC_GROUP_SIZE, ad_groups); - } + debug((char *) "%s| %s: ERR: No space to store groups\n", + LogTime(), PROGRAM); + xfree(pa); + xfree(ag); + return NULL; } else { if (!pstrcat(ad_groups," group=")) { debug((char *) "%s| %s: WARN: Too many groups ! size > %d : %s\n", @@ -313,7 +319,8 @@ idauth = get6byt_be(); snprintf(es,sizeof(es),"S-%d-%lu",rev,(long unsigned int)idauth); - for ( k=0; k<(int)nauth; k++ ) { + for (int k=0; k<(int)nauth; k++ ) { + uint32_t sauth; sauth = get4byt(); snprintf((char *)&es[strlen(es)],sizeof(es)-strlen(es),"-%u",sauth); } @@ -350,6 +357,12 @@ char **Rids=NULL; int l=0; + if (!ad_groups) { + debug((char *) "%s| %s: ERR: No space to store groups\n", + LogTime(), PROGRAM); + return NULL; + } + ad_data = (krb5_data *)xcalloc(1,sizeof(krb5_data)); #define KERB_LOGON_INFO 1 diff -u -r -N squid-3.5.1/helpers/storeid_rewrite/file/storeid_file_rewrite.8 squid-3.5.2/helpers/storeid_rewrite/file/storeid_file_rewrite.8 --- squid-3.5.1/helpers/storeid_rewrite/file/storeid_file_rewrite.8 2015-01-13 05:44:19.000000000 -0800 +++ squid-3.5.2/helpers/storeid_rewrite/file/storeid_file_rewrite.8 2015-02-18 04:56:33.000000000 -0800 @@ -133,7 +133,7 @@ .\" ======================================================================== .\" .IX Title "STOREID_FILE_REWRITE 1" -.TH STOREID_FILE_REWRITE 1 "2015-01-13" "perl v5.20.1" "User Contributed Perl Documentation" +.TH STOREID_FILE_REWRITE 1 "2015-02-18" "perl v5.20.1" "User Contributed Perl Documentation" .\" For nroff, turn off justification. Always turn off hyphenation; it makes .\" way too many mistakes in technical documents. .if n .ad l diff -u -r -N squid-3.5.1/include/splay.h squid-3.5.2/include/splay.h --- squid-3.5.1/include/splay.h 2015-01-13 04:52:01.000000000 -0800 +++ squid-3.5.2/include/splay.h 2015-02-18 04:17:02.000000000 -0800 @@ -9,16 +9,13 @@ #ifndef SQUID_SPLAY_H #define SQUID_SPLAY_H -#if defined(__cplusplus) - #include "fatal.h" - #include +// private class of Splay. Do not use directly template class SplayNode { - public: typedef V Value; typedef int SPLAYCMP(Value const &a, Value const &b); @@ -30,9 +27,8 @@ Value data; mutable SplayNode *left; mutable SplayNode *right; - void destroy(SPLAYFREE *); + void destroy(SPLAYFREE * = DefaultFree); void walk(SPLAYWALKEE *, void *callerState); - bool empty() const { return this == NULL; } SplayNode const * start() const; SplayNode const * finish() const; @@ -40,6 +36,8 @@ SplayNode * insert(Value data, SPLAYCMP * compare); + /// look in the splay for data for where compare(data,candidate) == true. + /// return NULL if not found, a pointer to the sought data if found. template SplayNode * splay(const FindValue &data, int( * compare)(FindValue const &a, Value const &b)) const; /// recursively visit left nodes, this node, and then right nodes @@ -57,7 +55,6 @@ template class Splay { - public: typedef V Value; typedef int SPLAYCMP(Value const &a, Value const &b); @@ -66,13 +63,13 @@ typedef const SplayConstIterator const_iterator; Splay():head(NULL), elements (0) {} - mutable SplayNode * head; template Value const *find (FindValue const &, int( * compare)(FindValue const &a, Value const &b)) const; + void insert(Value const &, SPLAYCMP *compare); void remove(Value const &, SPLAYCMP *compare); - void destroy(SPLAYFREE *); + void destroy(SPLAYFREE * = SplayNode::DefaultFree); SplayNode const * start() const; @@ -80,6 +77,8 @@ size_t size() const; + bool empty() const { return size() == 0; } + const_iterator begin() const; const_iterator end() const; @@ -87,22 +86,13 @@ /// recursively visit all nodes, in left-to-right order template void visit(Visitor &v) const; +private: + mutable SplayNode * head; size_t elements; }; SQUIDCEXTERN int splayLastResult; -SQUIDCEXTERN splayNode *splay_insert(void *, splayNode *, splayNode::SPLAYCMP *); - -SQUIDCEXTERN splayNode *splay_delete(const void *, splayNode *, splayNode::SPLAYCMP *); - -SQUIDCEXTERN splayNode *splay_splay(const void **, splayNode *, splayNode::SPLAYCMP *); - -SQUIDCEXTERN void splay_destroy(splayNode *, splayNode::SPLAYFREE *); - -SQUIDCEXTERN void splay_walk(splayNode *, splayNode::SPLAYWALKEE *, void *callerState); - -/* inline methods */ template SplayNode::SplayNode (Value const &someData) : data(someData), left(NULL), right (NULL) {} @@ -110,9 +100,6 @@ void SplayNode::walk(SPLAYWALKEE * walkee, void *state) { - if (this == NULL) - return; - if (left) left->walk(walkee, state); @@ -126,7 +113,7 @@ SplayNode const * SplayNode::start() const { - if (this && left) + if (left) return left->start(); return this; @@ -136,7 +123,7 @@ SplayNode const * SplayNode::finish() const { - if (this && right) + if (right) return right->finish(); return this; @@ -146,9 +133,6 @@ void SplayNode::destroy(SPLAYFREE * free_func) { - if (!this) - return; - if (left) left->destroy(free_func); @@ -164,9 +148,6 @@ SplayNode * SplayNode::remove(Value const dataToRemove, SPLAYCMP * compare) { - if (this == NULL) - return NULL; - SplayNode *result = splay(dataToRemove, compare); if (splayLastResult == 0) { /* found it */ @@ -194,13 +175,6 @@ { /* create node to insert */ SplayNode *newNode = new SplayNode(dataToInsert); - - if (this == NULL) { - splayLastResult = -1; - newNode->left = newNode->right = NULL; - return newNode; - } - SplayNode *newTop = splay(dataToInsert, compare); if (splayLastResult < 0) { @@ -225,12 +199,6 @@ SplayNode * SplayNode::splay(FindValue const &dataToFind, int( * compare)(FindValue const &a, Value const &b)) const { - if (this == NULL) { - /* can't have compared successfully :} */ - splayLastResult = -1; - return NULL; - } - Value temp = Value(); SplayNode N(temp); SplayNode *l; @@ -316,6 +284,9 @@ typename Splay::Value const * Splay::find (FindValue const &value, int( * compare)(FindValue const &a, Value const &b)) const { + if (head == NULL) + return NULL; + head = head->splay(value, compare); if (splayLastResult != 0) @@ -328,8 +299,13 @@ void Splay::insert(Value const &value, SPLAYCMP *compare) { - assert (!find (value, compare)); - head = head->insert(value, compare); + if (find(value, compare) != NULL) // ignore duplicates + return; + + if (head == NULL) + head = new SplayNode(value); + else + head = head->insert(value, compare); ++elements; } @@ -513,7 +489,5 @@ return toVisit.top()->data; } -#endif /* cplusplus */ - #endif /* SQUID_SPLAY_H */ diff -u -r -N squid-3.5.1/include/version.h squid-3.5.2/include/version.h --- squid-3.5.1/include/version.h 2015-01-13 04:54:26.000000000 -0800 +++ squid-3.5.2/include/version.h 2015-02-18 04:18:57.000000000 -0800 @@ -7,7 +7,7 @@ */ #ifndef SQUID_RELEASE_TIME -#define SQUID_RELEASE_TIME 1421153513 +#define SQUID_RELEASE_TIME 1424261814 #endif /* diff -u -r -N squid-3.5.1/lib/MemPoolChunked.cc squid-3.5.2/lib/MemPoolChunked.cc --- squid-3.5.1/lib/MemPoolChunked.cc 2015-01-13 04:52:01.000000000 -0800 +++ squid-3.5.2/lib/MemPoolChunked.cc 2015-02-18 04:17:02.000000000 -0800 @@ -141,16 +141,11 @@ pool->allChunks.insert(this, memCompChunks); } -MemPoolChunked::MemPoolChunked(const char *aLabel, size_t aSize) : MemImplementingAllocator(aLabel, aSize) +MemPoolChunked::MemPoolChunked(const char *aLabel, size_t aSize) : + MemImplementingAllocator(aLabel, aSize) , chunk_size(0), + chunk_capacity(0), chunkCount(0), freeCache(0), nextFreeChunk(0), + Chunks(0), allChunks(Splay()) { - chunk_size = 0; - chunk_capacity = 0; - chunkCount = 0; - freeCache = 0; - nextFreeChunk = 0; - Chunks = 0; - next = 0; - setChunkSize(MEM_CHUNK_SIZE); #if HAVE_MALLOPT && M_MMAP_MAX @@ -367,8 +362,6 @@ MemChunk *chunk, *freechunk, *listTail; time_t age; - if (!this) - return; if (!Chunks) return; diff -u -r -N squid-3.5.1/RELEASENOTES.html squid-3.5.2/RELEASENOTES.html --- squid-3.5.1/RELEASENOTES.html 2015-01-13 05:45:58.000000000 -0800 +++ squid-3.5.2/RELEASENOTES.html 2015-02-18 04:57:35.000000000 -0800 @@ -2,10 +2,10 @@ - Squid 3.5.1 release notes + Squid 3.5.2 release notes -

Squid 3.5.1 release notes

+

Squid 3.5.2 release notes

Squid Developers


@@ -63,10 +63,10 @@

1. Notice

-

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

+

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

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

+mirrors.

Some interesting new features adding system flexibility have been added along with general improvements all around. While this release is not fully bug-free we believe it is ready for use in production on many systems.

@@ -322,7 +322,7 @@ receive traffic from client software sending in this protocol. HTTP traffic without the PROXY header is not accepted on such a port.

-

The accel and intercept options are still used to identify the +

The accel and intercept options are still used to identify the HTTP traffic syntax being delivered by the client proxy.

Squid can be configured by adding an http_port @@ -414,17 +414,13 @@ Collapsing of requests is performed across SMP workers.

ftp_client_idle_timeout
-

This new configuration directive controls how long Squid should -wait for an FTP request on a connection to an ftp_port. Many FTP -clients do not deal with idle connection closures well, -necessitating a longer default timeout (30 minutes) than -client_idle_pconn_timeout used for incoming HTTP requests (2 -minutes). The current default may be changed as we get more -experience with FTP relaying.

- -
ftp_client_idle_timeout

New directive controlling how long to wait for an FTP request on a client connection to Squid ftp_port.

+

Many FTP clients do not deal with idle connection closures well, +necessitating a longer default timeout (30 minutes) than +client_idle_pconn_timeout used for incoming HTTP requests (2 +minutes).

+

The current default may be changed as we get more experience with FTP relaying.

ftp_port

New configuration directive to accept and relay native FTP diff -u -r -N squid-3.5.1/src/acl/Acl.cc squid-3.5.2/src/acl/Acl.cc --- squid-3.5.1/src/acl/Acl.cc 2015-01-13 04:52:01.000000000 -0800 +++ squid-3.5.2/src/acl/Acl.cc 2015-02-18 04:17:02.000000000 -0800 @@ -377,7 +377,7 @@ ACL::~ACL() { - debugs(28, 3, "ACL::~ACL: '" << cfgline << "'"); + debugs(28, 3, "freeing ACL " << name); safe_free(cfgline); AclMatchedName = NULL; // in case it was pointing to our name } diff -u -r -N squid-3.5.1/src/acl/Arp.cc squid-3.5.2/src/acl/Arp.cc --- squid-3.5.1/src/acl/Arp.cc 2015-01-13 04:52:01.000000000 -0800 +++ squid-3.5.2/src/acl/Arp.cc 2015-02-18 04:17:02.000000000 -0800 @@ -20,10 +20,7 @@ #include "globals.h" #include "ip/Address.h" -static void aclParseArpList(SplayNode **curlist); -static int aclMatchArp(SplayNode **dataptr, Ip::Address &c); -static SplayNode::SPLAYCMP aclArpCompare; -static SplayNode::SPLAYWALKEE aclDumpArpListWalkee; +#include ACL * ACLARP::clone() const @@ -31,19 +28,11 @@ return new ACLARP(*this); } -ACLARP::ACLARP (char const *theClass) : data (NULL), class_ (theClass) +ACLARP::ACLARP (char const *theClass) : class_ (theClass) {} -ACLARP::ACLARP (ACLARP const & old) : data (NULL), class_ (old.class_) +ACLARP::ACLARP (ACLARP const & old) : class_ (old.class_), aclArpData(old.aclArpData) { - /* we don't have copy constructors for the data yet */ - assert (!old.data); -} - -ACLARP::~ACLARP() -{ - if (data) - data->destroy(SplayNode::DefaultFree); } char const * @@ -55,7 +44,7 @@ bool ACLARP::empty () const { - return data->empty(); + return aclArpData.empty(); } /* ==== BEGIN ARP ACL SUPPORT ============================================= */ @@ -93,14 +82,14 @@ if (sscanf(t, "%[0-9a-fA-F:]", buf) != 1) { debugs(28, DBG_CRITICAL, "aclParseArpData: Bad ethernet address: '" << t << "'"); - safe_free(q); + delete q; return NULL; } if (!q->decode(buf)) { debugs(28, DBG_CRITICAL, "" << cfg_filename << " line " << config_lineno << ": " << config_input_line); debugs(28, DBG_CRITICAL, "aclParseArpData: Ignoring invalid ARP acl entry: can't parse '" << buf << "'"); - safe_free(q); + delete q; return NULL; } @@ -113,21 +102,11 @@ void ACLARP::parse() { - aclParseArpList(&data); -} - -void -aclParseArpList(SplayNode **curlist) -{ - char *t = NULL; - SplayNode **Top = curlist; - Eui::Eui48 *q = NULL; - - while ((t = strtokFile())) { - if ((q = aclParseArpData(t)) == NULL) - continue; - - *Top = (*Top)->insert(q, aclArpCompare); + while (const char *t = strtokFile()) { + if (Eui::Eui48 *q = aclParseArpData(t)) { + aclArpData.insert(*q); + delete q; + } } } @@ -142,51 +121,20 @@ return 0; } - return aclMatchArp(&data, checklist->src_addr); -} - -/***************/ -/* aclMatchArp */ -/***************/ -int -aclMatchArp(SplayNode **dataptr, Ip::Address &c) -{ - Eui::Eui48 result; - SplayNode **Top = dataptr; - - if (result.lookup(c)) { - /* Do ACL match lookup */ - *Top = (*Top)->splay(&result, aclArpCompare); - debugs(28, 3, "aclMatchArp: '" << c << "' " << (splayLastResult ? "NOT found" : "found")); - return (0 == splayLastResult); - } - - /* - * Address was not found on any interface - */ - debugs(28, 3, "aclMatchArp: " << c << " NOT found"); - return 0; -} - -static int -aclArpCompare(Eui::Eui48 * const &a, Eui::Eui48 * const &b) -{ - return memcmp(a, b, sizeof(Eui::Eui48)); -} - -static void -aclDumpArpListWalkee(Eui::Eui48 * const &node, void *state) -{ - static char buf[48]; - node->encode(buf, 48); - static_cast(state)->push_back(SBuf(buf)); + Eui::Eui48 lookingFor; + lookingFor.lookup(checklist->src_addr); + return (aclArpData.find(lookingFor) != aclArpData.end()); } SBufList ACLARP::dump() const { SBufList sl; - data->walk(aclDumpArpListWalkee, &sl); + for (AclArpData_t::iterator i = aclArpData.begin(); i != aclArpData.end(); ++i) { + char buf[48]; + i->encode(buf,48); + sl.push_back(SBuf(buf)); + } return sl; } diff -u -r -N squid-3.5.1/src/acl/Arp.h squid-3.5.2/src/acl/Arp.h --- squid-3.5.1/src/acl/Arp.h 2015-01-13 04:52:01.000000000 -0800 +++ squid-3.5.2/src/acl/Arp.h 2015-02-18 04:17:02.000000000 -0800 @@ -11,7 +11,8 @@ #include "acl/Acl.h" #include "acl/Checklist.h" -#include "splay.h" + +#include namespace Eui { @@ -27,7 +28,7 @@ ACLARP(char const *); ACLARP(ACLARP const &); - ~ACLARP(); + ~ACLARP() {} ACLARP&operator=(ACLARP const &); virtual ACL *clone()const; @@ -40,8 +41,9 @@ protected: static Prototype RegistryProtoype; static ACLARP RegistryEntry_; - SplayNode *data; char const *class_; + typedef std::set AclArpData_t; + AclArpData_t aclArpData; }; MEMPROXY_CLASS_INLINE(ACLARP); diff -u -r -N squid-3.5.1/src/acl/CertificateData.cc squid-3.5.2/src/acl/CertificateData.cc --- squid-3.5.1/src/acl/CertificateData.cc 2015-01-13 04:52:01.000000000 -0800 +++ squid-3.5.2/src/acl/CertificateData.cc 2015-02-18 04:17:02.000000000 -0800 @@ -71,25 +71,20 @@ return values.match(value); } -static void -aclDumpAttributeListWalkee(char * const & node_data, void *outlist) -{ - /* outlist is really a SBufList * */ - static_cast(outlist)->push_back(SBuf(node_data)); -} - SBufList ACLCertificateData::dump() const { SBufList sl; if (validAttributesStr) sl.push_back(SBuf(attribute)); - /* damn this is VERY inefficient for long ACL lists... filling - * a wordlist this way costs Sum(1,N) iterations. For instance - * a 1000-elements list will be filled in 499500 iterations. - */ - /* XXX FIXME: don't break abstraction */ - values.values->walk(aclDumpAttributeListWalkee, &sl); + +#if __cplusplus >= 201103L + sl.splice(sl.end(),values.dump()); +#else + // temp is needed until c++11 move constructor + SBufList tmp = values.dump(); + sl.splice(sl.end(),tmp); +#endif return sl; } diff -u -r -N squid-3.5.1/src/acl/DestinationIp.cc squid-3.5.2/src/acl/DestinationIp.cc --- squid-3.5.1/src/acl/DestinationIp.cc 2015-01-13 04:52:01.000000000 -0800 +++ squid-3.5.2/src/acl/DestinationIp.cc 2015-02-18 04:17:02.000000000 -0800 @@ -29,6 +29,10 @@ { ACLFilledChecklist *checklist = Filled(cl); + // if there is no HTTP request details fallback to the dst_addr + if (!checklist->request) + return ACLIP::match(checklist->dst_addr); + // Bug 3243: CVE 2009-0801 // Bypass of browser same-origin access control in intercepted communication // To resolve this we will force DIRECT and only to the original client destination. diff -u -r -N squid-3.5.1/src/acl/DestinationIp.h squid-3.5.2/src/acl/DestinationIp.h --- squid-3.5.1/src/acl/DestinationIp.h 2015-01-13 04:52:01.000000000 -0800 +++ squid-3.5.2/src/acl/DestinationIp.h 2015-02-18 04:17:02.000000000 -0800 @@ -33,7 +33,6 @@ ACLDestinationIP(): ACLIP(ACLDestinationIP::SupportedFlags) {} virtual char const *typeString() const; virtual int match(ACLChecklist *checklist); - virtual bool requiresRequest() const {return true;} virtual ACL *clone()const; diff -u -r -N squid-3.5.1/src/acl/DomainData.cc squid-3.5.2/src/acl/DomainData.cc --- squid-3.5.1/src/acl/DomainData.cc 2015-01-13 04:52:01.000000000 -0800 +++ squid-3.5.2/src/acl/DomainData.cc 2015-02-18 04:17:02.000000000 -0800 @@ -24,8 +24,10 @@ ACLDomainData::~ACLDomainData() { - if (domains) + if (domains) { domains->destroy(xRefFree); + delete domains; + } } template @@ -105,30 +107,27 @@ debugs(28, 3, "aclMatchDomainList: checking '" << host << "'"); - domains = domains->splay((char *)host, aclHostDomainCompare); + char *h = const_cast(host); + char const * const * result = domains->find(h, aclHostDomainCompare); - debugs(28, 3, "aclMatchDomainList: '" << host << "' " << (splayLastResult ? "NOT found" : "found")); + debugs(28, 3, "aclMatchDomainList: '" << host << "' " << (result ? "found" : "NOT found")); - return !splayLastResult; + return (result != NULL); } -static void -aclDumpDomainListWalkee(char * const & node_data, void *outlist) -{ - /* outlist is really a SBufList ** */ - static_cast(outlist)->push_back(SBuf(node_data)); -} +struct AclDomainDataDumpVisitor { + SBufList contents; + void operator() (char * const & node_data) { + contents.push_back(SBuf(node_data)); + } +}; SBufList ACLDomainData::dump() const { - SBufList sl; - /* damn this is VERY inefficient for long ACL lists... filling - * a wordlist this way costs Sum(1,N) iterations. For instance - * a 1000-elements list will be filled in 499500 iterations. - */ - domains->walk(aclDumpDomainListWalkee, &sl); - return sl; + AclDomainDataDumpVisitor visitor; + domains->visit(visitor); + return visitor.contents; } void @@ -136,9 +135,12 @@ { char *t = NULL; + if (!domains) + domains = new Splay(); + while ((t = strtokFile())) { Tolower(t); - domains = domains->insert(xstrdup(t), aclDomainCompare); + domains->insert(xstrdup(t), aclDomainCompare); } } diff -u -r -N squid-3.5.1/src/acl/DomainData.h squid-3.5.2/src/acl/DomainData.h --- squid-3.5.1/src/acl/DomainData.h 2015-01-13 04:52:01.000000000 -0800 +++ squid-3.5.2/src/acl/DomainData.h 2015-02-18 04:17:02.000000000 -0800 @@ -27,7 +27,7 @@ bool empty() const; virtual ACLData *clone() const; - SplayNode *domains; + Splay *domains; }; MEMPROXY_CLASS_INLINE(ACLDomainData); diff -u -r -N squid-3.5.1/src/acl/Eui64.cc squid-3.5.2/src/acl/Eui64.cc --- squid-3.5.1/src/acl/Eui64.cc 2015-01-13 04:52:01.000000000 -0800 +++ squid-3.5.2/src/acl/Eui64.cc 2015-02-18 04:17:02.000000000 -0800 @@ -20,30 +20,17 @@ #include "globals.h" #include "ip/Address.h" -static void aclParseEuiList(SplayNode **curlist); -static int aclMatchEui(SplayNode **dataptr, Ip::Address &c); -static SplayNode::SPLAYCMP aclEui64Compare; -static SplayNode::SPLAYWALKEE aclDumpEuiListWalkee; - ACL * ACLEui64::clone() const { return new ACLEui64(*this); } -ACLEui64::ACLEui64 (char const *theClass) : data (NULL), class_ (theClass) +ACLEui64::ACLEui64 (char const *theClass) : class_ (theClass) {} -ACLEui64::ACLEui64 (ACLEui64 const & old) : data (NULL), class_ (old.class_) -{ - /* we don't have copy constructors for the data yet */ - assert (!old.data); -} - -ACLEui64::~ACLEui64() +ACLEui64::ACLEui64 (ACLEui64 const & old) : eui64Data(old.eui64Data), class_ (old.class_) { - if (data) - data->destroy(SplayNode::DefaultFree); } char const * @@ -55,7 +42,7 @@ bool ACLEui64::empty () const { - return data->empty(); + return eui64Data.empty(); } Eui::Eui64 * @@ -67,14 +54,14 @@ if (sscanf(t, "%[0-9a-fA-F:]", buf) != 1) { debugs(28, DBG_CRITICAL, "aclParseEuiData: Bad EUI-64 address: '" << t << "'"); - safe_free(q); + delete q; return NULL; } if (!q->decode(buf)) { debugs(28, DBG_CRITICAL, "" << cfg_filename << " line " << config_lineno << ": " << config_input_line); debugs(28, DBG_CRITICAL, "aclParseEuiData: Ignoring invalid EUI-64 acl entry: can't parse '" << buf << "'"); - safe_free(q); + delete q; return NULL; } @@ -87,21 +74,11 @@ void ACLEui64::parse() { - aclParseEuiList(&data); -} - -void -aclParseEuiList(SplayNode **curlist) -{ - char *t = NULL; - SplayNode **Top = curlist; - Eui::Eui64 *q = NULL; - - while ((t = strtokFile())) { - if ((q = aclParseEuiData(t)) == NULL) - continue; - - *Top = (*Top)->insert(q, aclEui64Compare); + while (const char * t = strtokFile()) { + if (Eui::Eui64 * q = aclParseEuiData(t)) { + eui64Data.insert(*q); + delete q; + } } } @@ -116,52 +93,27 @@ return 0; } - return aclMatchEui(&data, checklist->src_addr); -} - -/***************/ -/* aclMatchEui */ -/***************/ -int -aclMatchEui(SplayNode **dataptr, Ip::Address &c) -{ - Eui::Eui64 result; - SplayNode **Top = dataptr; + Eui::Eui64 lookingFor; + if (lookingFor.lookup(checklist->src_addr)) { + bool found = (eui64Data.find(lookingFor) != eui64Data.end()); + debugs(28, 3, checklist->src_addr << "' " << (found ? "found" : "NOT found")); + return found; + } - if (result.lookup(c)) { - /* Do ACL match lookup */ - *Top = (*Top)->splay(&result, aclEui64Compare); - debugs(28, 3, "aclMatchEui: '" << c << "' " << (splayLastResult ? "NOT found" : "found")); - return (0 == splayLastResult); - } - - /* - * Address was not found on any interface - */ - debugs(28, 3, "aclMatchEui: " << c << " NOT found"); + debugs(28, 3, checklist->src_addr << " NOT found"); return 0; } -static int -aclEui64Compare(Eui::Eui64 * const &a, Eui::Eui64 * const &b) -{ - return memcmp(a, b, sizeof(Eui::Eui64)); -} - -static void -aclDumpEuiListWalkee(Eui::Eui64 * const &node, void *state) -{ - static char buf[48]; - node->encode(buf, 48); - static_cast(state)->push_back(SBuf(buf)); -} - SBufList ACLEui64::dump() const { - SBufList w; - data->walk(aclDumpEuiListWalkee, &w); - return w; + SBufList sl; + for (Eui64Data_t::iterator i = eui64Data.begin(); i != eui64Data.end(); ++i) { + static char buf[48]; + i->encode(buf,48); + sl.push_back(SBuf(buf)); + } + return sl; } #endif /* USE_SQUID_EUI */ diff -u -r -N squid-3.5.1/src/acl/Eui64.h squid-3.5.2/src/acl/Eui64.h --- squid-3.5.1/src/acl/Eui64.h 2015-01-13 04:52:01.000000000 -0800 +++ squid-3.5.2/src/acl/Eui64.h 2015-02-18 04:17:02.000000000 -0800 @@ -11,7 +11,8 @@ #include "acl/Acl.h" #include "acl/Checklist.h" -#include "splay.h" + +#include namespace Eui { @@ -27,7 +28,7 @@ ACLEui64(char const *); ACLEui64(ACLEui64 const &); - ~ACLEui64(); + ~ACLEui64() {} ACLEui64&operator=(ACLEui64 const &); virtual ACL *clone()const; @@ -40,7 +41,8 @@ protected: static Prototype RegistryProtoype; static ACLEui64 RegistryEntry_; - SplayNode *data; + typedef std::set Eui64Data_t; + Eui64Data_t eui64Data; char const *class_; }; diff -u -r -N squid-3.5.1/src/acl/HttpHeaderData.cc squid-3.5.2/src/acl/HttpHeaderData.cc --- squid-3.5.1/src/acl/HttpHeaderData.cc 2015-01-13 04:52:01.000000000 -0800 +++ squid-3.5.2/src/acl/HttpHeaderData.cc 2015-02-18 04:17:02.000000000 -0800 @@ -60,9 +60,13 @@ { SBufList sl; sl.push_back(SBuf(hdrName)); +#if __cplusplus >= 201103L + sl.splice(sl.end(), regex_rule->dump()); +#else // temp is needed until c++11 move-constructor SBufList temp = regex_rule->dump(); sl.splice(sl.end(), temp); +#endif return sl; } diff -u -r -N squid-3.5.1/src/acl/HttpStatus.cc squid-3.5.2/src/acl/HttpStatus.cc --- squid-3.5.1/src/acl/HttpStatus.cc 2015-01-13 04:52:01.000000000 -0800 +++ squid-3.5.2/src/acl/HttpStatus.cc 2015-02-18 04:17:02.000000000 -0800 @@ -17,9 +17,9 @@ #include -static void aclParseHTTPStatusList(SplayNode **curlist); +static void aclParseHTTPStatusList(Splay **curlist); static int aclHTTPStatusCompare(acl_httpstatus_data * const &a, acl_httpstatus_data * const &b); -static int aclMatchHTTPStatus(SplayNode **dataptr, Http::StatusCode status); +static int aclMatchHTTPStatus(Splay **dataptr, Http::StatusCode status); acl_httpstatus_data::acl_httpstatus_data(int x) : status1(x), status2(x) { ; } @@ -74,8 +74,10 @@ ACLHTTPStatus::~ACLHTTPStatus() { - if (data) - data->destroy(SplayNode::DefaultFree); + if (data) { + data->destroy(); + delete data; + } } char const * @@ -109,21 +111,23 @@ void ACLHTTPStatus::parse() { + if (!data) + data = new Splay(); + aclParseHTTPStatusList (&data); } void -aclParseHTTPStatusList(SplayNode **curlist) +aclParseHTTPStatusList(Splay **curlist) { char *t = NULL; - SplayNode **Top = curlist; acl_httpstatus_data *q = NULL; while ((t = strtokFile())) { if ((q = aclParseHTTPStatusData(t)) == NULL) continue; - *Top = (*Top)->insert(q, acl_httpstatus_data::compare); + (*curlist)->insert(q, acl_httpstatus_data::compare); } } @@ -134,15 +138,13 @@ } int -aclMatchHTTPStatus(SplayNode **dataptr, const Http::StatusCode status) +aclMatchHTTPStatus(Splay **dataptr, const Http::StatusCode status) { - acl_httpstatus_data X(status); - SplayNode **Top = dataptr; - *Top = Top[0]->splay(&X, aclHTTPStatusCompare); + const acl_httpstatus_data * const * result = (*dataptr)->find(&X, aclHTTPStatusCompare); - debugs(28, 3, "aclMatchHTTPStatus: '" << status << "' " << (splayLastResult ? "NOT found" : "found")); - return (0 == splayLastResult); + debugs(28, 3, "aclMatchHTTPStatus: '" << status << "' " << (result ? "found" : "NOT found")); + return (result != NULL); } static int @@ -157,18 +159,18 @@ return 0; } -static void -aclDumpHTTPStatusListWalkee(acl_httpstatus_data * const &node, void *state) -{ - // state is a SBufList* - static_cast(state)->push_back(node->toStr()); -} +struct HttpStatusAclDumpVisitor { + SBufList contents; + void operator() (const acl_httpstatus_data * node) { + contents.push_back(node->toStr()); + } +}; SBufList ACLHTTPStatus::dump() const { - SBufList w; - data->walk(aclDumpHTTPStatusListWalkee, &w); - return w; + HttpStatusAclDumpVisitor visitor; + data->visit(visitor); + return visitor.contents; } diff -u -r -N squid-3.5.1/src/acl/HttpStatus.h squid-3.5.2/src/acl/HttpStatus.h --- squid-3.5.1/src/acl/HttpStatus.h 2015-01-13 04:52:01.000000000 -0800 +++ squid-3.5.2/src/acl/HttpStatus.h 2015-02-18 04:17:02.000000000 -0800 @@ -46,7 +46,7 @@ protected: static Prototype RegistryProtoype; static ACLHTTPStatus RegistryEntry_; - SplayNode *data; + Splay *data; char const *class_; }; diff -u -r -N squid-3.5.1/src/acl/Ip.cc squid-3.5.2/src/acl/Ip.cc --- squid-3.5.1/src/acl/Ip.cc 2015-01-13 04:52:01.000000000 -0800 +++ squid-3.5.2/src/acl/Ip.cc 2015-02-18 04:17:02.000000000 -0800 @@ -31,18 +31,6 @@ } /** - * Writes an IP ACL data into a buffer, then copies the buffer into the wordlist given - * - \param ip ACL data structure to display - \param state wordlist structure which is being generated - */ -void -ACLIP::DumpIpListWalkee(acl_ip_data * const & ip, void *state) -{ - static_cast(state)->push_back(ip->toSBuf()); -} - -/** * print/format an acl_ip_data structure for debugging output. * \param buf string buffer to write to @@ -485,6 +473,9 @@ void ACLIP::parse() { + if (data == NULL) + data = new IPSplay(); + flags.parseFlags(); while (char *t = strtokFile()) { @@ -494,7 +485,8 @@ /* pop each result off the list and add it to the data tree individually */ acl_ip_data *next_node = q->next; q->next = NULL; - data = data->insert(q, acl_ip_data::NetworkCompare); + if (!data->find(q,acl_ip_data::NetworkCompare)) + data->insert(q, acl_ip_data::NetworkCompare); q = next_node; } } @@ -502,16 +494,25 @@ ACLIP::~ACLIP() { - if (data) - data->destroy(IPSplay::DefaultFree); + if (data) { + data->destroy(); + delete data; + } } +struct IpAclDumpVisitor { + SBufList contents; + void operator() (acl_ip_data * const & ip) { + contents.push_back(ip->toSBuf()); + } +}; + SBufList ACLIP::dump() const { - SBufList sl; - data->walk(DumpIpListWalkee, &sl); - return sl; + IpAclDumpVisitor visitor; + data->visit(visitor); + return visitor.contents; } bool @@ -534,9 +535,9 @@ ClientAddress.addr2.setEmpty(); ClientAddress.mask.setEmpty(); - data = data->splay(&ClientAddress, aclIpAddrNetworkCompare); - debugs(28, 3, "aclIpMatchIp: '" << clientip << "' " << (splayLastResult ? "NOT found" : "found")); - return !splayLastResult; + const acl_ip_data * const * result = data->find(&ClientAddress, aclIpAddrNetworkCompare); + debugs(28, 3, "aclIpMatchIp: '" << clientip << "' " << (result ? "found" : "NOT found")); + return (result != NULL); } acl_ip_data::acl_ip_data() :addr1(), addr2(), mask(), next (NULL) {} diff -u -r -N squid-3.5.1/src/acl/Ip.h squid-3.5.2/src/acl/Ip.h --- squid-3.5.1/src/acl/Ip.h 2015-01-13 04:52:01.000000000 -0800 +++ squid-3.5.2/src/acl/Ip.h 2015-02-18 04:17:02.000000000 -0800 @@ -57,7 +57,7 @@ ~ACLIP(); - typedef SplayNode IPSplay; + typedef Splay IPSplay; virtual char const *typeString() const = 0; virtual void parse(); @@ -71,8 +71,6 @@ int match(Ip::Address &); IPSplay *data; -private: - static void DumpIpListWalkee(acl_ip_data * const & ip, void *state); }; #endif /* SQUID_ACLIP_H */ diff -u -r -N squid-3.5.1/src/acl/NoteData.cc squid-3.5.2/src/acl/NoteData.cc --- squid-3.5.1/src/acl/NoteData.cc 2015-01-13 04:52:01.000000000 -0800 +++ squid-3.5.2/src/acl/NoteData.cc 2015-02-18 04:17:02.000000000 -0800 @@ -64,9 +64,13 @@ { SBufList sl; sl.push_back(SBuf(name)); +#if __cplusplus >= 201103L + sl.splice(sl.end(), values->dump()); +#else // temp is needed until c++11 move constructor SBufList temp = values->dump(); sl.splice(sl.end(), temp); +#endif return sl; } diff -u -r -N squid-3.5.1/src/acl/StringData.cc squid-3.5.2/src/acl/StringData.cc --- squid-3.5.1/src/acl/StringData.cc 2015-01-13 04:52:01.000000000 -0800 +++ squid-3.5.2/src/acl/StringData.cc 2015-02-18 04:17:02.000000000 -0800 @@ -14,70 +14,36 @@ #include "cache_cf.h" #include "Debug.h" -ACLStringData::ACLStringData() : values (NULL) -{} - -ACLStringData::ACLStringData(ACLStringData const &old) : values (NULL) -{ - assert (!old.values); -} - -template -inline void -xRefFree(T &thing) +ACLStringData::ACLStringData(ACLStringData const &old) : stringValues(old.stringValues) { - xfree (thing); -} - -ACLStringData::~ACLStringData() -{ - if (values) - values->destroy(xRefFree); -} - -static int -splaystrcmp (char * const &l, char * const &r) -{ - return strcmp (l,r); } void ACLStringData::insert(const char *value) { - values = values->insert(xstrdup(value), splaystrcmp); + stringValues.insert(SBuf(value)); } bool ACLStringData::match(char const *toFind) { - if (!values || !toFind) + if (stringValues.empty() || !toFind) return 0; - debugs(28, 3, "aclMatchStringList: checking '" << toFind << "'"); + SBuf tf(toFind); + debugs(28, 3, "aclMatchStringList: checking '" << tf << "'"); - values = values->splay((char *)toFind, splaystrcmp); + bool found = (stringValues.find(tf) != stringValues.end()); + debugs(28, 3, "aclMatchStringList: '" << tf << "' " << (found ? "found" : "NOT found")); - debugs(28, 3, "aclMatchStringList: '" << toFind << "' " << (splayLastResult ? "NOT found" : "found")); - - return !splayLastResult; -} - -static void -aclDumpStringWalkee(char * const & node_data, void *outlist) -{ - /* outlist is really a SBufList* */ - static_cast(outlist)->push_back(SBuf(node_data)); + return found; } SBufList ACLStringData::dump() const { SBufList sl; - /* damn this is VERY inefficient for long ACL lists... filling - * a SBufList this way costs Sum(1,N) iterations. For instance - * a 1000-elements list will be filled in 499500 iterations. - */ - values->walk(aclDumpStringWalkee, &sl); + sl.insert(sl.end(), stringValues.begin(), stringValues.end()); return sl; } @@ -85,22 +51,20 @@ ACLStringData::parse() { char *t; - while ((t = strtokFile())) - values = values->insert(xstrdup(t), splaystrcmp); + stringValues.insert(SBuf(t)); } bool ACLStringData::empty() const { - return values->empty(); + return stringValues.empty(); } ACLData * ACLStringData::clone() const { /* Splay trees don't clone yet. */ - assert (!values); return new ACLStringData(*this); } diff -u -r -N squid-3.5.1/src/acl/StringData.h squid-3.5.2/src/acl/StringData.h --- squid-3.5.1/src/acl/StringData.h 2015-01-13 04:52:01.000000000 -0800 +++ squid-3.5.2/src/acl/StringData.h 2015-02-18 04:17:02.000000000 -0800 @@ -10,7 +10,9 @@ #define SQUID_ACLSTRINGDATA_H #include "acl/Acl.h" #include "acl/Data.h" -#include "splay.h" +#include "SBuf.h" + +#include class ACLStringData : public ACLData { @@ -18,10 +20,10 @@ public: MEMPROXY_CLASS(ACLStringData); - ACLStringData(); + ACLStringData() {} ACLStringData(ACLStringData const &); ACLStringData &operator= (ACLStringData const &); - virtual ~ACLStringData(); + virtual ~ACLStringData() {} bool match(char const *); virtual SBufList dump() const; virtual void parse(); @@ -30,7 +32,9 @@ /// Insert a string data value void insert(const char *); - SplayNode *values; +private: + typedef std::set StringValues_t; + StringValues_t stringValues; }; /* TODO move into .cci files */ diff -u -r -N squid-3.5.1/src/acl/UserData.cc squid-3.5.2/src/acl/UserData.cc --- squid-3.5.1/src/acl/UserData.cc 2015-01-13 04:52:01.000000000 -0800 +++ squid-3.5.2/src/acl/UserData.cc 2015-02-18 04:17:02.000000000 -0800 @@ -13,39 +13,13 @@ #include "acl/UserData.h" #include "ConfigParser.h" #include "Debug.h" - -template -inline void -xRefFree(T &thing) -{ - xfree (thing); -} - -ACLUserData::~ACLUserData() -{ - if (names) - names->destroy(xRefFree); -} - -static int -splaystrcasecmp (char * const &l, char * const &r) -{ - return strcasecmp ((char *)l,(char *)r); -} - -static int -splaystrcmp (char * const &l, char * const &r) -{ - return strcmp ((char *)l,(char *)r); -} +#include "globals.h" +#include "SBufAlgos.h" bool ACLUserData::match(char const *user) { - SplayNode *Top = names; - - debugs(28, 7, "aclMatchUser: user is " << user << ", case_insensitive is " << flags.case_insensitive); - debugs(28, 8, "Top is " << Top << ", Top->data is " << ((char *) (Top != NULL ? (Top)->data : "Unavailable"))); + debugs(28, 7, "user is " << user << ", case_insensitive is " << flags.case_insensitive); if (user == NULL || strcmp(user, "-") == 0) return 0; @@ -55,25 +29,9 @@ return 1; } - if (flags.case_insensitive) - Top = Top->splay((char *)user, splaystrcasecmp); - else - Top = Top->splay((char *)user, splaystrcmp); - - /* Top=splay_splay(user,Top,(splayNode::SPLAYCMP *)dumping_strcmp); */ - debugs(28, 7, "aclMatchUser: returning " << !splayLastResult << ",Top is " << - Top << ", Top->data is " << ((char *) (Top ? Top->data : "Unavailable"))); - - names = Top; - - return !splayLastResult; -} - -static void -aclDumpUserListWalkee(char * const & node_data, void *outlist) -{ - /* outlist is really a SBufList* */ - static_cast(outlist)->push_back(SBuf(node_data)); + bool result = (userDataNames.find(SBuf(user)) != userDataNames.end()); + debugs(28, 7, "returning " << result); + return result; } SBufList @@ -89,65 +47,94 @@ if (flags.case_insensitive) sl.push_back(SBuf("-i")); - /* damn this is VERY inefficient for long ACL lists... filling - * a SBufList this way costs Sum(1,N) iterations. For instance - * a 1000-elements list will be filled in 499500 iterations. - */ - if (names) - names->walk(aclDumpUserListWalkee, &sl); + sl.insert(sl.end(), userDataNames.begin(), userDataNames.end()); + debugs(28,5, "ACLUserData dump output: " << SBufContainerJoin(userDataNames,SBuf(" "))); return sl; } +static bool +CaseInsensitveSBufCompare(const SBuf &lhs, const SBuf &rhs) +{ + return (lhs.caseCmp(rhs) < 0); +} + +static bool +CaseSensitveSBufCompare(const SBuf &lhs, const SBuf &rhs) +{ + return (lhs < rhs); +} + +ACLUserData::ACLUserData() : userDataNames(CaseSensitveSBufCompare) +{ +} + void ACLUserData::parse() { - debugs(28, 2, "aclParseUserList: parsing user list"); - char *t = NULL; + debugs(28, 2, "parsing user list"); + char *t = NULL; if ((t = ConfigParser::strtokFile())) { - debugs(28, 5, "aclParseUserList: First token is " << t); + SBuf s(t); + debugs(28, 5, "first token is " << s); - if (strcmp("-i", t) == 0) { - debugs(28, 5, "aclParseUserList: Going case-insensitive"); + if (s.cmp("-i",2) == 0) { + debugs(28, 5, "Going case-insensitive"); flags.case_insensitive = true; - } else if (strcmp("REQUIRED", t) == 0) { - debugs(28, 5, "aclParseUserList: REQUIRED-type enabled"); + // due to how the std::set API work, if we want to change + // the comparison function we have to create a new std::set + UserDataNames_t newUdn(CaseInsensitveSBufCompare); + newUdn.insert(userDataNames.begin(), userDataNames.end()); + swap(userDataNames,newUdn); + } else if (s.cmp("REQUIRED") == 0) { + debugs(28, 5, "REQUIRED-type enabled"); flags.required = true; } else { if (flags.case_insensitive) - Tolower(t); + s.toLower(); - names = names->insert(xstrdup(t), splaystrcmp); + debugs(28, 6, "Adding user " << s); + userDataNames.insert(s); } } - debugs(28, 3, "aclParseUserList: Case-insensitive-switch is " << flags.case_insensitive); + debugs(28, 3, "Case-insensitive-switch is " << flags.case_insensitive); /* we might inherit from a previous declaration */ - debugs(28, 4, "aclParseUserList: parsing user list"); + debugs(28, 4, "parsing following tokens"); while ((t = ConfigParser::strtokFile())) { - debugs(28, 6, "aclParseUserList: Got token: " << t); + SBuf s(t); + debugs(28, 6, "Got token: " << s); if (flags.case_insensitive) - Tolower(t); + s.toLower(); + + debugs(28, 6, "Adding user " << s); + userDataNames.insert(s); + } - names = names->insert(xstrdup(t), splaystrcmp); + if (flags.required && !userDataNames.empty()) { + debugs(28, DBG_PARSE_NOTE(1), "WARNING: detected attempt to add usernames to an acl of type REQUIRED"); + userDataNames.clear(); } + + debugs(28,4, "ACL contains " << userDataNames.size() << " users"); } bool ACLUserData::empty() const { - return names->empty() && !flags.required; + debugs(28,6,"required: " << flags.required << ", number of users: " << userDataNames.size()); + if (flags.required) + return false; + return userDataNames.empty(); } ACLData * ACLUserData::clone() const { - /* Splay trees don't clone yet. */ - assert (!names); return new ACLUserData; } diff -u -r -N squid-3.5.1/src/acl/UserData.h squid-3.5.2/src/acl/UserData.h --- squid-3.5.1/src/acl/UserData.h 2015-01-13 04:52:01.000000000 -0800 +++ squid-3.5.2/src/acl/UserData.h 2015-02-18 04:17:02.000000000 -0800 @@ -10,7 +10,9 @@ #define SQUID_ACLUSERDATA_H #include "acl/Acl.h" #include "acl/Data.h" -#include "splay.h" +#include "SBuf.h" + +#include class ACLUserData : public ACLData { @@ -18,19 +20,24 @@ public: MEMPROXY_CLASS(ACLUserData); - virtual ~ACLUserData(); + virtual ~ACLUserData() {} + ACLUserData(); bool match(char const *user); virtual SBufList dump() const; void parse(); bool empty() const; virtual ACLData *clone() const; - SplayNode *names; +private: + + typedef std::set UserDataNames_t; + UserDataNames_t userDataNames; struct { bool case_insensitive; bool required; } flags; + }; MEMPROXY_CLASS_INLINE(ACLUserData); diff -u -r -N squid-3.5.1/src/anyp/PortCfg.cc squid-3.5.2/src/anyp/PortCfg.cc --- squid-3.5.1/src/anyp/PortCfg.cc 2015-01-13 04:52:01.000000000 -0800 +++ squid-3.5.2/src/anyp/PortCfg.cc 2015-02-18 04:17:02.000000000 -0800 @@ -119,22 +119,34 @@ b->disable_pmtu_discovery = disable_pmtu_discovery; b->tcp_keepalive = tcp_keepalive; -#if 0 - // TODO: AYJ: 2009-07-18: for now SSL does not clone. Configure separate ports with IPs and SSL settings - #if USE_OPENSSL - char *cert; - char *key; - int version; - char *cipher; - char *options; - char *clientca; - char *cafile; - char *capath; - char *crlfile; - char *dhfile; - char *sslflags; - char *sslContextSessionId; + if (cert) + b->cert = xstrdup(cert); + if (key) + b->key = xstrdup(key); + b->version = version; + if (cipher) + b->cipher = xstrdup(cipher); + if (options) + b->options = xstrdup(options); + if (clientca) + b->clientca = xstrdup(clientca); + if (cafile) + b->cafile = xstrdup(cafile); + if (capath) + b->capath = xstrdup(capath); + if (crlfile) + b->crlfile = xstrdup(crlfile); + if (dhfile) + b->dhfile = xstrdup(dhfile); + if (sslflags) + b->sslflags = xstrdup(sslflags); + if (sslContextSessionId) + b->sslContextSessionId = xstrdup(sslContextSessionId); + +#if 0 + // TODO: AYJ: 2015-01-15: for now SSL does not clone the context object. + // cloning should only be done before the PortCfg is post-configure initialized and opened SSL_CTX *sslContext; #endif diff -u -r -N squid-3.5.1/src/auth/digest/Config.cc squid-3.5.2/src/auth/digest/Config.cc --- squid-3.5.1/src/auth/digest/Config.cc 2015-01-13 04:52:01.000000000 -0800 +++ squid-3.5.2/src/auth/digest/Config.cc 2015-02-18 04:17:02.000000000 -0800 @@ -1006,12 +1006,7 @@ debugs(29, 2, "Username for the nonce does not equal the username for the request"); nonce = NULL; } - /* check for stale nonce */ - if (authDigestNonceIsStale(nonce)) { - debugs(29, 3, "The received nonce is stale from " << username); - digest_request->setDenyMessage("Stale nonce"); - nonce = NULL; - } + if (!nonce) { /* we couldn't find a matching nonce! */ debugs(29, 2, "Unexpected or invalid nonce received from " << username); diff -u -r -N squid-3.5.1/src/auth/digest/UserRequest.cc squid-3.5.2/src/auth/digest/UserRequest.cc --- squid-3.5.1/src/auth/digest/UserRequest.cc 2015-01-13 04:52:01.000000000 -0800 +++ squid-3.5.2/src/auth/digest/UserRequest.cc 2015-02-18 04:17:02.000000000 -0800 @@ -173,10 +173,14 @@ } /* check for stale nonce */ - if (!authDigestNonceIsValid(digest_request->nonce, digest_request->nc)) { - debugs(29, 3, "user '" << auth_user->username() << "' validated OK but nonce stale"); - auth_user->credentials(Auth::Handshake); - digest_request->setDenyMessage("Stale nonce"); + /* check Auth::Pending to avoid loop */ + + if (!authDigestNonceIsValid(digest_request->nonce, digest_request->nc) && user()->credentials() != Auth::Pending) { + debugs(29, 3, auth_user->username() << "' validated OK but nonce stale: " << digest_request->nonceb64); + /* Pending prevent banner and makes a ldap control */ + auth_user->credentials(Auth::Pending); + nonce->flags.valid = false; + authDigestNoncePurge(nonce); return; } @@ -329,6 +333,8 @@ // add new helper kv-pair notes to the credentials object // so that any transaction using those credentials can access them auth_user_request->user()->notes.appendNewOnly(&reply.notes); + // remove any private credentials detail which got added. + auth_user_request->user()->notes.remove("ha1"); static bool oldHelperWarningDone = false; switch (reply.result) { diff -u -r -N squid-3.5.1/src/auth/negotiate/Config.cc squid-3.5.2/src/auth/negotiate/Config.cc --- squid-3.5.1/src/auth/negotiate/Config.cc 2015-01-13 04:52:01.000000000 -0800 +++ squid-3.5.2/src/auth/negotiate/Config.cc 2015-02-18 04:17:02.000000000 -0800 @@ -261,6 +261,8 @@ auth_user_request->user(newUser); auth_user_request->user()->auth_type = Auth::AUTH_NEGOTIATE; + auth_user_request->user()->BuildUserKey(proxy_auth, aRequestRealm); + /* all we have to do is identify that it's Negotiate - the helper does the rest */ debugs(29, 9, HERE << "decode Negotiate authentication"); return auth_user_request; diff -u -r -N squid-3.5.1/src/auth/negotiate/UserRequest.cc squid-3.5.2/src/auth/negotiate/UserRequest.cc --- squid-3.5.1/src/auth/negotiate/UserRequest.cc 2015-01-13 04:52:01.000000000 -0800 +++ squid-3.5.2/src/auth/negotiate/UserRequest.cc 2015-02-18 04:17:02.000000000 -0800 @@ -163,8 +163,6 @@ void Auth::Negotiate::UserRequest::authenticate(HttpRequest * aRequest, ConnStateData * conn, http_hdr_type type) { - assert(this); - /* Check that we are in the client side, where we can generate * auth challenges */ @@ -260,6 +258,8 @@ // add new helper kv-pair notes to the credentials object // so that any transaction using those credentials can access them auth_user_request->user()->notes.appendNewOnly(&reply.notes); + // remove any private credentials detail which got added. + auth_user_request->user()->notes.remove("token"); Auth::Negotiate::UserRequest *lm_request = dynamic_cast(auth_user_request.getRaw()); assert(lm_request != NULL); @@ -312,8 +312,7 @@ /* connection is authenticated */ debugs(29, 4, HERE << "authenticated user " << auth_user_request->user()->username()); - /* see if this is an existing user with a different proxy_auth - * string */ + /* see if this is an existing user */ AuthUserHashPointer *usernamehash = static_cast(hash_lookup(proxy_auth_username_cache, auth_user_request->user()->userKey())); Auth::User::Pointer local_auth_user = lm_request->user(); while (usernamehash && (usernamehash->user()->auth_type != Auth::AUTH_NEGOTIATE || @@ -390,22 +389,3 @@ delete r; } -void -Auth::Negotiate::UserRequest::addAuthenticationInfoHeader(HttpReply * rep, int accel) -{ - http_hdr_type type; - - if (!server_blob) - return; - - /* don't add to authentication error pages */ - if ((!accel && rep->sline.status() == Http::scProxyAuthenticationRequired) - || (accel && rep->sline.status() == Http::scUnauthorized)) - return; - - type = accel ? HDR_AUTHENTICATION_INFO : HDR_PROXY_AUTHENTICATION_INFO; - httpHeaderPutStrf(&rep->header, type, "Negotiate %s", server_blob); - - safe_free(server_blob); -} - diff -u -r -N squid-3.5.1/src/auth/negotiate/UserRequest.h squid-3.5.2/src/auth/negotiate/UserRequest.h --- squid-3.5.1/src/auth/negotiate/UserRequest.h 2015-01-13 04:52:01.000000000 -0800 +++ squid-3.5.2/src/auth/negotiate/UserRequest.h 2015-02-18 04:17:02.000000000 -0800 @@ -37,8 +37,6 @@ virtual void startHelperLookup(HttpRequest *request, AccessLogEntry::Pointer &al, AUTHCB *, void *); virtual const char *credentialsStr(); - virtual void addAuthenticationInfoHeader(HttpReply * rep, int accel); - virtual const char * connLastHeader(); /* we need to store the helper server between requests */ diff -u -r -N squid-3.5.1/src/auth/ntlm/Config.cc squid-3.5.2/src/auth/ntlm/Config.cc --- squid-3.5.1/src/auth/ntlm/Config.cc 2015-01-13 04:52:01.000000000 -0800 +++ squid-3.5.2/src/auth/ntlm/Config.cc 2015-02-18 04:17:02.000000000 -0800 @@ -241,6 +241,8 @@ auth_user_request->user(newUser); auth_user_request->user()->auth_type = Auth::AUTH_NTLM; + auth_user_request->user()->BuildUserKey(proxy_auth, aRequestRealm); + /* all we have to do is identify that it's NTLM - the helper does the rest */ debugs(29, 9, HERE << "decode: NTLM authentication"); return auth_user_request; diff -u -r -N squid-3.5.1/src/auth/ntlm/UserRequest.cc squid-3.5.2/src/auth/ntlm/UserRequest.cc --- squid-3.5.1/src/auth/ntlm/UserRequest.cc 2015-01-13 04:52:01.000000000 -0800 +++ squid-3.5.2/src/auth/ntlm/UserRequest.cc 2015-02-18 04:17:02.000000000 -0800 @@ -157,8 +157,6 @@ void Auth::Ntlm::UserRequest::authenticate(HttpRequest * aRequest, ConnStateData * conn, http_hdr_type type) { - assert(this); - /* Check that we are in the client side, where we can generate * auth challenges */ @@ -255,6 +253,8 @@ // add new helper kv-pair notes to the credentials object // so that any transaction using those credentials can access them auth_user_request->user()->notes.appendNewOnly(&reply.notes); + // remove any private credentials detail which got added. + auth_user_request->user()->notes.remove("token"); Auth::Ntlm::UserRequest *lm_request = dynamic_cast(auth_user_request.getRaw()); assert(lm_request != NULL); @@ -306,8 +306,7 @@ debugs(29, 4, HERE << "Successfully validated user via NTLM. Username '" << userLabel << "'"); /* connection is authenticated */ debugs(29, 4, HERE << "authenticated user " << auth_user_request->user()->username()); - /* see if this is an existing user with a different proxy_auth - * string */ + /* see if this is an existing user */ AuthUserHashPointer *usernamehash = static_cast(hash_lookup(proxy_auth_username_cache, auth_user_request->user()->userKey())); Auth::User::Pointer local_auth_user = lm_request->user(); while (usernamehash && (usernamehash->user()->auth_type != Auth::AUTH_NTLM || diff -u -r -N squid-3.5.1/src/auth/User.cc squid-3.5.2/src/auth/User.cc --- squid-3.5.1/src/auth/User.cc 2015-01-13 04:52:01.000000000 -0800 +++ squid-3.5.2/src/auth/User.cc 2015-02-18 04:17:02.000000000 -0800 @@ -309,7 +309,10 @@ Auth::User::BuildUserKey(const char *username, const char *realm) { SBuf key; - key.Printf("%s:%s", username, realm); + if (realm) + key.Printf("%s:%s", username, realm); + else + key.append(username, strlen(username)); return key; } @@ -365,10 +368,11 @@ if (aString) { assert(!username_); username_ = xstrdup(aString); - if (!requestRealm_.isEmpty()) - userKey_ = BuildUserKey(username_, requestRealm_.c_str()); + // NP: param #2 is working around a c_str() data-copy performance regression + userKey_ = BuildUserKey(username_, (!requestRealm_.isEmpty() ? requestRealm_.c_str() : NULL)); } else { safe_free(username_); + userKey_.clear(); } } diff -u -r -N squid-3.5.1/src/auth/User.h squid-3.5.2/src/auth/User.h --- squid-3.5.1/src/auth/User.h 2015-01-13 04:52:01.000000000 -0800 +++ squid-3.5.2/src/auth/User.h 2015-02-18 04:17:02.000000000 -0800 @@ -63,9 +63,10 @@ void absorb(Auth::User::Pointer from); virtual ~User(); char const *username() const { return username_; } - void username(char const *); + void username(char const *); ///< set stored username and userKey - const char *userKey() {return !userKey_.isEmpty() ? userKey_.c_str() : username_;} + // NP: key is set at the same time as username_. Until then both are empty/NULL. + const char *userKey() {return !userKey_.isEmpty() ? userKey_.c_str() : NULL;} /** * How long these credentials are still valid for. diff -u -r -N squid-3.5.1/src/auth/UserRequest.cc squid-3.5.2/src/auth/UserRequest.cc --- squid-3.5.1/src/auth/UserRequest.cc 2015-01-13 04:52:01.000000000 -0800 +++ squid-3.5.2/src/auth/UserRequest.cc 2015-02-18 04:17:02.000000000 -0800 @@ -124,9 +124,8 @@ char const * Auth::UserRequest::denyMessage(char const * const default_message) { - if (this == NULL || getDenyMessage() == NULL) { + if (getDenyMessage() == NULL) return default_message; - } return getDenyMessage(); } diff -u -r -N squid-3.5.1/src/cache_cf.cc squid-3.5.2/src/cache_cf.cc --- squid-3.5.1/src/cache_cf.cc 2015-01-13 04:52:01.000000000 -0800 +++ squid-3.5.2/src/cache_cf.cc 2015-02-18 04:17:02.000000000 -0800 @@ -881,7 +881,10 @@ debugs(3, DBG_IMPORTANT, "Initializing https proxy context"); - Config.ssl_client.sslContext = sslCreateClientContext(Config.ssl_client.cert, Config.ssl_client.key, Config.ssl_client.version, Config.ssl_client.cipher, Config.ssl_client.options, Config.ssl_client.flags, Config.ssl_client.cafile, Config.ssl_client.capath, Config.ssl_client.crlfile); + Config.ssl_client.sslContext = sslCreateClientContext(Config.ssl_client.cert, Config.ssl_client.key, Config.ssl_client.version, Config.ssl_client.cipher, NULL, Config.ssl_client.flags, Config.ssl_client.cafile, Config.ssl_client.capath, Config.ssl_client.crlfile); + // Pre-parse SSL client options to be applied when the client SSL objects created. + // Options must not used in the case of peek or stare bump mode. + Config.ssl_client.parsedOptions = Ssl::parse_options(::Config.ssl_client.options); for (CachePeer *p = Config.peers; p != NULL; p = p->next) { if (p->use_ssl) { diff -u -r -N squid-3.5.1/src/cbdata.cc squid-3.5.2/src/cbdata.cc --- squid-3.5.1/src/cbdata.cc 2015-01-13 04:52:01.000000000 -0800 +++ squid-3.5.2/src/cbdata.cc 2015-02-18 04:17:02.000000000 -0800 @@ -439,7 +439,7 @@ if (c->valid) { #if USE_CBDATA_DEBUG - debugs(45, DBG_IMPORTANT, "CBDATA memory leak. cbdata=" << p << " " << file << ":" << line); + debugs(45, 3, "CBDATA valid with no references ... cbdata=" << p << " " << file << ":" << line); #endif return; } diff -u -r -N squid-3.5.1/src/cbdata.h squid-3.5.2/src/cbdata.h --- squid-3.5.1/src/cbdata.h 2015-01-13 04:52:01.000000000 -0800 +++ squid-3.5.2/src/cbdata.h 2015-02-18 04:17:02.000000000 -0800 @@ -426,6 +426,7 @@ delete this; } +private: /** * The wrapped data - only public to allow the mild abuse of this facility * done by store_swapout - it gives a wrapped StoreEntry to StoreIO as the diff -u -r -N squid-3.5.1/src/cf.data.pre squid-3.5.2/src/cf.data.pre --- squid-3.5.1/src/cf.data.pre 2015-01-13 04:52:01.000000000 -0800 +++ squid-3.5.2/src/cf.data.pre 2015-02-18 04:17:02.000000000 -0800 @@ -155,6 +155,7 @@ Remove this line. Use always_direct or cache_peer_access ACLs instead if you need to prevent cache_peer use. DOC_END +# Options removed in 3.4 NAME: log_access TYPE: obsolete DOC_START @@ -175,6 +176,12 @@ DOC_END # Options Removed in 3.2 +NAME: chunked_request_body_max_size +TYPE: obsolete +DOC_START + Remove this line. Squid is now HTTP/1.1 compliant. +DOC_END + NAME: dns_v4_fallback TYPE: obsolete DOC_START @@ -1753,6 +1760,7 @@ NO_TLSv1_2 Disallow the use of TLSv1.2 SINGLE_DH_USE Always create a new key when using temporary/ephemeral DH key exchanges + NO_TICKET Disables TLS tickets extension ALL Enable various bug workarounds suggested as "harmless" by OpenSSL Be warned that this reduces SSL/TLS @@ -5552,33 +5560,6 @@ a large file. DOC_END -NAME: chunked_request_body_max_size -COMMENT: (bytes) -TYPE: b_int64_t -DEFAULT: 64 KB -LOC: Config.maxChunkedRequestBodySize -DOC_START - A broken or confused HTTP/1.1 client may send a chunked HTTP - request to Squid. Squid does not have full support for that - feature yet. To cope with such requests, Squid buffers the - entire request and then dechunks request body to create a - plain HTTP/1.0 request with a known content length. The plain - request is then used by the rest of Squid code as usual. - - The option value specifies the maximum size of the buffer used - to hold the request before the conversion. If the chunked - request size exceeds the specified limit, the conversion - fails, and the client receives an "unsupported request" error, - as if dechunking was disabled. - - Dechunking is enabled by default. To disable conversion of - chunked requests, set the maximum to zero. - - Request dechunking feature and this option in particular are a - temporary hack. When chunking requests and responses are fully - supported, there will be no need to buffer a chunked request. -DOC_END - NAME: broken_posts IFDEF: USE_HTTP_VIOLATIONS TYPE: acl_access diff -u -r -N squid-3.5.1/src/client_side.cc squid-3.5.2/src/client_side.cc --- squid-3.5.1/src/client_side.cc 2015-01-13 04:52:01.000000000 -0800 +++ squid-3.5.2/src/client_side.cc 2015-02-18 04:17:02.000000000 -0800 @@ -621,15 +621,16 @@ #endif - /*Add notes*/ - // The al->notes and request->notes must point to the same object. - (void)SyncNotes(*al, *request); - typedef Notes::iterator ACAMLI; - for (ACAMLI i = Config.notes.begin(); i != Config.notes.end(); ++i) { - if (const char *value = (*i)->match(request, al->reply, NULL)) { - NotePairs ¬es = SyncNotes(*al, *request); - notes.add((*i)->key.termedBuf(), value); - debugs(33, 3, HERE << (*i)->key.termedBuf() << " " << value); + /* Add notes (if we have a request to annotate) */ + if (request) { + // The al->notes and request->notes must point to the same object. + (void)SyncNotes(*al, *request); + for (Notes::iterator i = Config.notes.begin(); i != Config.notes.end(); ++i) { + if (const char *value = (*i)->match(request, al->reply, NULL)) { + NotePairs ¬es = SyncNotes(*al, *request); + notes.add((*i)->key.termedBuf(), value); + debugs(33, 3, (*i)->key.termedBuf() << " " << value); + } } } @@ -688,7 +689,6 @@ bool ConnStateData::areAllContextsForThisConnection() const { - assert(this != NULL); ClientSocketContext::Pointer context = getCurrentContext(); while (context.getRaw()) { @@ -844,7 +844,6 @@ ConnStateData::~ConnStateData() { - assert(this != NULL); debugs(33, 3, HERE << clientConnection); if (isOpen()) @@ -924,7 +923,6 @@ ClientSocketContext::Pointer ConnStateData::getCurrentContext() const { - assert(this); return currentobject; } @@ -1255,7 +1253,6 @@ String ClientHttpRequest::rangeBoundaryStr() const { - assert(this); const char *key; String b(APP_FULLNAME); b.append(":",1); diff -u -r -N squid-3.5.1/src/comm/Read.cc squid-3.5.2/src/comm/Read.cc --- squid-3.5.1/src/comm/Read.cc 2015-01-13 04:52:01.000000000 -0800 +++ squid-3.5.2/src/comm/Read.cc 2015-02-18 04:17:02.000000000 -0800 @@ -28,7 +28,7 @@ bool Comm::MonitorsRead(int fd) { - assert(isOpen(fd) && COMMIO_FD_READCB(fd)); + assert(isOpen(fd) && COMMIO_FD_READCB(fd) != NULL); // Being active is usually the same as monitoring because we always // start monitoring the FD when we configure Comm::IoCallback for I/O // and we usually configure Comm::IoCallback for I/O when we starting diff -u -r -N squid-3.5.1/src/comm.cc squid-3.5.2/src/comm.cc --- squid-3.5.1/src/comm.cc 2015-01-13 04:52:01.000000000 -0800 +++ squid-3.5.2/src/comm.cc 2015-02-18 04:17:02.000000000 -0800 @@ -148,7 +148,7 @@ bool comm_has_incomplete_write(int fd) { - assert(isOpen(fd) && COMMIO_FD_WRITECB(fd)); + assert(isOpen(fd) && COMMIO_FD_WRITECB(fd) != NULL); return COMMIO_FD_WRITECB(fd)->active(); } @@ -1082,44 +1082,30 @@ int commSetNonBlocking(int fd) { -#if !_SQUID_WINDOWS_ - int flags; - int dummy = 0; -#endif #if _SQUID_WINDOWS_ int nonblocking = TRUE; -#if _SQUID_CYGWIN_ - if (fd_table[fd].type != FD_PIPE) { -#endif - - if (ioctl(fd, FIONBIO, &nonblocking) < 0) { - debugs(50, 0, "commSetNonBlocking: FD " << fd << ": " << xstrerror() << " " << fd_table[fd].type); - return Comm::COMM_ERROR; - } - -#if _SQUID_CYGWIN_ - } else { -#endif -#endif -#if !_SQUID_WINDOWS_ + if (ioctl(fd, FIONBIO, &nonblocking) < 0) { + debugs(50, 0, "commSetNonBlocking: FD " << fd << ": " << xstrerror() << " " << fd_table[fd].type); + return Comm::COMM_ERROR; + } - if ((flags = fcntl(fd, F_GETFL, dummy)) < 0) { - debugs(50, 0, "FD " << fd << ": fcntl F_GETFL: " << xstrerror()); - return Comm::COMM_ERROR; - } +#else + int flags; + int dummy = 0; - if (fcntl(fd, F_SETFL, flags | SQUID_NONBLOCK) < 0) { - debugs(50, 0, "commSetNonBlocking: FD " << fd << ": " << xstrerror()); - return Comm::COMM_ERROR; - } + if ((flags = fcntl(fd, F_GETFL, dummy)) < 0) { + debugs(50, 0, "FD " << fd << ": fcntl F_GETFL: " << xstrerror()); + return Comm::COMM_ERROR; + } -#endif -#if _SQUID_CYGWIN_ + if (fcntl(fd, F_SETFL, flags | SQUID_NONBLOCK) < 0) { + debugs(50, 0, "commSetNonBlocking: FD " << fd << ": " << xstrerror()); + return Comm::COMM_ERROR; } #endif - fd_table[fd].flags.nonblocking = true; + fd_table[fd].flags.nonblocking = true; return 0; } diff -u -r -N squid-3.5.1/src/DelayTagged.cc squid-3.5.2/src/DelayTagged.cc --- squid-3.5.1/src/DelayTagged.cc 2015-01-13 04:52:01.000000000 -0800 +++ squid-3.5.2/src/DelayTagged.cc 2015-02-18 04:17:02.000000000 -0800 @@ -35,15 +35,15 @@ DelayPools::registerForUpdates (this); } -static SplayNode::SPLAYFREE DelayTaggedFree; +static Splay::SPLAYFREE DelayTaggedFree; DelayTagged::~DelayTagged() { DelayPools::deregisterForUpdates (this); - buckets.head->destroy (DelayTaggedFree); + buckets.destroy(DelayTaggedFree); } -static SplayNode::SPLAYCMP DelayTaggedCmp; +static Splay::SPLAYCMP DelayTaggedCmp; int DelayTaggedCmp(DelayTaggedBucket::Pointer const &left, DelayTaggedBucket::Pointer const &right) @@ -56,11 +56,13 @@ DelayTaggedFree(DelayTaggedBucket::Pointer &) {} -void -DelayTaggedStatsWalkee(DelayTaggedBucket::Pointer const ¤t, void *state) -{ - current->stats ((StoreEntry *)state); -} +struct DelayTaggedStatsVisitor { + StoreEntry *sentry; + explicit DelayTaggedStatsVisitor(StoreEntry *se): sentry(se) {} + void operator() (DelayTaggedBucket::Pointer const ¤t) { + current->stats(sentry); + } +}; void DelayTagged::stats(StoreEntry * sentry) @@ -72,12 +74,13 @@ storeAppendPrintf(sentry, "\t\tCurrent: "); - if (!buckets.head) { + if (buckets.empty()) { storeAppendPrintf (sentry, "Not used yet.\n\n"); return; } - buckets.head->walk(DelayTaggedStatsWalkee, sentry); + DelayTaggedStatsVisitor visitor(sentry); + buckets.visit(visitor); storeAppendPrintf(sentry, "\n\n"); } @@ -102,11 +105,20 @@ const_cast(current.getRaw())->theBucket.update(t->spec, t->incr); } +struct DelayTaggedUpdateVisitor { + DelayTaggedUpdater *updater; + explicit DelayTaggedUpdateVisitor(DelayTaggedUpdater *u) : updater(u) {} + void operator() (DelayTaggedBucket::Pointer const ¤t) { + const_cast(current.getRaw())->theBucket.update(updater->spec, updater->incr); + } +}; + void DelayTagged::update(int incr) { DelayTaggedUpdater updater(spec, incr); - buckets.head->walk (DelayTaggedUpdateWalkee, &updater); + DelayTaggedUpdateVisitor visitor(&updater); + buckets.visit(visitor); kickReads(); } @@ -182,7 +194,7 @@ } theBucket->theBucket.init(theTagged->spec); - theTagged->buckets.head = theTagged->buckets.head->insert (theBucket, DelayTaggedCmp); + theTagged->buckets.insert (theBucket, DelayTaggedCmp); } DelayTagged::Id::~Id() diff -u -r -N squid-3.5.1/src/DelayUser.cc squid-3.5.2/src/DelayUser.cc --- squid-3.5.1/src/DelayUser.cc 2015-01-13 04:52:01.000000000 -0800 +++ squid-3.5.2/src/DelayUser.cc 2015-02-18 04:17:02.000000000 -0800 @@ -37,15 +37,15 @@ DelayPools::registerForUpdates (this); } -static SplayNode::SPLAYFREE DelayUserFree; +static Splay::SPLAYFREE DelayUserFree; DelayUser::~DelayUser() { DelayPools::deregisterForUpdates (this); - buckets.head->destroy (DelayUserFree); + buckets.destroy(DelayUserFree); } -static SplayNode::SPLAYCMP DelayUserCmp; +static Splay::SPLAYCMP DelayUserCmp; int DelayUserCmp(DelayUserBucket::Pointer const &left, DelayUserBucket::Pointer const &right) @@ -68,6 +68,14 @@ current->stats ((StoreEntry *)state); } +struct DelayUserStatsVisitor { + StoreEntry *se; + explicit DelayUserStatsVisitor(StoreEntry *s) : se(s) {} + void operator() (DelayUserBucket::Pointer const ¤t) { + current->stats(se); + } +}; + void DelayUser::stats(StoreEntry * sentry) { @@ -78,12 +86,13 @@ storeAppendPrintf(sentry, "\t\tCurrent: "); - if (!buckets.head) { + if (buckets.empty()) { storeAppendPrintf (sentry, "Not used yet.\n\n"); return; } - buckets.head->walk(DelayUserStatsWalkee, sentry); + DelayUserStatsVisitor visitor(sentry); + buckets.visit(visitor); storeAppendPrintf(sentry, "\n\n"); } @@ -108,11 +117,20 @@ const_cast(current.getRaw())->theBucket.update(t->spec, t->incr); } +struct DelayUserUpdateVisitor { + DelayUserUpdater *t; + DelayUserUpdateVisitor(DelayUserUpdater *updater) : t(updater) {} + void operator() (DelayUserBucket::Pointer const ¤t) { + const_cast(current.getRaw())->theBucket.update(t->spec, t->incr); + } +}; + void DelayUser::update(int incr) { DelayUserUpdater updater(spec, incr); - buckets.head->walk (DelayUserUpdateWalkee, &updater); + DelayUserUpdateVisitor visitor(&updater); + buckets.visit(visitor); } void @@ -188,7 +206,7 @@ } theBucket->theBucket.init(theUser->spec); - theUser->buckets.head = theUser->buckets.head->insert (theBucket, DelayUserCmp); + theUser->buckets.insert (theBucket, DelayUserCmp); } DelayUser::Id::~Id() diff -u -r -N squid-3.5.1/src/dns_internal.cc squid-3.5.2/src/dns_internal.cc --- squid-3.5.1/src/dns_internal.cc 2015-01-13 04:52:01.000000000 -0800 +++ squid-3.5.2/src/dns_internal.cc 2015-02-18 04:17:02.000000000 -0800 @@ -381,7 +381,7 @@ idnsParseResolvConf(void) { bool result = false; -#if !_SQUID_WINDOWS_ || _SQUID_CYGWIN_ +#if !_SQUID_WINDOWS_ FILE *fp = fopen(_PATH_RESCONF, "r"); if (fp == NULL) { @@ -389,10 +389,6 @@ return false; } -#if _SQUID_CYGWIN_ - setmode(fileno(fp), O_TEXT); -#endif - char buf[RESOLV_BUFSZ]; const char *t = NULL; while (fgets(buf, RESOLV_BUFSZ, fp)) { diff -u -r -N squid-3.5.1/src/esi/Esi.cc squid-3.5.2/src/esi/Esi.cc --- squid-3.5.1/src/esi/Esi.cc 2015-01-13 04:52:01.000000000 -0800 +++ squid-3.5.2/src/esi/Esi.cc 2015-02-18 04:17:02.000000000 -0800 @@ -311,8 +311,6 @@ esiKick_t ESIContext::kick () { - assert (this); - if (flags.kicked) { debugs(86, 5, "esiKick: Re-entered whilst in progress"); // return ESI_KICK_INPROGRESS; @@ -1681,7 +1679,6 @@ esiTry::render(ESISegment::Pointer output) { /* Try renders from it's children */ - assert (this); assert (attempt.getRaw()); assert (except.getRaw()); debugs(86, 5, "esiTryRender: Rendering Try " << this); @@ -1749,7 +1746,6 @@ esiTry::process (int dovars) { esiProcessResult_t rv = ESI_PROCESS_PENDING_MAYFAIL; - assert (this); if (!attempt.getRaw()) { debugs(86, DBG_CRITICAL, "esiTryProcess: Try has no attempt element - ESI template is invalid (section 3.4)"); diff -u -r -N squid-3.5.1/src/esi/Include.cc squid-3.5.2/src/esi/Include.cc --- squid-3.5.1/src/esi/Include.cc 2015-01-13 04:52:01.000000000 -0800 +++ squid-3.5.2/src/esi/Include.cc 2015-02-18 04:17:02.000000000 -0800 @@ -198,7 +198,6 @@ /* esiStream functions */ ESIStreamContext::~ESIStreamContext() { - assert (this); freeResources(); } @@ -453,8 +452,6 @@ void ESIInclude::subRequestDone (ESIStreamContext::Pointer stream, bool success) { - assert (this); - if (!dataNeeded()) return; diff -u -r -N squid-3.5.1/src/eui/Eui48.cc squid-3.5.2/src/eui/Eui48.cc --- squid-3.5.1/src/eui/Eui48.cc 2015-01-13 04:52:01.000000000 -0800 +++ squid-3.5.2/src/eui/Eui48.cc 2015-02-18 04:17:02.000000000 -0800 @@ -116,7 +116,7 @@ } bool -Eui::Eui48::encode(char *buf, const int len) +Eui::Eui48::encode(char *buf, const int len) const { if (len < SZ_EUI48_BUF) return false; diff -u -r -N squid-3.5.1/src/eui/Eui48.h squid-3.5.2/src/eui/Eui48.h --- squid-3.5.1/src/eui/Eui48.h 2015-01-13 04:52:01.000000000 -0800 +++ squid-3.5.2/src/eui/Eui48.h 2015-02-18 04:17:02.000000000 -0800 @@ -30,6 +30,8 @@ public: Eui48() { clear(); } Eui48(const Eui48 &t) { memcpy(this, &t, sizeof(Eui48)); } + bool operator== (const Eui48 &t) const { return memcmp(eui, t.eui, SZ_EUI48_BUF) == 0; } + bool operator< (const Eui48 &t) const { return memcmp(eui, t.eui, SZ_EUI48_BUF) < 0; } ~Eui48() {} const unsigned char *get(void); @@ -62,7 +64,7 @@ * \retval false Conversion to ASCII failed. * \retval true Conversion completed successfully. */ - bool encode(char *buf, const int len); + bool encode(char *buf, const int len) const; // lookup an EUI-48 / MAC address via ARP bool lookup(const Ip::Address &c); diff -u -r -N squid-3.5.1/src/eui/Eui64.cc squid-3.5.2/src/eui/Eui64.cc --- squid-3.5.1/src/eui/Eui64.cc 2015-01-13 04:52:01.000000000 -0800 +++ squid-3.5.2/src/eui/Eui64.cc 2015-02-18 04:17:02.000000000 -0800 @@ -31,7 +31,7 @@ } bool -Eui::Eui64::encode(char *buf, const int len) +Eui::Eui64::encode(char *buf, const int len) const { if (len < SZ_EUI64_BUF) return false; diff -u -r -N squid-3.5.1/src/eui/Eui64.h squid-3.5.2/src/eui/Eui64.h --- squid-3.5.1/src/eui/Eui64.h 2015-01-13 04:52:01.000000000 -0800 +++ squid-3.5.2/src/eui/Eui64.h 2015-02-18 04:17:02.000000000 -0800 @@ -37,6 +37,9 @@ public: Eui64() { clear(); } Eui64(const Eui64 &t) { memcpy(this, &t, sizeof(Eui64)); } + Eui64& operator= (const Eui64 &t) {memcpy(this, &t, sizeof(Eui64)); return *this;} + bool operator== (const Eui64 &t) const { return (memcmp(eui,t.eui,SZ_EUI64_BUF) == 0); } + bool operator< (const Eui64 &t) const { return (memcmp(eui,t.eui,SZ_EUI64_BUF) < 0); } ~Eui64() {} const unsigned char *get(void); @@ -69,7 +72,7 @@ * \retval false Conversion to ASCII failed. * \retval true Conversion completed successfully. */ - bool encode(char *buf, const int len); + bool encode(char *buf, const int len) const; // lookup an EUI-64 address via IPv6 SLAAC or NDP bool lookup(const Ip::Address &c); diff -u -r -N squid-3.5.1/src/fs/ufs/RebuildState.cc squid-3.5.2/src/fs/ufs/RebuildState.cc --- squid-3.5.1/src/fs/ufs/RebuildState.cc 2015-01-13 04:52:01.000000000 -0800 +++ squid-3.5.2/src/fs/ufs/RebuildState.cc 2015-02-18 04:17:02.000000000 -0800 @@ -130,7 +130,6 @@ struct stat sb; int fd = -1; - assert(this != NULL); debugs(47, 3, HERE << "DIR #" << sd->index); assert(fd == -1); diff -u -r -N squid-3.5.1/src/htcp.cc squid-3.5.2/src/htcp.cc --- squid-3.5.1/src/htcp.cc 2015-01-13 04:52:01.000000000 -0800 +++ squid-3.5.2/src/htcp.cc 2015-02-18 04:17:02.000000000 -0800 @@ -47,8 +47,6 @@ typedef struct _htcpAuthHeader htcpAuthHeader; -typedef struct _htcpStuff htcpStuff; - typedef struct _htcpDetail htcpDetail; struct _Countstr { @@ -139,6 +137,17 @@ public: MEMPROXY_CLASS(htcpSpecifier); + htcpSpecifier() : + method(NULL), + uri(NULL), + version(NULL), + req_hdrs(NULL), + request(NULL), + checkHitRequest(NULL), + dhdr(NULL) + {} + // XXX: destructor? + void created (StoreEntry *newEntry); void checkHit(); void checkedHit(StoreEntry *e); @@ -166,7 +175,20 @@ char *cache_hdrs; }; -struct _htcpStuff { +class htcpStuff +{ +public: + htcpStuff(uint32_t id, int o, int r, int f) : + op(o), + rr(r), + f1(f), + response(0), + reason(0), + msg_id(id) + { + memset(&D, 0, sizeof(D)); + } + int op; int rr; int f1; @@ -834,19 +856,15 @@ static void htcpTstReply(htcpDataHeader * dhdr, StoreEntry * e, htcpSpecifier * spec, Ip::Address &from) { - htcpStuff stuff; static char pkt[8192]; HttpHeader hdr(hoHtcpReply); MemBuf mb; Packer p; ssize_t pktlen; - memset(&stuff, '\0', sizeof(stuff)); - stuff.op = HTCP_TST; - stuff.rr = RR_RESPONSE; - stuff.f1 = 0; + + htcpStuff stuff(dhdr->msg_id, HTCP_TST, RR_RESPONSE, 0); stuff.response = e ? 0 : 1; debugs(31, 3, "htcpTstReply: response = " << stuff.response); - stuff.msg_id = dhdr->msg_id; if (spec) { mb.init(); @@ -923,7 +941,6 @@ htcpClrReply(htcpDataHeader * dhdr, int purgeSucceeded, Ip::Address &from) { - htcpStuff stuff; static char pkt[8192]; ssize_t pktlen; @@ -932,20 +949,12 @@ if (dhdr->F1 == 0) return; - memset(&stuff, '\0', sizeof(stuff)); - - stuff.op = HTCP_CLR; - - stuff.rr = RR_RESPONSE; - - stuff.f1 = 0; + htcpStuff stuff(dhdr->msg_id, HTCP_CLR, RR_RESPONSE, 0); stuff.response = purgeSucceeded ? 0 : 2; debugs(31, 3, "htcpClrReply: response = " << stuff.response); - stuff.msg_id = dhdr->msg_id; - pktlen = htcpBuildPacket(pkt, sizeof(pkt), &stuff); if (pktlen == 0) { @@ -1538,7 +1547,6 @@ static char pkt[8192]; ssize_t pktlen; char vbuf[32]; - htcpStuff stuff; HttpHeader hdr(hoRequest); Packer pa; MemBuf mb; @@ -1551,11 +1559,8 @@ memset(&flags, '\0', sizeof(flags)); snprintf(vbuf, sizeof(vbuf), "%d/%d", req->http_ver.major, req->http_ver.minor); - stuff.op = HTCP_TST; - stuff.rr = RR_REQUEST; - stuff.f1 = 1; - stuff.response = 0; - stuff.msg_id = ++msg_id_counter; + + htcpStuff stuff(++msg_id_counter, HTCP_TST, RR_REQUEST, 1); SBuf sb = req->method.image(); stuff.S.method = sb.c_str(); stuff.S.uri = (char *) e->url(); @@ -1594,7 +1599,6 @@ static char pkt[8192]; ssize_t pktlen; char vbuf[32]; - htcpStuff stuff; HttpHeader hdr(hoRequest); Packer pa; MemBuf mb; @@ -1607,19 +1611,11 @@ memset(&flags, '\0', sizeof(flags)); snprintf(vbuf, sizeof(vbuf), "%d/%d", req->http_ver.major, req->http_ver.minor); - stuff.op = HTCP_CLR; - stuff.rr = RR_REQUEST; - stuff.f1 = 0; - stuff.response = 0; - stuff.msg_id = ++msg_id_counter; - switch (reason) { - case HTCP_CLR_INVALIDATION: + + htcpStuff stuff(++msg_id_counter, HTCP_CLR, RR_REQUEST, 0); + if (reason == HTCP_CLR_INVALIDATION) stuff.reason = 1; - break; - default: - stuff.reason = 0; - break; - } + SBuf sb = req->method.image(); stuff.S.method = sb.c_str(); if (e == NULL || e->mem_obj == NULL) { diff -u -r -N squid-3.5.1/src/HttpHdrRange.cc squid-3.5.2/src/HttpHdrRange.cc --- squid-3.5.1/src/HttpHdrRange.cc 2015-01-13 04:52:01.000000000 -0800 +++ squid-3.5.2/src/HttpHdrRange.cc 2015-02-18 04:17:02.000000000 -0800 @@ -224,7 +224,7 @@ const char *item; const char *pos = NULL; int ilen; - assert(this && range_spec); + assert(range_spec); ++ParsedCount; debugs(64, 8, "parsing range field: '" << range_spec << "'"); /* check range type */ @@ -306,7 +306,6 @@ HttpHdrRange::packInto(Packer * packer) const { const_iterator pos = begin(); - assert(this); while (pos != end()) { if (pos != begin()) @@ -371,7 +370,7 @@ int HttpHdrRange::canonize(HttpReply *rep) { - assert(this && rep); + assert(rep); if (rep->content_range) clen = rep->content_range->elength; @@ -401,7 +400,6 @@ HttpHdrRange::isComplex() const { int64_t offset = 0; - assert(this); /* check that all rangers are in "strong" order */ const_iterator pos (begin()); @@ -427,7 +425,6 @@ bool HttpHdrRange::willBeComplex() const { - assert(this); /* check that all rangers are in "strong" order, */ /* as far as we can tell without the content length */ int64_t offset = 0; @@ -460,7 +457,6 @@ HttpHdrRange::firstOffset() const { int64_t offset = HttpHdrRangeSpec::UnknownPosition; - assert(this); const_iterator pos = begin(); while (pos != end()) { @@ -484,7 +480,6 @@ { int64_t offset = HttpHdrRangeSpec::UnknownPosition; const_iterator pos = begin(); - assert(this); while (pos != end()) { int64_t current = (*pos)->offset; @@ -512,10 +507,6 @@ bool HttpHdrRange::offsetLimitExceeded(const int64_t limit) const { - if (NULL == this) - /* not a range request */ - return false; - if (limit == 0) /* 0 == disabled */ return true; diff -u -r -N squid-3.5.1/src/log/ModStdio.cc squid-3.5.2/src/log/ModStdio.cc --- squid-3.5.1/src/log/ModStdio.cc 2015-01-13 04:52:01.000000000 -0800 +++ squid-3.5.2/src/log/ModStdio.cc 2015-02-18 04:17:02.000000000 -0800 @@ -108,7 +108,6 @@ char from[MAXPATHLEN]; char to[MAXPATHLEN]; l_stdio_t *ll = (l_stdio_t *) lf->data; - assert(lf->path); const char *realpath = lf->path+6; // skip 'stdio:' prefix. assert(realpath); diff -u -r -N squid-3.5.1/src/neighbors.cc squid-3.5.2/src/neighbors.cc --- squid-3.5.1/src/neighbors.cc 2015-01-13 04:52:01.000000000 -0800 +++ squid-3.5.2/src/neighbors.cc 2015-02-18 04:17:02.000000000 -0800 @@ -1447,8 +1447,7 @@ fake->abort(); // sets ENTRY_ABORTED and initiates releated cleanup HTTPMSGUNLOCK(fake->mem_obj->request); fake->unlock("peerCountMcastPeersDone"); - HTTPMSGUNLOCK(psstate->request); - cbdataFree(psstate); + delete psstate; } static void diff -u -r -N squid-3.5.1/src/parser/Tokenizer.cc squid-3.5.2/src/parser/Tokenizer.cc --- squid-3.5.1/src/parser/Tokenizer.cc 2015-01-13 04:52:01.000000000 -0800 +++ squid-3.5.2/src/parser/Tokenizer.cc 2015-02-18 04:17:02.000000000 -0800 @@ -71,11 +71,13 @@ bool Parser::Tokenizer::prefix(SBuf &returnedToken, const CharacterSet &tokenChars, const SBuf::size_type limit) { - const SBuf::size_type prefixLen = buf_.substr(0,limit).findFirstNotOf(tokenChars); + SBuf::size_type prefixLen = buf_.substr(0,limit).findFirstNotOf(tokenChars); if (prefixLen == 0) return false; if (prefixLen == SBuf::npos && (atEnd() || limit == 0)) return false; + if (prefixLen == SBuf::npos && limit > 0) + prefixLen = limit; returnedToken = consume(prefixLen); // cannot be empty after the npos check return true; } diff -u -r -N squid-3.5.1/src/peer_select.cc squid-3.5.2/src/peer_select.cc --- squid-3.5.1/src/peer_select.cc 2015-01-13 04:52:01.000000000 -0800 +++ squid-3.5.2/src/peer_select.cc 2015-02-18 04:17:02.000000000 -0800 @@ -107,7 +107,7 @@ assert(entry); assert(entry->ping_status == PING_NONE); assert(direct != DIRECT_YES); - debugs(44, 3, "peerSelectIcpPing: " << entry->url() ); + debugs(44, 3, "peerSelectIcpPing: " << entry->url()); if (!request->flags.hierarchical && direct != DIRECT_NO) return 0; @@ -255,7 +255,7 @@ if (fs && psstate->paths->size() < (unsigned int)Config.forward_max_tries) { // send the next one off for DNS lookup. const char *host = fs->_peer ? fs->_peer->host : psstate->request->GetHost(); - debugs(44, 2, "Find IP destination for: " << psstate->entry->url() << "' via " << host); + debugs(44, 2, "Find IP destination for: " << psstate->url() << "' via " << host); ipcache_nbgethostbyname(host, peerSelectDnsResults, psstate); return; } @@ -753,7 +753,7 @@ StoreEntry *entry = psstate->entry; if (entry) - debugs(44, 3, "peerPingTimeout: '" << entry->url() << "'" ); + debugs(44, 3, "peerPingTimeout: '" << psstate->url() << "'" ); if (!cbdataReferenceValid(psstate->callback_data)) { /* request aborted */ @@ -821,7 +821,7 @@ { ps_state *psstate = (ps_state *)data; icp_opcode op = header->getOpCode(); - debugs(44, 3, "peerHandleIcpReply: " << icp_opcode_str[op] << " " << psstate->entry->url() ); + debugs(44, 3, "peerHandleIcpReply: " << icp_opcode_str[op] << " " << psstate->url() ); #if USE_CACHE_DIGESTS && 0 /* do cd lookup to count false misses */ @@ -854,9 +854,7 @@ peerHandleHtcpReply(CachePeer * p, peer_t type, HtcpReplyData * htcp, void *data) { ps_state *psstate = (ps_state *)data; - debugs(44, 3, "peerHandleHtcpReply: " << - (htcp->hit ? "HIT" : "MISS") << " " << - psstate->entry->url() ); + debugs(44, 3, "" << (htcp->hit ? "HIT" : "MISS") << " " << psstate->url()); ++ psstate->ping.n_recv; if (htcp->hit) { diff -u -r -N squid-3.5.1/src/SquidConfig.h squid-3.5.2/src/SquidConfig.h --- squid-3.5.1/src/SquidConfig.h 2015-01-13 04:52:01.000000000 -0800 +++ squid-3.5.2/src/SquidConfig.h 2015-02-18 04:17:02.000000000 -0800 @@ -100,7 +100,6 @@ } Timeout; size_t maxRequestHeaderSize; int64_t maxRequestBodySize; - int64_t maxChunkedRequestBodySize; size_t maxRequestBufferSize; size_t maxReplyHeaderSize; AclSizeLimit *ReplyBodySize; @@ -499,6 +498,7 @@ char *key; int version; char *options; + long parsedOptions; char *cipher; char *cafile; char *capath; diff -u -r -N squid-3.5.1/src/ssl/PeerConnector.cc squid-3.5.2/src/ssl/PeerConnector.cc --- squid-3.5.1/src/ssl/PeerConnector.cc 2015-01-13 04:52:01.000000000 -0800 +++ squid-3.5.2/src/ssl/PeerConnector.cc 2015-02-18 04:17:02.000000000 -0800 @@ -144,48 +144,61 @@ if (peer->sslSession) SSL_set_session(ssl, peer->sslSession); - - } else if (request->clientConnectionManager->sslBumpMode == Ssl::bumpPeek || request->clientConnectionManager->sslBumpMode == Ssl::bumpStare) { - // client connection is required for Peek or Stare mode in the case we need to splice + } else if (ConnStateData *csd = request->clientConnectionManager.valid()) { + // client connection is required in the case we need to splice // or terminate client and server connections assert(clientConn != NULL); - SSL *clientSsl = fd_table[request->clientConnectionManager->clientConnection->fd].ssl; - BIO *b = SSL_get_rbio(clientSsl); - Ssl::ClientBio *clnBio = static_cast(b->ptr); - const Ssl::Bio::sslFeatures &features = clnBio->getFeatures(); - if (features.sslVersion != -1) { - features.applyToSSL(ssl); - // Should we allow it for all protocols? - if (features.sslVersion >= 3) { - b = SSL_get_rbio(ssl); - Ssl::ServerBio *srvBio = static_cast(b->ptr); - srvBio->setClientFeatures(features); - srvBio->recordInput(true); - srvBio->mode(request->clientConnectionManager->sslBumpMode); + const char *hostName = NULL; + Ssl::ClientBio *cltBio = NULL; + + // In server-first bumping mode, clientSsl is NULL. + if (SSL *clientSsl = fd_table[clientConn->fd].ssl) { + BIO *b = SSL_get_rbio(clientSsl); + cltBio = static_cast(b->ptr); + const Ssl::Bio::sslFeatures &features = cltBio->getFeatures(); + if (!features.serverName.isEmpty()) + hostName = features.serverName.c_str(); + } + + if (!hostName) { + // While we are peeking at the certificate, we may not know the server + // name that the client will request (after interception or CONNECT) + // unless it was the CONNECT request with a user-typed address. + const bool isConnectRequest = !csd->port->flags.isIntercepted(); + if (!request->flags.sslPeek || isConnectRequest) + hostName = request->GetHost(); + } + + if (hostName) + SSL_set_ex_data(ssl, ssl_ex_index_server, (void*)hostName); + + Must(!csd->serverBump() || csd->serverBump()->step <= Ssl::bumpStep2); + if (csd->sslBumpMode == Ssl::bumpPeek || csd->sslBumpMode == Ssl::bumpStare) { + assert(cltBio); + const Ssl::Bio::sslFeatures &features = cltBio->getFeatures(); + if (features.sslVersion != -1) { + features.applyToSSL(ssl); + // Should we allow it for all protocols? + if (features.sslVersion >= 3) { + BIO *b = SSL_get_rbio(ssl); + Ssl::ServerBio *srvBio = static_cast(b->ptr); + // Inherite client features, like SSL version, SNI and other + srvBio->setClientFeatures(features); + srvBio->recordInput(true); + srvBio->mode(csd->sslBumpMode); + } } + } else { + // Set client SSL options + SSL_set_options(ssl, ::Config.ssl_client.parsedOptions); - const bool isConnectRequest = request->clientConnectionManager.valid() && - !request->clientConnectionManager->port->flags.isIntercepted(); - if (isConnectRequest) - SSL_set_ex_data(ssl, ssl_ex_index_server, (void*)request->GetHost()); - else if (!features.serverName.isEmpty()) - SSL_set_ex_data(ssl, ssl_ex_index_server, (void*)features.serverName.c_str()); + // Use SNI TLS extension only when we connect directly + // to the origin server and we know the server host name. + const char *sniServer = hostName ? hostName : + (!request->GetHostIsNumeric() ? request->GetHost() : NULL); + if (sniServer) + Ssl::setClientSNI(ssl, sniServer); } - } else { - // While we are peeking at the certificate, we may not know the server - // name that the client will request (after interception or CONNECT) - // unless it was the CONNECT request with a user-typed address. - const char *hostname = request->GetHost(); - const bool hostnameIsIp = request->GetHostIsNumeric(); - const bool isConnectRequest = request->clientConnectionManager.valid() && - !request->clientConnectionManager->port->flags.isIntercepted(); - if (!request->flags.sslPeek || isConnectRequest) - SSL_set_ex_data(ssl, ssl_ex_index_server, (void*)hostname); - - // Use SNI TLS extension only when we connect directly - // to the origin server and we know the server host name. - if (!hostnameIsIp) - Ssl::setClientSNI(ssl, hostname); } // If CertValidation Helper used do not lookup checklist for errors, diff -u -r -N squid-3.5.1/src/ssl/support.cc squid-3.5.2/src/ssl/support.cc --- squid-3.5.1/src/ssl/support.cc 2015-01-13 04:52:01.000000000 -0800 +++ squid-3.5.2/src/ssl/support.cc 2015-02-18 04:17:02.000000000 -0800 @@ -312,16 +312,19 @@ // pass them to certficate validator for more processing else if (Ssl::TheConfig.ssl_crt_validator) { ok = 1; - // Check if we have stored certificates chain. Store if not. - if (!SSL_get_ex_data(ssl, ssl_ex_index_ssl_cert_chain)) { - STACK_OF(X509) *certStack = X509_STORE_CTX_get1_chain(ctx); - if (certStack && !SSL_set_ex_data(ssl, ssl_ex_index_ssl_cert_chain, certStack)) - sk_X509_pop_free(certStack, X509_free); - } } } } + if (Ssl::TheConfig.ssl_crt_validator) { + // Check if we have stored certificates chain. Store if not. + if (!SSL_get_ex_data(ssl, ssl_ex_index_ssl_cert_chain)) { + STACK_OF(X509) *certStack = X509_STORE_CTX_get1_chain(ctx); + if (certStack && !SSL_set_ex_data(ssl, ssl_ex_index_ssl_cert_chain, certStack)) + sk_X509_pop_free(certStack, X509_free); + } + } + if (!ok && !SSL_get_ex_data(ssl, ssl_ex_index_ssl_error_detail) ) { // Find the broken certificate. It may be intermediate. @@ -477,6 +480,11 @@ "No_Compression", SSL_OP_NO_COMPRESSION }, #endif +#if SSL_OP_NO_TICKET + { + "NO_TICKET", SSL_OP_NO_TICKET + }, +#endif { "", 0 }, diff -u -r -N squid-3.5.1/src/stat.cc squid-3.5.2/src/stat.cc --- squid-3.5.1/src/stat.cc 2015-01-13 04:52:01.000000000 -0800 +++ squid-3.5.2/src/stat.cc 2015-02-18 04:17:02.000000000 -0800 @@ -370,11 +370,11 @@ storeAppendPrintf(state->sentry, "} by kid%d\n\n", KidIdentifier); state->sentry->complete(); state->sentry->unlock("statObjects+isDone"); - cbdataFree(state); + delete state; return; } else if (EBIT_TEST(state->sentry->flags, ENTRY_ABORTED)) { state->sentry->unlock("statObjects+aborted"); - cbdataFree(state); + delete state; return; } else if (state->sentry->checkDeferRead(-1)) { state->sentry->flush(); diff -u -r -N squid-3.5.1/src/stmem.cc squid-3.5.2/src/stmem.cc --- squid-3.5.1/src/stmem.cc 2015-01-13 04:52:01.000000000 -0800 +++ squid-3.5.2/src/stmem.cc 2015-02-18 04:17:02.000000000 -0800 @@ -58,7 +58,7 @@ void mem_hdr::freeContent() { - nodes.destroy(SplayNode::DefaultFree); + nodes.destroy(); inmem_hi = 0; debugs(19, 9, HERE << this << " hi: " << inmem_hi); } diff -u -r -N squid-3.5.1/src/stmem.h squid-3.5.2/src/stmem.h --- squid-3.5.1/src/stmem.h 2015-01-13 04:52:01.000000000 -0800 +++ squid-3.5.2/src/stmem.h 2015-02-18 04:17:02.000000000 -0800 @@ -44,7 +44,7 @@ /* Only for use of MemObject */ void internalAppend(const char *data, int len); - static SplayNode::SPLAYCMP NodeCompare; + static Splay::SPLAYCMP NodeCompare; private: void debugDump() const; diff -u -r -N squid-3.5.1/src/store.cc squid-3.5.2/src/store.cc --- squid-3.5.1/src/store.cc 2015-01-13 04:52:01.000000000 -0800 +++ squid-3.5.2/src/store.cc 2015-02-18 04:17:02.000000000 -0800 @@ -1686,9 +1686,7 @@ const char * StoreEntry::url() const { - if (this == NULL) - return "[null_entry]"; - else if (mem_obj == NULL) + if (mem_obj == NULL) return "[null_mem_obj]"; else return mem_obj->storeId(); diff -u -r -N squid-3.5.1/src/store_swapout.cc squid-3.5.2/src/store_swapout.cc --- squid-3.5.1/src/store_swapout.cc 2015-01-13 04:52:01.000000000 -0800 +++ squid-3.5.2/src/store_swapout.cc 2015-02-18 04:17:02.000000000 -0800 @@ -89,8 +89,9 @@ static void storeSwapOutFileNotify(void *data, int errflag, StoreIOState::Pointer self) { - generic_cbdata *c = (generic_cbdata *)data; - StoreEntry *e = (StoreEntry *)c->data; + StoreEntry *e; + static_cast(data)->unwrap(&e); + MemObject *mem = e->mem_obj; assert(e->swap_status == SWAPOUT_WRITING); assert(mem); @@ -281,12 +282,12 @@ static void storeSwapOutFileClosed(void *data, int errflag, StoreIOState::Pointer self) { - generic_cbdata *c = (generic_cbdata *)data; - StoreEntry *e = (StoreEntry *)c->data; + StoreEntry *e; + static_cast(data)->unwrap(&e); + MemObject *mem = e->mem_obj; assert(mem->swapout.sio == self); assert(e->swap_status == SWAPOUT_WRITING); - cbdataFree(c); // if object_size is still unknown, the entry was probably aborted if (errflag || e->objectLen() < 0) { diff -u -r -N squid-3.5.1/src/String.cc squid-3.5.2/src/String.cc --- squid-3.5.1/src/String.cc 2015-01-13 04:52:01.000000000 -0800 +++ squid-3.5.2/src/String.cc 2015-02-18 04:17:02.000000000 -0800 @@ -105,7 +105,7 @@ String::allocAndFill(const char *str, int len) { PROF_start(StringAllocAndFill); - assert(this && str); + assert(str); allocBuffer(len + 1); len_ = len; memcpy(buf_, str, len); @@ -127,7 +127,6 @@ String::clean() { PROF_start(StringClean); - assert(this); /* TODO if mempools has already closed this will FAIL!! */ if (defined()) @@ -163,7 +162,6 @@ void String::append( char const *str, int len) { - assert(this); assert(str && len >= 0); PROF_start(StringAppend); diff -u -r -N squid-3.5.1/src/tests/stub_libeui.cc squid-3.5.2/src/tests/stub_libeui.cc --- squid-3.5.1/src/tests/stub_libeui.cc 2015-01-13 04:52:01.000000000 -0800 +++ squid-3.5.2/src/tests/stub_libeui.cc 2015-02-18 04:17:02.000000000 -0800 @@ -18,7 +18,7 @@ #if USE_SQUID_EUI const unsigned char *Eui::Eui48::get(void) STUB_RETVAL(NULL) bool Eui::Eui48::decode(const char *asc) STUB_RETVAL(false) -bool Eui::Eui48::encode(char *buf, const int len) STUB_RETVAL(false) +bool Eui::Eui48::encode(char *buf, const int len) const STUB_RETVAL(false) bool Eui::Eui48::lookup(const Ip::Address &c) STUB_RETVAL(false) #endif @@ -26,7 +26,7 @@ #if USE_SQUID_EUI const unsigned char *Eui::Eui64::get(void) STUB_RETVAL(NULL) bool Eui::Eui64::decode(const char *asc) STUB_RETVAL(false) -bool Eui::Eui64::encode(char *buf, const int len) STUB_RETVAL(false) +bool Eui::Eui64::encode(char *buf, const int len) const STUB_RETVAL(false) bool Eui::Eui64::lookup(const Ip::Address &c) STUB_RETVAL(false) bool Eui::Eui64::lookupNdp(const Ip::Address &c) STUB_RETVAL(false) bool Eui::Eui64::lookupSlaac(const Ip::Address &c) STUB_RETVAL(false) diff -u -r -N squid-3.5.1/src/tests/testRefCount.cc squid-3.5.2/src/tests/testRefCount.cc --- squid-3.5.1/src/tests/testRefCount.cc 2015-01-13 04:52:01.000000000 -0800 +++ squid-3.5.2/src/tests/testRefCount.cc 2015-02-18 04:17:02.000000000 -0800 @@ -20,7 +20,7 @@ ~_ToRefCount() {--Instances;} int someMethod() { - if (!this) + if (!Instances) exit(1); return 1; @@ -40,7 +40,7 @@ typedef RefCount Pointer; int doSomething() { - if (!this) + if (!Instances) exit (1); return 1; } diff -u -r -N squid-3.5.1/src/tools.cc squid-3.5.2/src/tools.cc --- squid-3.5.1/src/tools.cc 2015-01-13 04:52:01.000000000 -0800 +++ squid-3.5.2/src/tools.cc 2015-02-18 04:17:02.000000000 -0800 @@ -896,7 +896,7 @@ } #endif /* HAVE_SETRLIMIT */ -#if HAVE_SETRLIMIT && defined(RLIMIT_DATA) +#if HAVE_SETRLIMIT && defined(RLIMIT_DATA) && !_SQUID_CYGWIN_ if (getrlimit(RLIMIT_DATA, &rl) < 0) { debugs(50, DBG_CRITICAL, "getrlimit: RLIMIT_DATA: " << xstrerror()); } else if (rl.rlim_max > rl.rlim_cur) { @@ -912,7 +912,7 @@ debugs(50, DBG_IMPORTANT, "NOTICE: Could not increase the number of filedescriptors"); } -#if HAVE_SETRLIMIT && defined(RLIMIT_VMEM) +#if HAVE_SETRLIMIT && defined(RLIMIT_VMEM) && !_SQUID_CYGWIN_ if (getrlimit(RLIMIT_VMEM, &rl) < 0) { debugs(50, DBG_CRITICAL, "getrlimit: RLIMIT_VMEM: " << xstrerror()); } else if (rl.rlim_max > rl.rlim_cur) { @@ -1227,7 +1227,10 @@ cap_value_t cap_list[10]; cap_list[ncaps] = CAP_NET_BIND_SERVICE; ++ncaps; - if (Ip::Interceptor.TransparentActive() || Ip::Qos::TheConfig.isHitNfmarkActive() || Ip::Qos::TheConfig.isAclNfmarkActive()) { + if (Ip::Interceptor.TransparentActive() || + Ip::Qos::TheConfig.isHitNfmarkActive() || + Ip::Qos::TheConfig.isAclNfmarkActive() || + Ip::Qos::TheConfig.isAclTosActive()) { cap_list[ncaps] = CAP_NET_ADMIN; ++ncaps; } diff -u -r -N squid-3.5.1/test-suite/mem_hdr_test.cc squid-3.5.2/test-suite/mem_hdr_test.cc --- squid-3.5.1/test-suite/mem_hdr_test.cc 2015-01-13 04:52:01.000000000 -0800 +++ squid-3.5.2/test-suite/mem_hdr_test.cc 2015-02-18 04:17:02.000000000 -0800 @@ -75,7 +75,7 @@ assert (!aSplay.find(&ref13,mem_hdr::NodeCompare)); ref13.nodeBuffer.length = 1; assert (aSplay.find(&ref13,mem_hdr::NodeCompare)); - aSplay.destroy(SplayNode::DefaultFree); + aSplay.destroy(); } void diff -u -r -N squid-3.5.1/test-suite/splay.cc squid-3.5.2/test-suite/splay.cc --- squid-3.5.1/test-suite/splay.cc 2015-01-13 04:52:01.000000000 -0800 +++ squid-3.5.2/test-suite/splay.cc 2015-02-18 04:17:02.000000000 -0800 @@ -18,14 +18,7 @@ #include #endif -#if 0 -#define assert(X) {if (!(X)) exit (1);} #include "splay.h" -#undef assert -#else -#include "splay.h" -#endif - #include "util.h" class intnode @@ -146,7 +139,10 @@ for (i = 0; i < 100; ++i) { I = (intnode *)xcalloc(sizeof(intnode), 1); I->i = squid_random(); - top = top->insert(I, compareintvoid); + if (top) + top = top->insert(I, compareintvoid); + else + top = new splayNode(static_cast(new intnode(101))); } SplayCheck::BeginWalk(); @@ -155,15 +151,12 @@ SplayCheck::BeginWalk(); top->walk(SplayCheck::WalkVoid, NULL); top->destroy(destintvoid); - /* check we don't segfault on NULL splay calls */ - top = NULL; - top->splay((void *)NULL, compareintvoid); } /* test typesafe splay containers */ { /* intnode* */ - SplayNode *safeTop = NULL; + SplayNode *safeTop = new SplayNode(new intnode(101)); for ( int i = 0; i < 100; ++i) { intnode *I; @@ -176,13 +169,10 @@ safeTop->walk(SplayCheck::WalkNode, NULL); safeTop->destroy(destint); - /* check we don't segfault on NULL splay calls */ - safeTop = NULL; - safeTop->splay((intnode *)NULL, compareint); } { /* intnode */ - SplayNode *safeTop = NULL; + SplayNode *safeTop = new SplayNode(101); for (int i = 0; i < 100; ++i) { intnode I; @@ -194,11 +184,6 @@ safeTop->walk(SplayCheck::WalkNodeRef, NULL); safeTop->destroy(destintref); - /* check we don't segfault on NULL splay calls */ - safeTop = NULL; - safeTop->splay(intnode(), compareintref); - SplayCheck::BeginWalk(); - safeTop->walk(SplayCheck::WalkNodeRef, NULL); } /* check the check routine */ @@ -215,7 +200,7 @@ { /* check for begin() */ - SplayNode *safeTop = NULL; + Splay *safeTop = new Splay(); if (safeTop->start() != NULL) exit (1); @@ -228,15 +213,15 @@ I.i = squid_random(); if (I.i > 50 && I.i < 10000000) - safeTop = safeTop->insert(I, compareintref); + safeTop->insert(I, compareintref); } { intnode I; I.i = 50; - safeTop = safeTop->insert (I, compareintref); + safeTop->insert (I, compareintref); I.i = 10000000; - safeTop = safeTop->insert (I, compareintref); + safeTop->insert (I, compareintref); } if (!safeTop->start()) @@ -280,6 +265,8 @@ exit (1); } + /* TODO: also test the other Splay API */ + return 0; } diff -u -r -N squid-3.5.1/tools/cachemgr.cc squid-3.5.2/tools/cachemgr.cc --- squid-3.5.1/tools/cachemgr.cc 2015-01-13 04:52:01.000000000 -0800 +++ squid-3.5.2/tools/cachemgr.cc 2015-02-18 04:17:02.000000000 -0800 @@ -980,7 +980,7 @@ cachemgr_request *req; char *s; - char *t; + char *t = NULL; char *q; if ((buf = read_post_request()) != NULL) @@ -1005,6 +1005,7 @@ req = (cachemgr_request *)xcalloc(1, sizeof(cachemgr_request)); for (s = strtok(buf, "&"); s != NULL; s = strtok(NULL, "&")) { + safe_free(t); t = xstrdup(s); if ((q = strchr(t, '=')) == NULL) @@ -1035,8 +1036,8 @@ req->workers = xstrdup(q); else if (0 == strcmp(t, "processes") && strlen(q)) req->processes = xstrdup(q); - safe_free(t); } + safe_free(t); if (req->server && !req->hostname) { char *p;