diff -u -r -N squid-3.3.11/ChangeLog squid-3.3.12/ChangeLog
--- squid-3.3.11/ChangeLog	2013-12-01 02:55:13.000000000 +1300
+++ squid-3.3.12/ChangeLog	2014-03-09 18:24:25.000000000 +1300
@@ -1,4 +1,14 @@
 
+Changes to squid-3.3.12 (09 Mar 2014):
+
+	- Regression Bug 3769: client_netmask not evaluated since Comm redesign
+	- Bug 4026: Fix SSL and adaptation_access handling of aborted connections
+	- Bug 3969: Fix credentials caching for Digest authentication
+	- Bug 3806: Caching responses with Vary header
+	- Fix umask default on crash report generated email
+	- Fix pthread library detection on FreeBSD 10
+	- Avoid assertions on Range requests that trigger Squid-generated errors.
+
 Changes to squid-3.3.11 (01 Dec 2013):
 
 	- Regression Bug 3936: error-details.txt parse error with OpenSSL since 3.3.9
diff -u -r -N squid-3.3.11/configure squid-3.3.12/configure
--- squid-3.3.11/configure	2013-12-01 02:56:05.000000000 +1300
+++ squid-3.3.12/configure	2014-03-09 18:25:22.000000000 +1300
@@ -1,7 +1,7 @@
 #! /bin/sh
 # From configure.ac Revision.
 # Guess values for system-dependent variables and create Makefiles.
-# Generated by GNU Autoconf 2.68 for Squid Web Proxy 3.3.11.
+# Generated by GNU Autoconf 2.68 for Squid Web Proxy 3.3.12.
 #
 # Report bugs to <http://bugs.squid-cache.org/>.
 #
@@ -575,8 +575,8 @@
 # Identity of this package.
 PACKAGE_NAME='Squid Web Proxy'
 PACKAGE_TARNAME='squid'
-PACKAGE_VERSION='3.3.11'
-PACKAGE_STRING='Squid Web Proxy 3.3.11'
+PACKAGE_VERSION='3.3.12'
+PACKAGE_STRING='Squid Web Proxy 3.3.12'
 PACKAGE_BUGREPORT='http://bugs.squid-cache.org/'
 PACKAGE_URL=''
 
@@ -1574,7 +1574,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.3.11 to adapt to many kinds of systems.
+\`configure' configures Squid Web Proxy 3.3.12 to adapt to many kinds of systems.
 
 Usage: $0 [OPTION]... [VAR=VALUE]...
 
@@ -1644,7 +1644,7 @@
 
 if test -n "$ac_init_help"; then
   case $ac_init_help in
-     short | recursive ) echo "Configuration of Squid Web Proxy 3.3.11:";;
+     short | recursive ) echo "Configuration of Squid Web Proxy 3.3.12:";;
    esac
   cat <<\_ACEOF
 
@@ -2018,7 +2018,7 @@
 test -n "$ac_init_help" && exit $ac_status
 if $ac_init_version; then
   cat <<\_ACEOF
-Squid Web Proxy configure 3.3.11
+Squid Web Proxy configure 3.3.12
 generated by GNU Autoconf 2.68
 
 Copyright (C) 2010 Free Software Foundation, Inc.
@@ -3114,7 +3114,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.3.11, which was
+It was created by Squid Web Proxy $as_me 3.3.12, which was
 generated by GNU Autoconf 2.68.  Invocation command line was
 
   $ $0 $@
@@ -3933,7 +3933,7 @@
 
 # Define the identity of the package.
  PACKAGE='squid'
- VERSION='3.3.11'
+ VERSION='3.3.12'
 
 
 cat >>confdefs.h <<_ACEOF
@@ -19343,7 +19343,7 @@
 $as_echo "$as_me: Windows threads support automatically enabled" >&6;}
             ;;
           freebsd)
-            if test `echo "$squid_host_os_version" | cut -b1` -lt 7 ; then
+            if test `echo "$squid_host_os_version" | tr -d .` -lt 70 ; then
                 { $as_echo "$as_me:${as_lineno-$LINENO}: pthread library requires FreeBSD 7 or later" >&5
 $as_echo "$as_me: pthread library requires FreeBSD 7 or later" >&6;}
                 squid_opt_use_diskthreads="no"
@@ -31863,7 +31863,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.3.11, which was
+This file was extended by Squid Web Proxy $as_me 3.3.12, which was
 generated by GNU Autoconf 2.68.  Invocation command line was
 
   CONFIG_FILES    = $CONFIG_FILES
@@ -31929,7 +31929,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.3.11
+Squid Web Proxy config.status 3.3.12
 configured by $0, generated by GNU Autoconf 2.68,
   with options \\"\$ac_cs_config\\"
 
diff -u -r -N squid-3.3.11/configure.ac squid-3.3.12/configure.ac
--- squid-3.3.11/configure.ac	2013-12-01 02:56:05.000000000 +1300
+++ squid-3.3.12/configure.ac	2014-03-09 18:25:22.000000000 +1300
@@ -1,4 +1,4 @@
-AC_INIT([Squid Web Proxy],[3.3.11],[http://bugs.squid-cache.org/],[squid])
+AC_INIT([Squid Web Proxy],[3.3.12],[http://bugs.squid-cache.org/],[squid])
 AC_PREREQ(2.61)
 AC_CONFIG_HEADERS([include/autoconf.h])
 AC_CONFIG_AUX_DIR(cfgaux)
@@ -582,7 +582,7 @@
             AC_MSG_NOTICE([Windows threads support automatically enabled])
             ;;
           freebsd)
-            if test `echo "$squid_host_os_version" | cut -b1` -lt 7 ; then
+            if test `echo "$squid_host_os_version" | tr -d .` -lt 70 ; then
                 AC_MSG_NOTICE(pthread library requires FreeBSD 7 or later)
                 squid_opt_use_diskthreads="no"
             else
diff -u -r -N squid-3.3.11/helpers/basic_auth/DB/basic_db_auth.8 squid-3.3.12/helpers/basic_auth/DB/basic_db_auth.8
--- squid-3.3.11/helpers/basic_auth/DB/basic_db_auth.8	2013-12-01 03:12:16.000000000 +1300
+++ squid-3.3.12/helpers/basic_auth/DB/basic_db_auth.8	2014-03-09 18:44:35.000000000 +1300
@@ -124,7 +124,7 @@
 .\" ========================================================================
 .\"
 .IX Title "BASIC_DB_AUTH 1"
-.TH BASIC_DB_AUTH 1 "2013-11-30" "perl v5.10.1" "User Contributed Perl Documentation"
+.TH BASIC_DB_AUTH 1 "2014-03-08" "perl v5.10.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.3.11/helpers/external_acl/SQL_session/ext_sql_session_acl.8 squid-3.3.12/helpers/external_acl/SQL_session/ext_sql_session_acl.8
--- squid-3.3.11/helpers/external_acl/SQL_session/ext_sql_session_acl.8	2013-12-01 03:12:18.000000000 +1300
+++ squid-3.3.12/helpers/external_acl/SQL_session/ext_sql_session_acl.8	2014-03-09 18:44:37.000000000 +1300
@@ -124,7 +124,7 @@
 .\" ========================================================================
 .\"
 .IX Title "EXT_SQL_SESSION_ACL 1"
-.TH EXT_SQL_SESSION_ACL 1 "2013-11-30" "perl v5.10.1" "User Contributed Perl Documentation"
+.TH EXT_SQL_SESSION_ACL 1 "2014-03-08" "perl v5.10.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.3.11/helpers/external_acl/wbinfo_group/ext_wbinfo_group_acl.8 squid-3.3.12/helpers/external_acl/wbinfo_group/ext_wbinfo_group_acl.8
--- squid-3.3.11/helpers/external_acl/wbinfo_group/ext_wbinfo_group_acl.8	2013-12-01 03:12:18.000000000 +1300
+++ squid-3.3.12/helpers/external_acl/wbinfo_group/ext_wbinfo_group_acl.8	2014-03-09 18:44:37.000000000 +1300
@@ -124,7 +124,7 @@
 .\" ========================================================================
 .\"
 .IX Title "EXT_WBINFO_GROUP_ACL.PL.IN 1"
-.TH EXT_WBINFO_GROUP_ACL.PL.IN 1 "2013-11-30" "perl v5.10.1" "User Contributed Perl Documentation"
+.TH EXT_WBINFO_GROUP_ACL.PL.IN 1 "2014-03-08" "perl v5.10.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.3.11/helpers/log_daemon/DB/log_db_daemon.8 squid-3.3.12/helpers/log_daemon/DB/log_db_daemon.8
--- squid-3.3.11/helpers/log_daemon/DB/log_db_daemon.8	2013-12-01 03:12:18.000000000 +1300
+++ squid-3.3.12/helpers/log_daemon/DB/log_db_daemon.8	2014-03-09 18:44:37.000000000 +1300
@@ -124,7 +124,7 @@
 .\" ========================================================================
 .\"
 .IX Title "LOG_DB_DAEMON 1"
-.TH LOG_DB_DAEMON 1 "2013-11-30" "perl v5.10.1" "User Contributed Perl Documentation"
+.TH LOG_DB_DAEMON 1 "2014-03-08" "perl v5.10.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.3.11/include/version.h squid-3.3.12/include/version.h
--- squid-3.3.11/include/version.h	2013-12-01 02:56:05.000000000 +1300
+++ squid-3.3.12/include/version.h	2014-03-09 18:25:22.000000000 +1300
@@ -7,7 +7,7 @@
  */
 
 #ifndef SQUID_RELEASE_TIME
-#define SQUID_RELEASE_TIME 1385819711
+#define SQUID_RELEASE_TIME 1394342663
 #endif
 
 #ifndef APP_SHORTNAME
diff -u -r -N squid-3.3.11/lib/sspwin32.c squid-3.3.12/lib/sspwin32.c
--- squid-3.3.11/lib/sspwin32.c	2013-12-01 02:55:13.000000000 +1300
+++ squid-3.3.12/lib/sspwin32.c	2014-03-09 18:24:25.000000000 +1300
@@ -32,10 +32,10 @@
  */
 
 #include "squid.h"
-#include "util.h"
-
-#include "libntlmauth/ntlmauth.h"
+#include "base64.h"
+#include "ntlmauth/ntlmauth.h"
 #include "sspwin32.h"
+#include "util.h"
 
 typedef struct _AUTH_SEQ {
     BOOL fInitialized;
@@ -513,8 +513,8 @@
     } while (0);
     if (fResult != NULL) {
         challenge = (ntlm_challenge *) fResult;
-        Use_Unicode = NEGOTIATE_UNICODE & challenge->flags;
-        NTLM_LocalCall = NEGOTIATE_THIS_IS_LOCAL_CALL & challenge->flags;
+        Use_Unicode = NTLM_NEGOTIATE_UNICODE & challenge->flags;
+        NTLM_LocalCall = NTLM_NEGOTIATE_THIS_IS_LOCAL_CALL & challenge->flags;
         encoded = base64_encode_bin((char *) fResult, cbOut);
     }
     return encoded;
diff -u -r -N squid-3.3.11/RELEASENOTES.html squid-3.3.12/RELEASENOTES.html
--- squid-3.3.11/RELEASENOTES.html	2013-12-01 03:12:23.000000000 +1300
+++ squid-3.3.12/RELEASENOTES.html	2014-03-09 18:44:43.000000000 +1300
@@ -2,10 +2,10 @@
 <HTML>
 <HEAD>
  <META NAME="GENERATOR" CONTENT="LinuxDoc-Tools 0.9.69">
- <TITLE>Squid 3.3.11 release notes</TITLE>
+ <TITLE>Squid 3.3.12 release notes</TITLE>
 </HEAD>
 <BODY>
-<H1>Squid 3.3.11 release notes</H1>
+<H1>Squid 3.3.12 release notes</H1>
 
 <H2>Squid Developers</H2>
 <HR>
@@ -56,7 +56,7 @@
 <HR>
 <H2><A NAME="s1">1.</A> <A HREF="#toc1">Notice</A></H2>
 
-<P>The Squid Team are pleased to announce the release of Squid-3.3.11.</P>
+<P>The Squid Team are pleased to announce the release of Squid-3.3.12.</P>
 <P>This new release is available for download from 
 <A HREF="http://www.squid-cache.org/Versions/v3/3.3/">http://www.squid-cache.org/Versions/v3/3.3/</A> or the 
 <A HREF="http://www.squid-cache.org/Mirrors/http-mirrors.html">mirrors</A>.</P>
@@ -281,6 +281,9 @@
 <EM>ssl::certUntrusted</EM>,
 <EM>ssl::certSelfSigned</EM>.</P>
 
+<DT><B>client_netmask</B><DD>
+<P>IP address 127.0.0.1 (localhost IPv4) is no longer masked.</P>
+
 <DT><B>external_acl_type</B><DD>
 <P><EM>%ACL</EM> format tag ported from 2.6.
 Sends the name of ACL being tested to the external helper.</P>
diff -u -r -N squid-3.3.11/src/AccessLogEntry.cc squid-3.3.12/src/AccessLogEntry.cc
--- squid-3.3.11/src/AccessLogEntry.cc	2013-12-01 02:55:13.000000000 +1300
+++ squid-3.3.12/src/AccessLogEntry.cc	2014-03-09 18:24:25.000000000 +1300
@@ -15,17 +15,30 @@
 void
 AccessLogEntry::getLogClientIp(char *buf, size_t bufsz) const
 {
+    Ip::Address log_ip;
+
 #if FOLLOW_X_FORWARDED_FOR
     if (Config.onoff.log_uses_indirect_client && request)
-        request->indirect_client_addr.NtoA(buf, bufsz);
+        log_ip = request->indirect_client_addr;
     else
 #endif
         if (tcpClient != NULL)
-            tcpClient->remote.NtoA(buf, bufsz);
-        else if (cache.caddr.IsNoAddr()) // e.g., ICAP OPTIONS lack client
+            log_ip = tcpClient->remote;
+        else if (cache.caddr.IsNoAddr()) { // e.g., ICAP OPTIONS lack client
             strncpy(buf, "-", bufsz);
-        else
-            cache.caddr.NtoA(buf, bufsz);
+            return;
+        } else
+            log_ip = cache.caddr;
+
+    // Apply so-called 'privacy masking' to IPv4 clients
+    // - localhost IP is always shown in full
+    // - IPv4 clients masked with client_netmask
+    // - IPv6 clients use 'privacy addressing' instead.
+
+    if (!log_ip.IsLocalhost() && log_ip.IsIPv4())
+        log_ip.ApplyMask(Config.Addrs.client_netmask);
+
+    log_ip.NtoA(buf, bufsz);
 }
 
 AccessLogEntry::~AccessLogEntry()
diff -u -r -N squid-3.3.11/src/auth/basic/auth_basic.cc squid-3.3.12/src/auth/basic/auth_basic.cc
--- squid-3.3.11/src/auth/basic/auth_basic.cc	2013-12-01 02:55:13.000000000 +1300
+++ squid-3.3.12/src/auth/basic/auth_basic.cc	2014-03-09 18:24:25.000000000 +1300
@@ -195,25 +195,6 @@
     helperStats(sentry, basicauthenticators, "Basic Authenticator Statistics");
 }
 
-static Auth::User::Pointer
-authBasicAuthUserFindUsername(const char *username)
-{
-    AuthUserHashPointer *usernamehash;
-    debugs(29, 9, HERE << "Looking for user '" << username << "'");
-
-    if (username && (usernamehash = static_cast<AuthUserHashPointer *>(hash_lookup(proxy_auth_username_cache, username)))) {
-        while (usernamehash) {
-            if ((usernamehash->user()->auth_type == Auth::AUTH_BASIC) &&
-                    !strcmp(username, (char const *)usernamehash->key))
-                return usernamehash->user();
-
-            usernamehash = static_cast<AuthUserHashPointer *>(usernamehash->next);
-        }
-    }
-
-    return NULL;
-}
-
 char *
 Auth::Basic::Config::decodeCleartext(const char *httpAuthHeader)
 {
@@ -310,7 +291,7 @@
     /* now lookup and see if we have a matching auth_user structure in memory. */
     Auth::User::Pointer auth_user;
 
-    if ((auth_user = authBasicAuthUserFindUsername(lb->username())) == NULL) {
+    if ((auth_user = findUserInCache(lb->username(), Auth::AUTH_BASIC)) == NULL) {
         /* the user doesn't exist in the username cache yet */
         /* save the credentials */
         debugs(29, 9, HERE << "Creating new user '" << lb->username() << "'");
diff -u -r -N squid-3.3.11/src/auth/Config.cc squid-3.3.12/src/auth/Config.cc
--- squid-3.3.11/src/auth/Config.cc	2013-12-01 02:55:13.000000000 +1300
+++ squid-3.3.12/src/auth/Config.cc	2014-03-09 18:24:25.000000000 +1300
@@ -32,6 +32,7 @@
 
 #include "squid.h"
 #include "auth/Config.h"
+#include "auth/Gadgets.h"
 #include "auth/UserRequest.h"
 #include "Debug.h"
 #include "globals.h"
@@ -76,3 +77,22 @@
 void
 Auth::Config::registerWithCacheManager(void)
 {}
+
+Auth::User::Pointer
+Auth::Config::findUserInCache(const char *nameKey, Auth::Type authType)
+{
+    AuthUserHashPointer *usernamehash;
+    debugs(29, 9, "Looking for user '" << nameKey << "'");
+
+    if (nameKey && (usernamehash = static_cast<AuthUserHashPointer *>(hash_lookup(proxy_auth_username_cache, nameKey)))) {
+        while (usernamehash) {
+            if ((usernamehash->user()->auth_type == authType) &&
+                    !strcmp(nameKey, (char const *)usernamehash->key))
+                return usernamehash->user();
+
+            usernamehash = static_cast<AuthUserHashPointer *>(usernamehash->next);
+        }
+    }
+
+    return NULL;
+}
diff -u -r -N squid-3.3.11/src/auth/Config.h squid-3.3.12/src/auth/Config.h
--- squid-3.3.11/src/auth/Config.h	2013-12-01 02:55:13.000000000 +1300
+++ squid-3.3.12/src/auth/Config.h	2014-03-09 18:24:25.000000000 +1300
@@ -122,6 +122,9 @@
     /** add headers as needed when challenging for auth */
     virtual void fixHeader(UserRequest::Pointer, HttpReply *, http_hdr_type, HttpRequest *) = 0;
 
+    /// Find any existing user credentials in the authentication cache by name and type.
+    virtual Auth::User::Pointer findUserInCache(const char *nameKey, Auth::Type type);
+
     /** prepare to handle requests */
     virtual void init(Config *) = 0;
 
diff -u -r -N squid-3.3.11/src/auth/digest/auth_digest.cc squid-3.3.12/src/auth/digest/auth_digest.cc
--- squid-3.3.11/src/auth/digest/auth_digest.cc	2013-12-01 02:55:13.000000000 +1300
+++ squid-3.3.12/src/auth/digest/auth_digest.cc	2014-03-09 18:24:25.000000000 +1300
@@ -476,25 +476,6 @@
     authDigestNonceUnlink(nonce);
 }
 
-/* USER related functions */
-static Auth::User::Pointer
-authDigestUserFindUsername(const char *username)
-{
-    AuthUserHashPointer *usernamehash;
-    debugs(29, 9, HERE << "Looking for user '" << username << "'");
-
-    if (username && (usernamehash = static_cast < AuthUserHashPointer * >(hash_lookup(proxy_auth_username_cache, username)))) {
-        while ((usernamehash->user()->auth_type != Auth::AUTH_DIGEST) && (usernamehash->next))
-            usernamehash = static_cast<AuthUserHashPointer *>(usernamehash->next);
-
-        if (usernamehash->user()->auth_type == Auth::AUTH_DIGEST) {
-            return usernamehash->user();
-        }
-    }
-
-    return NULL;
-}
-
 void
 Auth::Digest::Config::rotateHelpers()
 {
@@ -729,7 +710,7 @@
 {
     dlink_node *node;
 
-    if (!user || !nonce)
+    if (!user || !nonce || !nonce->user)
         return;
 
     Auth::Digest::User *digest_user = user;
@@ -1076,7 +1057,7 @@
 
     Auth::User::Pointer auth_user;
 
-    if ((auth_user = authDigestUserFindUsername(username)) == NULL) {
+    if ((auth_user = findUserInCache(username, Auth::AUTH_DIGEST)) == NULL) {
         /* the user doesn't exist in the username cache yet */
         debugs(29, 9, HERE << "Creating new digest user '" << username << "'");
         digest_user = new Auth::Digest::User(this);
diff -u -r -N squid-3.3.11/src/client_side.cc squid-3.3.12/src/client_side.cc
--- squid-3.3.11/src/client_side.cc	2013-12-01 02:55:13.000000000 +1300
+++ squid-3.3.12/src/client_side.cc	2014-03-09 18:24:25.000000000 +1300
@@ -1281,9 +1281,7 @@
          * offset data, but we won't be requesting it.
          * So, we can either re-request, or generate an error
          */
-        debugs(33, 3, "clientBuildRangeHeader: will not do ranges: " << range_err << ".");
-        delete http->request->range;
-        http->request->range = NULL;
+        http->request->ignoreRange(range_err);
     } else {
         /* XXX: TODO: Review, this unconditional set may be wrong. - TODO: review. */
         httpStatusLineSet(&rep->sline, rep->sline.version,
@@ -1662,9 +1660,16 @@
 int64_t
 ClientSocketContext::getNextRangeOffset() const
 {
+    debugs (33, 5, "range: " << http->request->range <<
+            "; http offset " << http->out.offset <<
+            "; reply " << reply);
+
+    // XXX: This method is called from many places, including pullData() which
+    // may be called before prepareReply() [on some Squid-generated errors].
+    // Hence, we may not even know yet whether we should honor/do ranges.
+
     if (http->request->range) {
         /* offset in range specs does not count the prefix of an http msg */
-        debugs (33, 5, "ClientSocketContext::getNextRangeOffset: http offset " << http->out.offset);
         /* check: reply was parsed and range iterator was initialized */
         assert(http->range_iter.valid);
         /* filter out data according to range specs */
@@ -1701,7 +1706,7 @@
 void
 ClientSocketContext::pullData()
 {
-    debugs(33, 5, HERE << clientConnection << " attempting to pull upstream data");
+    debugs(33, 5, reply << " written " << http->out.size << " into " << clientConnection);
 
     /* More data will be coming from the stream. */
     StoreIOBuffer readBuffer;
@@ -2492,7 +2497,7 @@
         clientReplyContext *repContext = dynamic_cast<clientReplyContext *>(node->data.getRaw());
         assert(repContext);
         debugs(33, 5, "Responding with delated error for " << http->uri);
-        repContext->setReplyToStoreEntry(sslServerBump->entry);
+        repContext->setReplyToStoreEntry(sslServerBump->entry, "delayed SslBump error");
 
         // save the original request for logging purposes
         if (!context->http->al->request)
diff -u -r -N squid-3.3.11/src/client_side_reply.cc squid-3.3.12/src/client_side_reply.cc
--- squid-3.3.11/src/client_side_reply.cc	2013-12-01 02:55:13.000000000 +1300
+++ squid-3.3.12/src/client_side_reply.cc	2014-03-09 18:24:25.000000000 +1300
@@ -134,13 +134,18 @@
 
     http->al->http.code = errstate->httpStatus;
 
+    if (http->request)
+        http->request->ignoreRange("responding with a Squid-generated error");
+
     createStoreEntry(method, RequestFlags());
     assert(errstate->callback_data == NULL);
     errorAppendEntry(http->storeEntry(), errstate);
     /* Now the caller reads to get this */
 }
 
-void clientReplyContext::setReplyToStoreEntry(StoreEntry *entry)
+// Assumes that the entry contains an error response without Content-Range.
+// To use with regular entries, make HTTP Range header removal conditional.
+void clientReplyContext::setReplyToStoreEntry(StoreEntry *entry, const char *reason)
 {
     entry->lock(); // removeClientStoreReference() unlocks
     sc = storeClientListAdd(entry, this);
@@ -149,6 +154,8 @@
 #endif
     reqofs = 0;
     reqsize = 0;
+    if (http->request)
+        http->request->ignoreRange(reason);
     flags.storelogiccomplete = 1;
     http->storeEntry(entry);
 }
@@ -507,6 +514,7 @@
 
     if (strcmp(e->mem_obj->url, urlCanonical(r)) != 0) {
         debugs(33, DBG_IMPORTANT, "clientProcessHit: URL mismatch, '" << e->mem_obj->url << "' != '" << urlCanonical(r) << "'");
+        http->logType = LOG_TCP_MISS; // we lack a more precise LOG_*_MISS code
         processMiss();
         return;
     }
@@ -538,6 +546,7 @@
     case VARY_CANCEL:
         /* varyEvaluateMatch found a object loop. Process as miss */
         debugs(88, DBG_IMPORTANT, "clientProcessHit: Vary object loop!");
+        http->logType = LOG_TCP_MISS; // we lack a more precise LOG_*_MISS code
         processMiss();
         return;
     }
diff -u -r -N squid-3.3.11/src/client_side_reply.h squid-3.3.12/src/client_side_reply.h
--- squid-3.3.11/src/client_side_reply.h	2013-12-01 02:55:13.000000000 +1300
+++ squid-3.3.12/src/client_side_reply.h	2014-03-09 18:24:25.000000000 +1300
@@ -73,7 +73,7 @@
     int storeOKTransferDone() const;
     int storeNotOKTransferDone() const;
     /// replaces current response store entry with the given one
-    void setReplyToStoreEntry(StoreEntry *e);
+    void setReplyToStoreEntry(StoreEntry *e, const char *reason);
     /// builds error using clientBuildError() and calls setReplyToError() below
     void setReplyToError(err_type, http_status, const HttpRequestMethod&, char const *, Ip::Address &, HttpRequest *, const char *,
 #if USE_AUTH
diff -u -r -N squid-3.3.11/src/client_side_request.cc squid-3.3.12/src/client_side_request.cc
--- squid-3.3.11/src/client_side_request.cc	2013-12-01 02:55:13.000000000 +1300
+++ squid-3.3.12/src/client_side_request.cc	2014-03-09 18:24:25.000000000 +1300
@@ -875,11 +875,12 @@
 #if ICAP_CLIENT
     Adaptation::Icap::History::Pointer ih = request->icapHistory();
     if (ih != NULL) {
-        if (getConn() != NULL) {
+        if (getConn() != NULL && getConn()->clientConnection != NULL) {
             ih->rfc931 = getConn()->clientConnection->rfc931;
 #if USE_SSL
-            assert(getConn()->clientConnection != NULL);
-            ih->ssluser = sslGetUserEmail(fd_table[getConn()->clientConnection->fd].ssl);
+            if (getConn()->clientConnection->isOpen()) {
+                ih->ssluser = sslGetUserEmail(fd_table[getConn()->clientConnection->fd].ssl);
+            }
 #endif
         }
         ih->log_uri = log_uri;
@@ -1130,8 +1131,7 @@
     else {
         req_hdr->delById(HDR_RANGE);
         req_hdr->delById(HDR_REQUEST_RANGE);
-        delete request->range;
-        request->range = NULL;
+        request->ignoreRange("neither HEAD nor GET");
     }
 
     if (req_hdr->has(HDR_AUTHORIZATION))
@@ -1663,7 +1663,7 @@
             clientStreamNode *node = (clientStreamNode *)client_stream.tail->prev->data;
             clientReplyContext *repContext = dynamic_cast<clientReplyContext *>(node->data.getRaw());
             assert (repContext);
-            repContext->setReplyToStoreEntry(e);
+            repContext->setReplyToStoreEntry(e, "immediate SslBump error");
             errorAppendEntry(e, calloutContext->error);
             calloutContext->error = NULL;
             if (calloutContext->readNextRequest)
diff -u -r -N squid-3.3.11/src/http.cc squid-3.3.12/src/http.cc
--- squid-3.3.11/src/http.cc	2013-12-01 02:55:13.000000000 +1300
+++ squid-3.3.12/src/http.cc	2014-03-09 18:24:25.000000000 +1300
@@ -1736,8 +1736,7 @@
         /* don't cache the result */
         request->flags.cachable = 0;
         /* pretend it's not a range request */
-        delete request->range;
-        request->range = NULL;
+        request->ignoreRange("want to request the whole object");
         request->flags.isRanged=false;
     }
 
diff -u -r -N squid-3.3.11/src/HttpRequest.cc squid-3.3.12/src/HttpRequest.cc
--- squid-3.3.11/src/HttpRequest.cc	2013-12-01 02:55:13.000000000 +1300
+++ squid-3.3.12/src/HttpRequest.cc	2014-03-09 18:24:25.000000000 +1300
@@ -658,6 +658,20 @@
     return rangeOffsetLimit;
 }
 
+void
+HttpRequest::ignoreRange(const char *reason)
+{
+    if (range) {
+        debugs(73, 3, static_cast<void*>(range) << " for " << reason);
+        delete range;
+        range = NULL;
+    }
+    // Some callers also reset isRanged but it may not be safe for all callers:
+    // isRanged is used to determine whether a weak ETag comparison is allowed,
+    // and that check should not ignore the Range header if it was present.
+    // TODO: Some callers also delete HDR_RANGE, HDR_REQUEST_RANGE. Should we?
+}
+
 bool
 HttpRequest::canHandle1xx() const
 {
diff -u -r -N squid-3.3.11/src/HttpRequest.h squid-3.3.12/src/HttpRequest.h
--- squid-3.3.11/src/HttpRequest.h	2013-12-01 02:55:13.000000000 +1300
+++ squid-3.3.12/src/HttpRequest.h	2014-03-09 18:24:25.000000000 +1300
@@ -246,6 +246,8 @@
      */
     CbcPointer<ConnStateData> clientConnectionManager;
 
+    /// forgets about the cached Range header (for a reason)
+    void ignoreRange(const char *reason);
     int64_t getRangeOffsetLimit(); /* the result of this function gets cached in rangeOffsetLimit */
 
 private:
diff -u -r -N squid-3.3.11/src/MemBlob.cc squid-3.3.12/src/MemBlob.cc
--- squid-3.3.11/src/MemBlob.cc	2013-12-01 02:55:13.000000000 +1300
+++ squid-3.3.12/src/MemBlob.cc	2014-03-09 18:24:25.000000000 +1300
@@ -122,8 +122,7 @@
     if (n > 0) { // appending zero bytes is allowed but only affects the stats
         Must(willFit(n));
         Must(source);
-        /// \note memcpy() is safe because we copy to an unused area
-        memcpy(mem + size, source, n);
+        memmove(mem + size, source, n);
         size += n;
     }
     ++Stats.append;
diff -u -r -N squid-3.3.11/src/MemStore.cc squid-3.3.12/src/MemStore.cc
--- squid-3.3.11/src/MemStore.cc	2013-12-01 02:55:13.000000000 +1300
+++ squid-3.3.12/src/MemStore.cc	2014-03-09 18:24:25.000000000 +1300
@@ -310,6 +310,12 @@
         return;
     }
 
+    if (e.mem_obj->vary_headers) {
+        // XXX: We must store/load SerialisedMetaData to cache Vary in RAM
+        debugs(20, 5, "Vary not yet supported: " << e.mem_obj->vary_headers);
+        return;
+    }
+
     keep(e); // may still fail
 }
 
diff -u -r -N squid-3.3.11/src/store.cc squid-3.3.12/src/store.cc
--- squid-3.3.11/src/store.cc	2013-12-01 02:55:13.000000000 +1300
+++ squid-3.3.12/src/store.cc	2014-03-09 18:24:25.000000000 +1300
@@ -761,7 +761,7 @@
             StoreEntry *pe = storeCreateEntry(mem_obj->url, mem_obj->log_url, request->flags, request->method);
             /* We are allowed to do this typecast */
             HttpReply *rep = new HttpReply;
-            rep->setHeaders(HTTP_OK, "Internal marker object", "x-squid-internal/vary", -1, -1, squid_curtime + 100000);
+            rep->setHeaders(HTTP_OK, "Internal marker object", "x-squid-internal/vary", 0, -1, squid_curtime + 100000);
             vary = mem_obj->getReply()->header.getList(HDR_VARY);
 
             if (vary.size()) {
@@ -780,12 +780,14 @@
             }
 
 #endif
-            pe->replaceHttpReply(rep);
+            pe->replaceHttpReply(rep, false); // no write until key is public
 
             pe->timestampsSet();
 
             pe->makePublic();
 
+            pe->startWriting(); // after makePublic()
+
             pe->complete();
 
             pe->unlock();
diff -u -r -N squid-3.3.11/src/tools.cc squid-3.3.12/src/tools.cc
--- squid-3.3.11/src/tools.cc	2013-12-01 02:55:13.000000000 +1300
+++ squid-3.3.12/src/tools.cc	2014-03-09 18:24:25.000000000 +1300
@@ -128,7 +128,14 @@
     FILE *fp = NULL;
     static char command[256];
 
-    const mode_t prev_umask=umask(S_IRWXU);
+    /*
+     * NP: umask() takes the mask of bits we DONT want set.
+     *
+     * We want the current user to have read/write access
+     * and since this file will be passed to mailsystem,
+     * the group and other must have read access.
+     */
+    const mode_t prev_umask=umask(S_IXUSR|S_IXGRP|S_IWGRP|S_IWOTH|S_IXOTH);
 
 #if HAVE_MKSTEMP
     char filename[] = "/tmp/squid-XXXXXX";
