diff -u -r -N squid-3.5.20/aclocal.m4 squid-3.5.21/aclocal.m4 --- squid-3.5.20/aclocal.m4 2016-07-01 23:38:43.000000000 +1200 +++ squid-3.5.21/aclocal.m4 2016-09-09 06:58:28.000000000 +1200 @@ -744,7 +744,6 @@ cat <<_LT_EOF >> "$cfgfile" #! $SHELL # Generated automatically by $as_me ($PACKAGE) $VERSION -# Libtool was configured on host `(hostname || uname -n) 2>/dev/null | sed 1q`: # NOTE: Changes made to this file will be lost: look at ltmain.sh. # Provide generalized library-building support services. diff -u -r -N squid-3.5.20/cfgaux/ltmain.sh squid-3.5.21/cfgaux/ltmain.sh --- squid-3.5.20/cfgaux/ltmain.sh 2016-07-01 23:38:54.000000000 +1200 +++ squid-3.5.21/cfgaux/ltmain.sh 2016-09-09 06:58:46.000000000 +1200 @@ -31,7 +31,7 @@ PROGRAM=libtool PACKAGE=libtool -VERSION="2.4.6 Debian-2.4.6-0.1" +VERSION="2.4.6 Debian-2.4.6-2" package_revision=2.4.6 @@ -2068,7 +2068,7 @@ compiler: $LTCC compiler flags: $LTCFLAGS linker: $LD (gnu? $with_gnu_ld) - version: $progname (GNU libtool) 2.4.6 + version: $progname $scriptversion Debian-2.4.6-2 automake: `($AUTOMAKE --version) 2>/dev/null |$SED 1q` autoconf: `($AUTOCONF --version) 2>/dev/null |$SED 1q` diff -u -r -N squid-3.5.20/ChangeLog squid-3.5.21/ChangeLog --- squid-3.5.20/ChangeLog 2016-07-01 23:37:50.000000000 +1200 +++ squid-3.5.21/ChangeLog 2016-09-09 06:56:46.000000000 +1200 @@ -1,3 +1,16 @@ +Changes to squid-3.5.21 (08 Sep 2016): + + - Bug 4563: duplicate code in httpMakeVaryMark + - Bug 4542: authentication credentials IP TTL updated incorrectly + - Bug 4534: assertion failure in xcalloc when using many cache_dir + - Bug 4428: mal-formed Cache-Control:stale-if-error header + - Bug 3025: Proxy-Authenticate problem using ICAP server + - Fix segfault via Ftp::Client::readControlReply() + - Fix SSL-Bump failure results in SEGFAULT + - HTTP/1.1: MUST always revalidate Cache-Control:no-cache responses + - HTTP/1.1: do not allow Proxy-Connection to override Connection header + - SSL: CN wildcard must only match a single domain component [fragment] + Changes to squid-3.5.20 (01 Jul 2016): - Bug 4523: smblib compile fails on NetBSD diff -u -r -N squid-3.5.20/configure squid-3.5.21/configure --- squid-3.5.20/configure 2016-07-01 23:40:16.000000000 +1200 +++ squid-3.5.21/configure 2016-09-09 07:00:42.000000000 +1200 @@ -1,7 +1,7 @@ #! /bin/sh # From configure.ac Revision. # Guess values for system-dependent variables and create Makefiles. -# Generated by GNU Autoconf 2.69 for Squid Web Proxy 3.5.20. +# Generated by GNU Autoconf 2.69 for Squid Web Proxy 3.5.21. # # Report bugs to . # @@ -595,8 +595,8 @@ # Identity of this package. PACKAGE_NAME='Squid Web Proxy' PACKAGE_TARNAME='squid' -PACKAGE_VERSION='3.5.20' -PACKAGE_STRING='Squid Web Proxy 3.5.20' +PACKAGE_VERSION='3.5.21' +PACKAGE_STRING='Squid Web Proxy 3.5.21' PACKAGE_BUGREPORT='http://bugs.squid-cache.org/' PACKAGE_URL='' @@ -1636,7 +1636,7 @@ # Omit some internal or obsolete options to make the list less imposing. # This message is too long to be a string in the A/UX 3.1 sh. cat <<_ACEOF -\`configure' configures Squid Web Proxy 3.5.20 to adapt to many kinds of systems. +\`configure' configures Squid Web Proxy 3.5.21 to adapt to many kinds of systems. Usage: $0 [OPTION]... [VAR=VALUE]... @@ -1707,7 +1707,7 @@ if test -n "$ac_init_help"; then case $ac_init_help in - short | recursive ) echo "Configuration of Squid Web Proxy 3.5.20:";; + short | recursive ) echo "Configuration of Squid Web Proxy 3.5.21:";; esac cat <<\_ACEOF @@ -2119,7 +2119,7 @@ test -n "$ac_init_help" && exit $ac_status if $ac_init_version; then cat <<\_ACEOF -Squid Web Proxy configure 3.5.20 +Squid Web Proxy configure 3.5.21 generated by GNU Autoconf 2.69 Copyright (C) 2012 Free Software Foundation, Inc. @@ -3223,7 +3223,7 @@ This file contains any messages produced by compilers while running configure, to aid debugging if configure makes a mistake. -It was created by Squid Web Proxy $as_me 3.5.20, which was +It was created by Squid Web Proxy $as_me 3.5.21, which was generated by GNU Autoconf 2.69. Invocation command line was $ $0 $@ @@ -4090,7 +4090,7 @@ # Define the identity of the package. PACKAGE='squid' - VERSION='3.5.20' + VERSION='3.5.21' cat >>confdefs.h <<_ACEOF @@ -41876,7 +41876,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.20, which was +This file was extended by Squid Web Proxy $as_me 3.5.21, which was generated by GNU Autoconf 2.69. Invocation command line was CONFIG_FILES = $CONFIG_FILES @@ -41942,7 +41942,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.20 +Squid Web Proxy config.status 3.5.21 configured by $0, generated by GNU Autoconf 2.69, with options \\"\$ac_cs_config\\" @@ -43262,7 +43262,6 @@ cat <<_LT_EOF >> "$cfgfile" #! $SHELL # Generated automatically by $as_me ($PACKAGE) $VERSION -# Libtool was configured on host `(hostname || uname -n) 2>/dev/null | sed 1q`: # NOTE: Changes made to this file will be lost: look at ltmain.sh. # Provide generalized library-building support services. diff -u -r -N squid-3.5.20/configure.ac squid-3.5.21/configure.ac --- squid-3.5.20/configure.ac 2016-07-01 23:40:16.000000000 +1200 +++ squid-3.5.21/configure.ac 2016-09-09 07:00:41.000000000 +1200 @@ -5,7 +5,7 @@ ## Please see the COPYING and CONTRIBUTORS files for details. ## -AC_INIT([Squid Web Proxy],[3.5.20],[http://bugs.squid-cache.org/],[squid]) +AC_INIT([Squid Web Proxy],[3.5.21],[http://bugs.squid-cache.org/],[squid]) AC_PREREQ(2.61) AC_CONFIG_HEADERS([include/autoconf.h]) AC_CONFIG_AUX_DIR(cfgaux) diff -u -r -N squid-3.5.20/doc/release-notes/release-3.5.html squid-3.5.21/doc/release-notes/release-3.5.html --- squid-3.5.20/doc/release-notes/release-3.5.html 2016-07-02 00:30:54.000000000 +1200 +++ squid-3.5.21/doc/release-notes/release-3.5.html 2016-09-09 08:06:08.000000000 +1200 @@ -2,10 +2,10 @@ - Squid 3.5.20 release notes + Squid 3.5.21 release notes -

Squid 3.5.20 release notes

+

Squid 3.5.21 release notes

Squid Developers


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

1. Notice

-

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

+

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

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

diff -u -r -N squid-3.5.20/helpers/basic_auth/DB/basic_db_auth.8 squid-3.5.21/helpers/basic_auth/DB/basic_db_auth.8 --- squid-3.5.20/helpers/basic_auth/DB/basic_db_auth.8 2016-07-02 00:30:59.000000000 +1200 +++ squid-3.5.21/helpers/basic_auth/DB/basic_db_auth.8 2016-09-09 08:06:12.000000000 +1200 @@ -133,7 +133,7 @@ .\" ======================================================================== .\" .IX Title "BASIC_DB_AUTH 8" -.TH BASIC_DB_AUTH 8 "2016-07-01" "perl v5.22.2" "User Contributed Perl Documentation" +.TH BASIC_DB_AUTH 8 "2016-09-08" "perl v5.22.2" "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.20/helpers/basic_auth/MSNT-multi-domain/basic_msnt_multi_domain_auth.8 squid-3.5.21/helpers/basic_auth/MSNT-multi-domain/basic_msnt_multi_domain_auth.8 --- squid-3.5.20/helpers/basic_auth/MSNT-multi-domain/basic_msnt_multi_domain_auth.8 2016-07-02 00:31:06.000000000 +1200 +++ squid-3.5.21/helpers/basic_auth/MSNT-multi-domain/basic_msnt_multi_domain_auth.8 2016-09-09 08:06:18.000000000 +1200 @@ -133,7 +133,7 @@ .\" ======================================================================== .\" .IX Title "BASIC_MSNT_MULTI_DOMAIN_AUTH 1" -.TH BASIC_MSNT_MULTI_DOMAIN_AUTH 1 "2016-07-01" "perl v5.22.2" "User Contributed Perl Documentation" +.TH BASIC_MSNT_MULTI_DOMAIN_AUTH 1 "2016-09-08" "perl v5.22.2" "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.20/helpers/basic_auth/POP3/basic_pop3_auth.8 squid-3.5.21/helpers/basic_auth/POP3/basic_pop3_auth.8 --- squid-3.5.20/helpers/basic_auth/POP3/basic_pop3_auth.8 2016-07-02 00:31:13.000000000 +1200 +++ squid-3.5.21/helpers/basic_auth/POP3/basic_pop3_auth.8 2016-09-09 08:06:24.000000000 +1200 @@ -133,7 +133,7 @@ .\" ======================================================================== .\" .IX Title "BASIC_POP3_AUTH 8" -.TH BASIC_POP3_AUTH 8 "2016-07-01" "perl v5.22.2" "User Contributed Perl Documentation" +.TH BASIC_POP3_AUTH 8 "2016-09-08" "perl v5.22.2" "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.20/helpers/external_acl/delayer/ext_delayer_acl.8 squid-3.5.21/helpers/external_acl/delayer/ext_delayer_acl.8 --- squid-3.5.20/helpers/external_acl/delayer/ext_delayer_acl.8 2016-07-02 00:31:28.000000000 +1200 +++ squid-3.5.21/helpers/external_acl/delayer/ext_delayer_acl.8 2016-09-09 08:06:41.000000000 +1200 @@ -133,7 +133,7 @@ .\" ======================================================================== .\" .IX Title "EXT_DELAYER_ACL 8" -.TH EXT_DELAYER_ACL 8 "2016-07-01" "perl v5.22.2" "User Contributed Perl Documentation" +.TH EXT_DELAYER_ACL 8 "2016-09-08" "perl v5.22.2" "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.20/helpers/external_acl/SQL_session/ext_sql_session_acl.8 squid-3.5.21/helpers/external_acl/SQL_session/ext_sql_session_acl.8 --- squid-3.5.20/helpers/external_acl/SQL_session/ext_sql_session_acl.8 2016-07-02 00:31:36.000000000 +1200 +++ squid-3.5.21/helpers/external_acl/SQL_session/ext_sql_session_acl.8 2016-09-09 08:06:50.000000000 +1200 @@ -133,7 +133,7 @@ .\" ======================================================================== .\" .IX Title "EXT_SQL_SESSION_ACL 8" -.TH EXT_SQL_SESSION_ACL 8 "2016-07-01" "perl v5.22.2" "User Contributed Perl Documentation" +.TH EXT_SQL_SESSION_ACL 8 "2016-09-08" "perl v5.22.2" "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.20/helpers/external_acl/wbinfo_group/ext_wbinfo_group_acl.8 squid-3.5.21/helpers/external_acl/wbinfo_group/ext_wbinfo_group_acl.8 --- squid-3.5.20/helpers/external_acl/wbinfo_group/ext_wbinfo_group_acl.8 2016-07-02 00:31:40.000000000 +1200 +++ squid-3.5.21/helpers/external_acl/wbinfo_group/ext_wbinfo_group_acl.8 2016-09-09 08:06:55.000000000 +1200 @@ -133,7 +133,7 @@ .\" ======================================================================== .\" .IX Title "EXT_WBINFO_GROUP_ACL 8" -.TH EXT_WBINFO_GROUP_ACL 8 "2016-07-01" "perl v5.22.2" "User Contributed Perl Documentation" +.TH EXT_WBINFO_GROUP_ACL 8 "2016-09-08" "perl v5.22.2" "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.20/helpers/log_daemon/DB/log_db_daemon.8 squid-3.5.21/helpers/log_daemon/DB/log_db_daemon.8 --- squid-3.5.20/helpers/log_daemon/DB/log_db_daemon.8 2016-07-02 00:31:43.000000000 +1200 +++ squid-3.5.21/helpers/log_daemon/DB/log_db_daemon.8 2016-09-09 08:06:58.000000000 +1200 @@ -133,7 +133,7 @@ .\" ======================================================================== .\" .IX Title "LOG_DB_DAEMON 8" -.TH LOG_DB_DAEMON 8 "2016-07-01" "perl v5.22.2" "User Contributed Perl Documentation" +.TH LOG_DB_DAEMON 8 "2016-09-08" "perl v5.22.2" "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.20/helpers/storeid_rewrite/file/storeid_file_rewrite.8 squid-3.5.21/helpers/storeid_rewrite/file/storeid_file_rewrite.8 --- squid-3.5.20/helpers/storeid_rewrite/file/storeid_file_rewrite.8 2016-07-02 00:31:58.000000000 +1200 +++ squid-3.5.21/helpers/storeid_rewrite/file/storeid_file_rewrite.8 2016-09-09 08:07:15.000000000 +1200 @@ -133,7 +133,7 @@ .\" ======================================================================== .\" .IX Title "STOREID_FILE_REWRITE 8" -.TH STOREID_FILE_REWRITE 8 "2016-07-01" "perl v5.22.2" "User Contributed Perl Documentation" +.TH STOREID_FILE_REWRITE 8 "2016-09-08" "perl v5.22.2" "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.20/include/version.h squid-3.5.21/include/version.h --- squid-3.5.20/include/version.h 2016-07-01 23:40:17.000000000 +1200 +++ squid-3.5.21/include/version.h 2016-09-09 07:00:42.000000000 +1200 @@ -7,7 +7,7 @@ */ #ifndef SQUID_RELEASE_TIME -#define SQUID_RELEASE_TIME 1467373063 +#define SQUID_RELEASE_TIME 1473360998 #endif /* diff -u -r -N squid-3.5.20/libltdl/configure squid-3.5.21/libltdl/configure --- squid-3.5.20/libltdl/configure 2016-07-01 23:50:44.000000000 +1200 +++ squid-3.5.21/libltdl/configure 2016-09-09 07:19:37.000000000 +1200 @@ -14975,7 +14975,6 @@ cat <<_LT_EOF >> "$cfgfile" #! $SHELL # Generated automatically by $as_me ($PACKAGE) $VERSION -# Libtool was configured on host `(hostname || uname -n) 2>/dev/null | sed 1q`: # NOTE: Changes made to this file will be lost: look at ltmain.sh. # Provide generalized library-building support services. diff -u -r -N squid-3.5.20/libltdl/m4/libtool.m4 squid-3.5.21/libltdl/m4/libtool.m4 --- squid-3.5.20/libltdl/m4/libtool.m4 2016-07-01 23:38:55.000000000 +1200 +++ squid-3.5.21/libltdl/m4/libtool.m4 2016-09-09 06:58:47.000000000 +1200 @@ -728,7 +728,6 @@ cat <<_LT_EOF >> "$cfgfile" #! $SHELL # Generated automatically by $as_me ($PACKAGE) $VERSION -# Libtool was configured on host `(hostname || uname -n) 2>/dev/null | sed 1q`: # NOTE: Changes made to this file will be lost: look at ltmain.sh. # Provide generalized library-building support services. diff -u -r -N squid-3.5.20/RELEASENOTES.html squid-3.5.21/RELEASENOTES.html --- squid-3.5.20/RELEASENOTES.html 2016-07-02 00:30:54.000000000 +1200 +++ squid-3.5.21/RELEASENOTES.html 2016-09-09 08:06:08.000000000 +1200 @@ -2,10 +2,10 @@ - Squid 3.5.20 release notes + Squid 3.5.21 release notes -

Squid 3.5.20 release notes

+

Squid 3.5.21 release notes

Squid Developers


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

1. Notice

-

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

+

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

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

diff -u -r -N squid-3.5.20/src/acl/ServerName.cc squid-3.5.21/src/acl/ServerName.cc --- squid-3.5.20/src/acl/ServerName.cc 2016-07-01 23:37:50.000000000 +1200 +++ squid-3.5.21/src/acl/ServerName.cc 2016-09-09 06:56:46.000000000 +1200 @@ -30,7 +30,7 @@ const char *h = static_cast(a); const char *d = static_cast(b); debugs(28, 7, "Match:" << h << " <> " << d); - return matchDomainName(h, d, true); + return matchDomainName(h, d, mdnHonorWildcards); } bool diff -u -r -N squid-3.5.20/src/auth/User.cc squid-3.5.21/src/auth/User.cc --- squid-3.5.20/src/auth/User.cc 2016-07-01 23:37:50.000000000 +1200 +++ squid-3.5.21/src/auth/User.cc 2016-09-09 06:56:46.000000000 +1200 @@ -284,7 +284,7 @@ /* This ip has already been seen. */ found = 1; /* update IP ttl */ - ipdata->ip_expiretime = squid_curtime; + ipdata->ip_expiretime = squid_curtime + ::Config.authenticateIpTTL; } else if (ipdata->ip_expiretime <= squid_curtime) { /* This IP has expired - remove from the seen list */ dlinkDelete(&ipdata->node, &ip_list); diff -u -r -N squid-3.5.20/src/CacheDigest.cc squid-3.5.21/src/CacheDigest.cc --- squid-3.5.20/src/CacheDigest.cc 2016-07-01 23:37:50.000000000 +1200 +++ squid-3.5.21/src/CacheDigest.cc 2016-09-09 06:56:46.000000000 +1200 @@ -35,12 +35,12 @@ static uint32_t hashed_keys[4]; static void -cacheDigestInit(CacheDigest * cd, int capacity, int bpe) +cacheDigestInit(CacheDigest * cd, uint64_t capacity, uint8_t bpe) { - const size_t mask_size = cacheDigestCalcMaskSize(capacity, bpe); + const uint32_t mask_size = cacheDigestCalcMaskSize(capacity, bpe); assert(cd); assert(capacity > 0 && bpe > 0); - assert(mask_size > 0); + assert(mask_size != 0); cd->capacity = capacity; cd->bits_per_entry = bpe; cd->mask_size = mask_size; @@ -50,7 +50,7 @@ } CacheDigest * -cacheDigestCreate(int capacity, int bpe) +cacheDigestCreate(uint64_t capacity, uint8_t bpe) { CacheDigest *cd = (CacheDigest *)memAllocate(MEM_CACHE_DIGEST); assert(SQUID_MD5_DIGEST_LENGTH == 16); /* our hash functions rely on 16 byte keys */ @@ -97,7 +97,7 @@ /* changes mask size, resets bits to 0, preserves "cd" pointer */ void -cacheDigestChangeCap(CacheDigest * cd, int new_cap) +cacheDigestChangeCap(CacheDigest * cd, uint64_t new_cap) { assert(cd); cacheDigestClean(cd); @@ -278,12 +278,12 @@ storeAppendPrintf(e, "%s digest: size: %d bytes\n", label ? label : "", stats.bit_count / 8 ); - storeAppendPrintf(e, "\t entries: count: %d capacity: %d util: %d%%\n", + storeAppendPrintf(e, "\t entries: count: %" PRIu64 " capacity: %" PRIu64 " util: %d%%\n", cd->count, cd->capacity, xpercentInt(cd->count, cd->capacity) ); - storeAppendPrintf(e, "\t deletion attempts: %d\n", + storeAppendPrintf(e, "\t deletion attempts: %" PRIu64 "\n", cd->del_count ); storeAppendPrintf(e, "\t bits: per entry: %d on: %d capacity: %d util: %d%%\n", @@ -297,16 +297,18 @@ ); } -size_t -cacheDigestCalcMaskSize(int cap, int bpe) +uint32_t +cacheDigestCalcMaskSize(uint64_t cap, uint8_t bpe) { - return (size_t) (cap * bpe + 7) / 8; + uint64_t bitCount = (cap * bpe) + 7; + assert(bitCount < INT_MAX); // dont 31-bit overflow later + return static_cast(bitCount / 8); } static void cacheDigestHashKey(const CacheDigest * cd, const cache_key * key) { - const unsigned int bit_count = cd->mask_size * 8; + const uint32_t bit_count = cd->mask_size * 8; unsigned int tmp_keys[4]; /* we must memcpy to ensure alignment */ memcpy(tmp_keys, key, sizeof(tmp_keys)); diff -u -r -N squid-3.5.20/src/CacheDigest.h squid-3.5.21/src/CacheDigest.h --- squid-3.5.20/src/CacheDigest.h 2016-07-01 23:37:50.000000000 +1200 +++ squid-3.5.21/src/CacheDigest.h 2016-09-09 06:56:46.000000000 +1200 @@ -22,23 +22,23 @@ { public: /* public, read-only */ - char *mask; /* bit mask */ - int mask_size; /* mask size in bytes */ - int capacity; /* expected maximum for .count, not a hard limit */ - int bits_per_entry; /* number of bits allocated for each entry from capacity */ - int count; /* number of digested entries */ - int del_count; /* number of deletions performed so far */ + uint64_t count; /* number of digested entries */ + uint64_t del_count; /* number of deletions performed so far */ + uint64_t capacity; /* expected maximum for .count, not a hard limit */ + char *mask; /* bit mask */ + uint32_t mask_size; /* mask size in bytes */ + int8_t bits_per_entry; /* number of bits allocated for each entry from capacity */ }; -CacheDigest *cacheDigestCreate(int capacity, int bpe); +CacheDigest *cacheDigestCreate(uint64_t capacity, uint8_t bpe); void cacheDigestDestroy(CacheDigest * cd); CacheDigest *cacheDigestClone(const CacheDigest * cd); void cacheDigestClear(CacheDigest * cd); -void cacheDigestChangeCap(CacheDigest * cd, int new_cap); +void cacheDigestChangeCap(CacheDigest * cd, uint64_t new_cap); int cacheDigestTest(const CacheDigest * cd, const cache_key * key); void cacheDigestAdd(CacheDigest * cd, const cache_key * key); void cacheDigestDel(CacheDigest * cd, const cache_key * key); -size_t cacheDigestCalcMaskSize(int cap, int bpe); +uint32_t cacheDigestCalcMaskSize(uint64_t cap, uint8_t bpe); int cacheDigestBitUtil(const CacheDigest * cd); void cacheDigestGuessStatsUpdate(CacheDigestGuessStats * stats, int real_hit, int guess_hit); void cacheDigestGuessStatsReport(const CacheDigestGuessStats * stats, StoreEntry * sentry, const char *label); diff -u -r -N squid-3.5.20/src/clients/FtpClient.cc squid-3.5.21/src/clients/FtpClient.cc --- squid-3.5.20/src/clients/FtpClient.cc 2016-07-01 23:37:50.000000000 +1200 +++ squid-3.5.21/src/clients/FtpClient.cc 2016-09-09 06:56:46.000000000 +1200 @@ -314,6 +314,11 @@ /* We've already read some reply data */ handleControlReply(); } else { + + if (!Comm::IsConnOpen(ctrl.conn)) { + debugs(9, 3, "cannot read without ctrl " << ctrl.conn); + return; + } /* * Cancel the timeout on the Data socket (if any) and * establish one on the control socket. diff -u -r -N squid-3.5.20/src/client_side_reply.cc squid-3.5.21/src/client_side_reply.cc --- squid-3.5.20/src/client_side_reply.cc 2016-07-01 23:37:50.000000000 +1200 +++ squid-3.5.21/src/client_side_reply.cc 2016-09-09 06:56:46.000000000 +1200 @@ -1305,8 +1305,14 @@ // if there is not configured a peer proxy with login=PASS or login=PASSTHRU option enabled // remove the Proxy-Authenticate header - if ( !request->peer_login || (strcmp(request->peer_login,"PASS") != 0 && strcmp(request->peer_login,"PASSTHRU") != 0)) - reply->header.delById(HDR_PROXY_AUTHENTICATE); + if ( !request->peer_login || (strcmp(request->peer_login,"PASS") != 0 && strcmp(request->peer_login,"PASSTHRU") != 0)) { +#if USE_ADAPTATION + // but allow adaptation services to authenticate clients + // via request satisfaction + if (!http->requestSatisfactionMode()) +#endif + reply->header.delById(HDR_PROXY_AUTHENTICATE); + } reply->header.removeHopByHopEntries(); diff -u -r -N squid-3.5.20/src/client_side_request.cc squid-3.5.21/src/client_side_request.cc --- squid-3.5.20/src/client_side_request.cc 2016-07-01 23:37:50.000000000 +1200 +++ squid-3.5.21/src/client_side_request.cc 2016-09-09 06:56:46.000000000 +1200 @@ -1811,7 +1811,7 @@ repContext->setReplyToStoreEntry(e, "immediate SslBump error"); errorAppendEntry(e, calloutContext->error); calloutContext->error = NULL; - if (calloutContext->readNextRequest) + if (calloutContext->readNextRequest && getConn()) getConn()->flags.readMore = true; // resume any pipeline reads. node = (clientStreamNode *)client_stream.tail->data; clientStreamRead(node, this, node->readBuffer); diff -u -r -N squid-3.5.20/src/client_side_request.h squid-3.5.21/src/client_side_request.h --- squid-3.5.20/src/client_side_request.h 2016-07-01 23:37:50.000000000 +1200 +++ squid-3.5.21/src/client_side_request.h 2016-09-09 06:56:46.000000000 +1200 @@ -140,6 +140,7 @@ public: void startAdaptation(const Adaptation::ServiceGroupPointer &g); + bool requestSatisfactionMode() const { return request_satisfaction_mode; } // private but exposed for ClientRequestContext void handleAdaptationFailure(int errDetail, bool bypassable = false); diff -u -r -N squid-3.5.20/src/enums.h squid-3.5.21/src/enums.h --- squid-3.5.20/src/enums.h 2016-07-01 23:37:50.000000000 +1200 +++ squid-3.5.21/src/enums.h 2016-09-09 06:56:46.000000000 +1200 @@ -95,11 +95,11 @@ */ enum { ENTRY_SPECIAL, - ENTRY_REVALIDATE, + ENTRY_REVALIDATE_ALWAYS, DELAY_SENDING, RELEASE_REQUEST, REFRESH_REQUEST, - ENTRY_CACHABLE_RESERVED_FOR_FUTURE_USE, + ENTRY_REVALIDATE_STALE, ENTRY_DISPATCHED, KEY_PRIVATE, ENTRY_FWD_HDR_WAIT, diff -u -r -N squid-3.5.20/src/http.cc squid-3.5.21/src/http.cc --- squid-3.5.20/src/http.cc 2016-07-01 23:37:50.000000000 +1200 +++ squid-3.5.21/src/http.cc 2016-09-09 06:56:46.000000000 +1200 @@ -572,43 +572,27 @@ /* NOTREACHED */ } -/* - * For Vary, store the relevant request headers as - * virtual headers in the reply - * Returns an empty SBuf if the variance cannot be stored - */ -SBuf -httpMakeVaryMark(HttpRequest * request, HttpReply const * reply) +/// assemble a variant key (vary-mark) from the given Vary header and HTTP request +static void +assembleVaryKey(String &vary, SBuf &vstr, const HttpRequest &request) { - String vary, hdr; - const char *pos = NULL; - const char *item; - const char *value; - int ilen; - SBuf vstr; static const SBuf asterisk("*"); - - vary = reply->header.getList(HDR_VARY); + const char *pos = nullptr; + const char *item = nullptr; + int ilen = 0; while (strListGetItem(&vary, ',', &item, &ilen, &pos)) { - char *name = (char *)xmalloc(ilen + 1); - xstrncpy(name, item, ilen + 1); - Tolower(name); - - if (strcmp(name, "*") == 0) { - /* Can not handle "Vary: *" withtout ETag support */ - safe_free(name); + SBuf name(item, ilen); + if (name == asterisk) { vstr.clear(); break; } - + name.toLower(); if (!vstr.isEmpty()) vstr.append(", ", 2); vstr.append(name); - hdr = request->header.getByName(name); - safe_free(name); - value = hdr.termedBuf(); - + String hdr(request.header.getByName(name.c_str())); + const char *value = hdr.termedBuf(); if (value) { value = rfc1738_escape_part(value); vstr.append("=\"", 2); @@ -618,43 +602,26 @@ hdr.clean(); } +} - vary.clean(); -#if X_ACCELERATOR_VARY - - pos = NULL; - vary = reply->header.getList(HDR_X_ACCELERATOR_VARY); - - while (strListGetItem(&vary, ',', &item, &ilen, &pos)) { - char *name = (char *)xmalloc(ilen + 1); - xstrncpy(name, item, ilen + 1); - Tolower(name); - - if (strcmp(name, "*") == 0) { - /* Can not handle "Vary: *" withtout ETag support */ - safe_free(name); - vstr.clear(); - break; - } - - if (!vstr.isEmpty()) - vstr.append(", ", 2); - vstr.append(name); - hdr = request->header.getByName(name); - safe_free(name); - value = hdr.termedBuf(); - - if (value) { - value = rfc1738_escape_part(value); - vstr.append("=\"", 2); - vstr.append(value); - vstr.append("\"", 1); - } +/* + * For Vary, store the relevant request headers as + * virtual headers in the reply + * Returns an empty SBuf if the variance cannot be stored + */ +SBuf +httpMakeVaryMark(HttpRequest * request, HttpReply const * reply) +{ + SBuf vstr; + String vary; - hdr.clean(); - } + vary = reply->header.getList(HDR_VARY); + assembleVaryKey(vary, vstr, *request); +#if X_ACCELERATOR_VARY vary.clean(); + vary = reply->header.getList(HDR_X_ACCELERATOR_VARY); + assembleVaryKey(vary, vstr, *request); #endif debugs(11, 3, vstr); @@ -991,8 +958,10 @@ // CC:private (yes, these can sometimes be stored) const bool ccPrivate = rep->cache_control->hasPrivate(); - if (ccMustRevalidate || ccNoCacheNoParams || ccSMaxAge || ccPrivate) - EBIT_SET(entry->flags, ENTRY_REVALIDATE); + if (ccNoCacheNoParams || ccPrivate) + EBIT_SET(entry->flags, ENTRY_REVALIDATE_ALWAYS); + else if (ccMustRevalidate || ccSMaxAge) + EBIT_SET(entry->flags, ENTRY_REVALIDATE_STALE); } #if USE_HTTP_VIOLATIONS // response header Pragma::no-cache is undefined in HTTP else { @@ -1002,7 +971,7 @@ * but servers like "Active Imaging Webcast/2.0" sure do use it */ if (rep->header.has(HDR_PRAGMA) && rep->header.hasListMember(HDR_PRAGMA,"no-cache",',')) - EBIT_SET(entry->flags, ENTRY_REVALIDATE); + EBIT_SET(entry->flags, ENTRY_REVALIDATE_ALWAYS); } #endif } diff -u -r -N squid-3.5.20/src/HttpHdrCc.cc squid-3.5.21/src/HttpHdrCc.cc --- squid-3.5.20/src/HttpHdrCc.cc 2016-07-01 23:37:50.000000000 +1200 +++ squid-3.5.21/src/HttpHdrCc.cc 2016-09-09 06:56:46.000000000 +1200 @@ -257,6 +257,27 @@ /* for all options having values, "=value" after the name */ switch (flag) { + case CC_BADHDR: + break; + case CC_PUBLIC: + break; + case CC_PRIVATE: + if (Private().size()) + packerPrintf(p, "=\"" SQUIDSTRINGPH "\"", SQUIDSTRINGPRINT(Private())); + break; + + case CC_NO_CACHE: + if (noCache().size()) + packerPrintf(p, "=\"" SQUIDSTRINGPH "\"", SQUIDSTRINGPRINT(noCache())); + break; + case CC_NO_STORE: + break; + case CC_NO_TRANSFORM: + break; + case CC_MUST_REVALIDATE: + break; + case CC_PROXY_REVALIDATE: + break; case CC_MAX_AGE: packerPrintf(p, "=%d", (int) maxAge()); break; @@ -272,8 +293,14 @@ case CC_MIN_FRESH: packerPrintf(p, "=%d", (int) minFresh()); break; - default: - /* do nothing, directive was already printed */ + case CC_ONLY_IF_CACHED: + break; + case CC_STALE_IF_ERROR: + packerPrintf(p, "=%d", staleIfError()); + break; + case CC_OTHER: + case CC_ENUM_END: + // done below after the loop break; } diff -u -r -N squid-3.5.20/src/HttpHeaderTools.cc squid-3.5.21/src/HttpHeaderTools.cc --- squid-3.5.20/src/HttpHeaderTools.cc 2016-07-01 23:37:50.000000000 +1200 +++ squid-3.5.21/src/HttpHeaderTools.cc 2016-09-09 06:56:46.000000000 +1200 @@ -131,32 +131,30 @@ } /** - * return true if a given directive is found in at least one of - * the "connection" header-fields note: if HDR_PROXY_CONNECTION is - * present we ignore HDR_CONNECTION. + * \return true if a given directive is found in the Connection header field-value. + * + * \note if no Connection header exists we may check the Proxy-Connection header */ -int +bool httpHeaderHasConnDir(const HttpHeader * hdr, const char *directive) { String list; - int res; + /* what type of header do we have? */ + if (hdr->has(HDR_CONNECTION)) { + list = hdr->getList(HDR_CONNECTION); + return strListIsMember(&list, directive, ',') != 0; + } #if USE_HTTP_VIOLATIONS - if (hdr->has(HDR_PROXY_CONNECTION)) + if (hdr->has(HDR_PROXY_CONNECTION)) { list = hdr->getList(HDR_PROXY_CONNECTION); - else + return strListIsMember(&list, directive, ',') != 0; + } #endif - if (hdr->has(HDR_CONNECTION)) - list = hdr->getList(HDR_CONNECTION); - else - return 0; - - res = strListIsMember(&list, directive, ','); - - list.clean(); - return res; + // else, no connection header for it to exist in + return false; } /** handy to printf prefixes of potentially very long buffers */ diff -u -r -N squid-3.5.20/src/HttpHeaderTools.h squid-3.5.21/src/HttpHeaderTools.h --- squid-3.5.20/src/HttpHeaderTools.h 2016-07-01 23:37:50.000000000 +1200 +++ squid-3.5.21/src/HttpHeaderTools.h 2016-09-09 06:56:46.000000000 +1200 @@ -120,7 +120,7 @@ http_hdr_type httpHeaderIdByName(const char *name, size_t name_len, const HttpHeaderFieldInfo * attrs, int end); http_hdr_type httpHeaderIdByNameDef(const char *name, int name_len); const char *httpHeaderNameById(int id); -int httpHeaderHasConnDir(const HttpHeader * hdr, const char *directive); +bool httpHeaderHasConnDir(const HttpHeader * hdr, const char *directive); int httpHeaderParseInt(const char *start, int *val); void httpHeaderPutStrf(HttpHeader * hdr, http_hdr_type id, const char *fmt,...) PRINTF_FORMAT_ARG3; diff -u -r -N squid-3.5.20/src/peer_digest.cc squid-3.5.21/src/peer_digest.cc --- squid-3.5.20/src/peer_digest.cc 2016-07-01 23:37:50.000000000 +1200 +++ squid-3.5.21/src/peer_digest.cc 2016-09-09 06:56:46.000000000 +1200 @@ -754,7 +754,7 @@ if (!reason && !size) { if (!pd->cd) reason = "null digest?!"; - else if (fetch->mask_offset != (int)pd->cd->mask_size) + else if (fetch->mask_offset != pd->cd->mask_size) reason = "premature end of digest?!"; else if (!peerDigestUseful(pd)) reason = "useless digest"; diff -u -r -N squid-3.5.20/src/PeerDigest.h squid-3.5.21/src/PeerDigest.h --- squid-3.5.20/src/PeerDigest.h 2016-07-01 23:37:50.000000000 +1200 +++ squid-3.5.21/src/PeerDigest.h 2016-09-09 06:56:46.000000000 +1200 @@ -52,7 +52,7 @@ store_client *old_sc; HttpRequest *request; int offset; - int mask_offset; + uint32_t mask_offset; time_t start_time; time_t resp_time; time_t expires; diff -u -r -N squid-3.5.20/src/refresh.cc squid-3.5.21/src/refresh.cc --- squid-3.5.20/src/refresh.cc 2016-07-01 23:37:50.000000000 +1200 +++ squid-3.5.21/src/refresh.cc 2016-09-09 06:56:46.000000000 +1200 @@ -356,12 +356,15 @@ * Cache-Control: proxy-revalidate * the spec says the response must always be revalidated if stale. */ - if (EBIT_TEST(entry->flags, ENTRY_REVALIDATE) && staleness > -1 + const bool revalidateAlways = EBIT_TEST(entry->flags, ENTRY_REVALIDATE_ALWAYS); + bool revalidateStale = staleness > -1 && EBIT_TEST(entry->flags, ENTRY_REVALIDATE_STALE); #if USE_HTTP_VIOLATIONS - && !R->flags.ignore_must_revalidate + revalidateStale = revalidateStale && !R->flags.ignore_must_revalidate; #endif - ) { - debugs(22, 3, "YES: Must revalidate stale object (origin set must-revalidate or proxy-revalidate)"); + if (revalidateAlways || revalidateStale) { + debugs(22, 3, "YES: Must revalidate stale object (origin set " << + (revalidateAlways ? "no-cache or private" : + "must-revalidate, proxy-revalidate or s-maxage") << ")"); if (request) request->flags.failOnValidationError = true; return STALE_MUST_REVALIDATE; diff -u -r -N squid-3.5.20/src/ssl/support.cc squid-3.5.21/src/ssl/support.cc --- squid-3.5.20/src/ssl/support.cc 2016-07-01 23:37:50.000000000 +1200 +++ squid-3.5.21/src/ssl/support.cc 2016-09-09 06:56:46.000000000 +1200 @@ -199,9 +199,12 @@ char cn[1024]; const char *server = (const char *)check_data; - if (cn_data->length > (int)sizeof(cn) - 1) { + if (cn_data->length == 0) + return 1; // zero length cn, ignore + + if (cn_data->length > (int)sizeof(cn) - 1) return 1; //if does not fit our buffer just ignore - } + char *s = reinterpret_cast(cn_data->data); char *d = cn; for (int i = 0; i < cn_data->length; ++i, ++d, ++s) { @@ -211,7 +214,7 @@ } cn[cn_data->length] = '\0'; debugs(83, 4, "Verifying server domain " << server << " to certificate name/subjectAltName " << cn); - return matchDomainName(server, cn[0] == '*' ? cn + 1 : cn); + return matchDomainName(server, (cn[0] == '*' ? cn + 1 : cn), mdnRejectSubsubDomains); } bool Ssl::checkX509ServerValidity(X509 *cert, const char *server) diff -u -r -N squid-3.5.20/src/stat.cc squid-3.5.21/src/stat.cc --- squid-3.5.20/src/stat.cc 2016-07-01 23:37:50.000000000 +1200 +++ squid-3.5.21/src/stat.cc 2016-09-09 06:56:46.000000000 +1200 @@ -286,8 +286,8 @@ if (EBIT_TEST(flags, ENTRY_SPECIAL)) strcat(buf, "SPECIAL,"); - if (EBIT_TEST(flags, ENTRY_REVALIDATE)) - strcat(buf, "REVALIDATE,"); + if (EBIT_TEST(flags, ENTRY_REVALIDATE_ALWAYS)) + strcat(buf, "REVALIDATE_ALWAYS,"); if (EBIT_TEST(flags, DELAY_SENDING)) strcat(buf, "DELAY_SENDING,"); @@ -298,6 +298,9 @@ if (EBIT_TEST(flags, REFRESH_REQUEST)) strcat(buf, "REFRESH_REQUEST,"); + if (EBIT_TEST(flags, ENTRY_REVALIDATE_STALE)) + strcat(buf, "REVALIDATE_STALE,"); + if (EBIT_TEST(flags, ENTRY_DISPATCHED)) strcat(buf, "DISPATCHED,"); diff -u -r -N squid-3.5.20/src/store.cc squid-3.5.21/src/store.cc --- squid-3.5.20/src/store.cc 2016-07-01 23:37:50.000000000 +1200 +++ squid-3.5.21/src/store.cc 2016-09-09 06:56:46.000000000 +1200 @@ -2122,10 +2122,11 @@ // print only set flags, using unique letters if (e.flags) { if (EBIT_TEST(e.flags, ENTRY_SPECIAL)) os << 'S'; - if (EBIT_TEST(e.flags, ENTRY_REVALIDATE)) os << 'R'; + if (EBIT_TEST(e.flags, ENTRY_REVALIDATE_ALWAYS)) os << 'R'; if (EBIT_TEST(e.flags, DELAY_SENDING)) os << 'P'; if (EBIT_TEST(e.flags, RELEASE_REQUEST)) os << 'X'; if (EBIT_TEST(e.flags, REFRESH_REQUEST)) os << 'F'; + if (EBIT_TEST(e.flags, ENTRY_REVALIDATE_STALE)) os << 'E'; if (EBIT_TEST(e.flags, ENTRY_DISPATCHED)) os << 'D'; if (EBIT_TEST(e.flags, KEY_PRIVATE)) os << 'I'; if (EBIT_TEST(e.flags, ENTRY_FWD_HDR_WAIT)) os << 'W'; diff -u -r -N squid-3.5.20/src/store_digest.cc squid-3.5.21/src/store_digest.cc --- squid-3.5.20/src/store_digest.cc 2016-07-01 23:37:50.000000000 +1200 +++ squid-3.5.21/src/store_digest.cc 2016-09-09 06:56:46.000000000 +1200 @@ -76,36 +76,63 @@ static void storeDigestRewriteFinish(StoreEntry * e); static EVH storeDigestSwapOutStep; static void storeDigestCBlockSwapOut(StoreEntry * e); -static int storeDigestCalcCap(void); -static int storeDigestResize(void); static void storeDigestAdd(const StoreEntry *); -#endif /* USE_CACHE_DIGESTS */ - -static void -storeDigestRegisterWithCacheManager(void) +/// calculates digest capacity +static uint64_t +storeDigestCalcCap() { - Mgr::RegisterAction("store_digest", "Store Digest", storeDigestReport, 0, 1); -} + /* + * To-Do: Bloom proved that the optimal filter utilization is 50% (half of + * the bits are off). However, we do not have a formula to calculate the + * number of _entries_ we want to pre-allocate for. + */ + const uint64_t hi_cap = Store::Root().maxSize() / Config.Store.avgObjectSize; + const uint64_t lo_cap = 1 + Store::Root().currentSize() / Config.Store.avgObjectSize; + const uint64_t e_count = StoreEntry::inUseCount(); + uint64_t cap = e_count ? e_count : hi_cap; + debugs(71, 2, "have: " << e_count << ", want " << cap << + " entries; limits: [" << lo_cap << ", " << hi_cap << "]"); -/* - * PUBLIC FUNCTIONS - */ + if (cap < lo_cap) + cap = lo_cap; + + /* do not enforce hi_cap limit, average-based estimation may be wrong + *if (cap > hi_cap) + * cap = hi_cap; + */ + + // Bug 4534: we still have to set an upper-limit at some reasonable value though. + // this matches cacheDigestCalcMaskSize doing (cap*bpe)+7 < INT_MAX + const uint64_t absolute_max = (INT_MAX -8) / Config.digest.bits_per_entry; + if (cap > absolute_max) { + static time_t last_loud = 0; + if (last_loud < squid_curtime - 86400) { + debugs(71, DBG_IMPORTANT, "WARNING: Cache Digest cannot store " << cap << " entries. Limiting to " << absolute_max); + last_loud = squid_curtime; + } else { + debugs(71, 3, "WARNING: Cache Digest cannot store " << cap << " entries. Limiting to " << absolute_max); + } + cap = absolute_max; + } + + return cap; +} +#endif /* USE_CACHE_DIGESTS */ void storeDigestInit(void) { - storeDigestRegisterWithCacheManager(); + Mgr::RegisterAction("store_digest", "Store Digest", storeDigestReport, 0, 1); #if USE_CACHE_DIGESTS - const int cap = storeDigestCalcCap(); - if (!Config.onoff.digest_generation) { store_digest = NULL; debugs(71, 3, "Local cache digest generation disabled"); return; } + const uint64_t cap = storeDigestCalcCap(); store_digest = cacheDigestCreate(cap, Config.digest.bits_per_entry); debugs(71, DBG_IMPORTANT, "Local cache digest enabled; rebuild/rewrite every " << (int) Config.digest.rebuild_period << "/" << @@ -290,6 +317,31 @@ storeDigestRebuildResume(); } +/// \returns true if we actually resized the digest +static bool +storeDigestResize() +{ + const uint64_t cap = storeDigestCalcCap(); + assert(store_digest); + uint64_t diff; + if (cap > store_digest->capacity) + diff = cap - store_digest->capacity; + else + diff = store_digest->capacity - cap; + debugs(71, 2, store_digest->capacity << " -> " << cap << "; change: " << + diff << " (" << xpercentInt(diff, store_digest->capacity) << "%)" ); + /* avoid minor adjustments */ + + if (diff <= store_digest->capacity / 10) { + debugs(71, 2, "small change, will not resize."); + return false; + } else { + debugs(71, 2, "big change, resizing."); + cacheDigestChangeCap(store_digest, cap); + } + return true; +} + /* called be Rewrite to push Rebuild forward */ static void storeDigestRebuildResume(void) @@ -439,7 +491,7 @@ assert(e); /* _add_ check that nothing bad happened while we were waiting @?@ @?@ */ - if (sd_state.rewrite_offset + chunk_size > store_digest->mask_size) + if (static_cast(sd_state.rewrite_offset + chunk_size) > store_digest->mask_size) chunk_size = store_digest->mask_size - sd_state.rewrite_offset; e->append(store_digest->mask + sd_state.rewrite_offset, chunk_size); @@ -451,7 +503,7 @@ sd_state.rewrite_offset += chunk_size; /* are we done ? */ - if (sd_state.rewrite_offset >= store_digest->mask_size) + if (static_cast(sd_state.rewrite_offset) >= store_digest->mask_size) storeDigestRewriteFinish(e); else eventAdd("storeDigestSwapOutStep", storeDigestSwapOutStep, data, 0.0, 1, false); @@ -467,60 +519,10 @@ sd_state.cblock.count = htonl(store_digest->count); sd_state.cblock.del_count = htonl(store_digest->del_count); sd_state.cblock.mask_size = htonl(store_digest->mask_size); - sd_state.cblock.bits_per_entry = (unsigned char) - Config.digest.bits_per_entry; + sd_state.cblock.bits_per_entry = Config.digest.bits_per_entry; sd_state.cblock.hash_func_count = (unsigned char) CacheDigestHashFuncCount; e->append((char *) &sd_state.cblock, sizeof(sd_state.cblock)); } -/* calculates digest capacity */ -static int -storeDigestCalcCap(void) -{ - /* - * To-Do: Bloom proved that the optimal filter utilization is 50% (half of - * the bits are off). However, we do not have a formula to calculate the - * number of _entries_ we want to pre-allocate for. - */ - const int hi_cap = Store::Root().maxSize() / Config.Store.avgObjectSize; - const int lo_cap = 1 + Store::Root().currentSize() / Config.Store.avgObjectSize; - const int e_count = StoreEntry::inUseCount(); - int cap = e_count ? e_count :hi_cap; - debugs(71, 2, "storeDigestCalcCap: have: " << e_count << ", want " << cap << - " entries; limits: [" << lo_cap << ", " << hi_cap << "]"); - - if (cap < lo_cap) - cap = lo_cap; - - /* do not enforce hi_cap limit, average-based estimation may be wrong - *if (cap > hi_cap) - * cap = hi_cap; - */ - return cap; -} - -/* returns true if we actually resized the digest */ -static int -storeDigestResize(void) -{ - const int cap = storeDigestCalcCap(); - int diff; - assert(store_digest); - diff = abs(cap - store_digest->capacity); - debugs(71, 2, "storeDigestResize: " << - store_digest->capacity << " -> " << cap << "; change: " << - diff << " (" << xpercentInt(diff, store_digest->capacity) << "%)" ); - /* avoid minor adjustments */ - - if (diff <= store_digest->capacity / 10) { - debugs(71, 2, "storeDigestResize: small change, will not resize."); - return 0; - } else { - debugs(71, 2, "storeDigestResize: big change, resizing."); - cacheDigestChangeCap(store_digest, cap); - return 1; - } -} - #endif /* USE_CACHE_DIGESTS */ diff -u -r -N squid-3.5.20/src/tests/stub_CacheDigest.cc squid-3.5.21/src/tests/stub_CacheDigest.cc --- squid-3.5.20/src/tests/stub_CacheDigest.cc 2016-07-01 23:37:50.000000000 +1200 +++ squid-3.5.21/src/tests/stub_CacheDigest.cc 2016-09-09 06:56:46.000000000 +1200 @@ -16,11 +16,11 @@ class CacheDigestGuessStats; class StoreEntry; -CacheDigest * cacheDigestCreate(int, int) STUB_RETVAL(NULL) +CacheDigest * cacheDigestCreate(uint64_t, uint8_t) STUB_RETVAL(NULL) void cacheDigestDestroy(CacheDigest *) STUB CacheDigest * cacheDigestClone(const CacheDigest *) STUB_RETVAL(NULL) void cacheDigestClear(CacheDigest * ) STUB -void cacheDigestChangeCap(CacheDigest *,int) STUB +void cacheDigestChangeCap(CacheDigest *,uint64_t) STUB int cacheDigestTest(const CacheDigest *, const cache_key *) STUB_RETVAL(1) void cacheDigestAdd(CacheDigest *, const cache_key *) STUB void cacheDigestDel(CacheDigest *, const cache_key *) STUB @@ -28,5 +28,5 @@ void cacheDigestGuessStatsUpdate(CacheDigestGuessStats *, int, int) STUB void cacheDigestGuessStatsReport(const CacheDigestGuessStats *, StoreEntry *, const char *) STUB void cacheDigestReport(CacheDigest *, const char *, StoreEntry *) STUB -size_t cacheDigestCalcMaskSize(int, int) STUB_RETVAL(1) +uint32_t cacheDigestCalcMaskSize(uint64_t, uint8_t) STUB_RETVAL(1) diff -u -r -N squid-3.5.20/src/tests/stub_HelperChildConfig.cc squid-3.5.21/src/tests/stub_HelperChildConfig.cc --- squid-3.5.20/src/tests/stub_HelperChildConfig.cc 2016-07-01 23:37:50.000000000 +1200 +++ squid-3.5.21/src/tests/stub_HelperChildConfig.cc 2016-09-09 06:56:46.000000000 +1200 @@ -47,4 +47,5 @@ } void Helper::ChildConfig::parseConfig() STUB +Helper::ChildConfig & Helper::ChildConfig::updateLimits(const Helper::ChildConfig &) STUB_RETVAL(*this) diff -u -r -N squid-3.5.20/src/tunnel.cc squid-3.5.21/src/tunnel.cc --- squid-3.5.20/src/tunnel.cc 2016-07-01 23:37:50.000000000 +1200 +++ squid-3.5.21/src/tunnel.cc 2016-09-09 06:56:46.000000000 +1200 @@ -476,7 +476,7 @@ // we need to relay the 401/407 responses when login=PASS(THRU) const char *pwd = server.conn->getPeer()->login; - const bool relay = pwd && (strcmp(pwd, "PASS") != 0 || strcmp(pwd, "PASSTHRU") != 0) && + const bool relay = pwd && (strcmp(pwd, "PASS") == 0 || strcmp(pwd, "PASSTHRU") == 0) && (*status_ptr == Http::scProxyAuthenticationRequired || *status_ptr == Http::scUnauthorized); diff -u -r -N squid-3.5.20/src/url.cc squid-3.5.21/src/url.cc --- squid-3.5.20/src/url.cc 2016-07-01 23:37:50.000000000 +1200 +++ squid-3.5.21/src/url.cc 2016-09-09 06:56:46.000000000 +1200 @@ -54,6 +54,7 @@ assert(0 == matchDomainName("foo.com", ".foo.com")); assert(0 == matchDomainName(".foo.com", ".foo.com")); assert(0 == matchDomainName("x.foo.com", ".foo.com")); + assert(0 == matchDomainName("y.x.foo.com", ".foo.com")); assert(0 != matchDomainName("x.foo.com", "foo.com")); assert(0 != matchDomainName("foo.com", "x.foo.com")); assert(0 != matchDomainName("bar.com", "foo.com")); @@ -66,6 +67,17 @@ assert(0 < matchDomainName("bfoo.com", "afoo.com")); assert(0 > matchDomainName("afoo.com", "bfoo.com")); assert(0 < matchDomainName("x-foo.com", ".foo.com")); + + assert(0 == matchDomainName(".foo.com", ".foo.com", mdnRejectSubsubDomains)); + assert(0 == matchDomainName("x.foo.com", ".foo.com", mdnRejectSubsubDomains)); + assert(0 != matchDomainName("y.x.foo.com", ".foo.com", mdnRejectSubsubDomains)); + assert(0 != matchDomainName(".x.foo.com", ".foo.com", mdnRejectSubsubDomains)); + + assert(0 == matchDomainName("*.foo.com", "x.foo.com", mdnHonorWildcards)); + assert(0 == matchDomainName("*.foo.com", ".x.foo.com", mdnHonorWildcards)); + assert(0 == matchDomainName("*.foo.com", ".foo.com", mdnHonorWildcards)); + assert(0 != matchDomainName("*.foo.com", "foo.com", mdnHonorWildcards)); + /* more cases? */ } @@ -690,16 +702,20 @@ } int -matchDomainName(const char *h, const char *d, bool honorWildcards) +matchDomainName(const char *h, const char *d, uint flags) { int dl; int hl; + const bool hostIncludesSubdomains = (*h == '.'); while ('.' == *h) ++h; hl = strlen(h); + if (hl == 0) + return -1; + dl = strlen(d); /* @@ -737,9 +753,20 @@ * is a leading '.'. */ - if ('.' == d[0]) - return 0; - else + if ('.' == d[0]) { + if (flags & mdnRejectSubsubDomains) { + // Check for sub-sub domain and reject + while(--hl >= 0 && h[hl] != '.'); + if (hl < 0) { + // No sub-sub domain found, but reject if there is a + // leading dot in given host string (which is removed + // before the check is started). + return hostIncludesSubdomains ? 1 : 0; + } else + return 1; // sub-sub domain, reject + } else + return 0; + } else return 1; } } @@ -751,7 +778,7 @@ // If the h has a form of "*.foo.com" and d has a form of "x.foo.com" // then the h[hl] points to '*', h[hl+1] to '.' and d[dl] to 'x' // The following checks are safe, the "h[hl + 1]" in the worst case is '\0'. - if (honorWildcards && h[hl] == '*' && h[hl + 1] == '.') + if ((flags & mdnHonorWildcards) && h[hl] == '*' && h[hl + 1] == '.') return 0; /* diff -u -r -N squid-3.5.20/src/URL.h squid-3.5.21/src/URL.h --- squid-3.5.20/src/URL.h 2016-07-01 23:37:50.000000000 +1200 +++ squid-3.5.21/src/URL.h 2016-09-09 06:56:46.000000000 +1200 @@ -73,23 +73,29 @@ char *urlRInternal(const char *host, unsigned short port, const char *dir, const char *name); char *urlInternal(const char *dir, const char *name); +enum MatchDomainNameFlags { + mdnNone = 0, + mdnHonorWildcards = 1 << 0, + mdnRejectSubsubDomains = 1 << 1 +}; + /** - * matchDomainName() compares a hostname (usually extracted from traffic) - * with a domainname (usually from an ACL) according to the following rules: - * - * HOST | DOMAIN | MATCH? - * -------------|-------------|------ - * foo.com | foo.com | YES - * .foo.com | foo.com | YES - * x.foo.com | foo.com | NO - * foo.com | .foo.com | YES - * .foo.com | .foo.com | YES - * x.foo.com | .foo.com | YES + * matchDomainName() matches a hostname (usually extracted from traffic) + * with a domainname when mdnNone or mdnRejectSubsubDomains flags are used + * according to the following rules: * - * We strip leading dots on hosts (but not domains!) so that - * ".foo.com" is always the same as "foo.com". + * HOST | DOMAIN | mdnNone | mdnRejectSubsubDomains + * -------------|-------------|-----------|----------------------- + * foo.com | foo.com | YES | YES + * .foo.com | foo.com | YES | YES + * x.foo.com | foo.com | NO | NO + * foo.com | .foo.com | YES | YES + * .foo.com | .foo.com | YES | YES + * x.foo.com | .foo.com | YES | YES + * .x.foo.com | .foo.com | YES | NO + * y.x.foo.com | .foo.com | YES | NO * - * if honorWildcards is true then the matchDomainName() also accepts + * if mdnHonorWildcards flag is set then the matchDomainName() also accepts * optional wildcards on hostname: * * HOST | DOMAIN | MATCH? @@ -99,11 +105,14 @@ * *.foo.com | .foo.com | YES * *.foo.com | foo.com | NO * + * The combination of mdnHonorWildcards and mdnRejectSubsubDomains flags is + * supported. + * * \retval 0 means the host matches the domain * \retval 1 means the host is greater than the domain * \retval -1 means the host is less than the domain */ -int matchDomainName(const char *host, const char *domain, bool honorWildcards = false); +int matchDomainName(const char *host, const char *domain, uint flags = mdnNone); int urlCheckRequest(const HttpRequest *); int urlDefaultPort(AnyP::ProtocolType p); char *urlHostname(const char *url);