diff -u -N -r squid-3.0.STABLE4/ChangeLog squid-3.0.STABLE5/ChangeLog
--- squid-3.0.STABLE4/ChangeLog	2008-04-01 23:54:25.000000000 +1200
+++ squid-3.0.STABLE5/ChangeLog	2008-04-29 15:43:22.000000000 +1200
@@ -1,3 +1,16 @@
+Changes to squid-3.0.STABLE5 (28 Apr 2008):
+
+	- Support for resolv.conf 'domain' option
+	- Improved URI support, including
+		longer URI up to 8192 bytes accepted
+		better handling of intercepted URI
+		better port for non-FQDN URI lookups
+	- Improved logging, including
+		Bug 3210 fixed: incorrect timestamp format in earlier 3.0 releases.
+		Fixed 'log_ip_on_direct' option behaviour
+	- Support for profiling on x86 64-bit systems
+	- .. and other bugs and minor code cleanups.
+
 Changes to squid-3.0.STABLE4 (2 Apr 2008):
 
 	- Bug 2288: compile error slipped into STABLE3.
diff -u -N -r squid-3.0.STABLE4/configure squid-3.0.STABLE5/configure
--- squid-3.0.STABLE4/configure	2008-04-01 23:54:39.000000000 +1200
+++ squid-3.0.STABLE5/configure	2008-04-29 15:43:33.000000000 +1200
@@ -1,7 +1,7 @@
 #! /bin/sh
 # From configure.in Revision: 1.488.2.3 .
 # Guess values for system-dependent variables and create Makefiles.
-# Generated by GNU Autoconf 2.61 for Squid Web Proxy 3.0.STABLE4.
+# Generated by GNU Autoconf 2.61 for Squid Web Proxy 3.0.STABLE5.
 #
 # Report bugs to <http://www.squid-cache.org/bugs/>.
 #
@@ -729,8 +729,8 @@
 # Identity of this package.
 PACKAGE_NAME='Squid Web Proxy'
 PACKAGE_TARNAME='squid'
-PACKAGE_VERSION='3.0.STABLE4'
-PACKAGE_STRING='Squid Web Proxy 3.0.STABLE4'
+PACKAGE_VERSION='3.0.STABLE5'
+PACKAGE_STRING='Squid Web Proxy 3.0.STABLE5'
 PACKAGE_BUGREPORT='http://www.squid-cache.org/bugs/'
 
 ac_unique_file="src/main.cc"
@@ -1507,7 +1507,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.0.STABLE4 to adapt to many kinds of systems.
+\`configure' configures Squid Web Proxy 3.0.STABLE5 to adapt to many kinds of systems.
 
 Usage: $0 [OPTION]... [VAR=VALUE]...
 
@@ -1577,7 +1577,7 @@
 
 if test -n "$ac_init_help"; then
   case $ac_init_help in
-     short | recursive ) echo "Configuration of Squid Web Proxy 3.0.STABLE4:";;
+     short | recursive ) echo "Configuration of Squid Web Proxy 3.0.STABLE5:";;
    esac
   cat <<\_ACEOF
 
@@ -1886,7 +1886,7 @@
 test -n "$ac_init_help" && exit $ac_status
 if $ac_init_version; then
   cat <<\_ACEOF
-Squid Web Proxy configure 3.0.STABLE4
+Squid Web Proxy configure 3.0.STABLE5
 generated by GNU Autoconf 2.61
 
 Copyright (C) 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001,
@@ -1900,7 +1900,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.0.STABLE4, which was
+It was created by Squid Web Proxy $as_me 3.0.STABLE5, which was
 generated by GNU Autoconf 2.61.  Invocation command line was
 
   $ $0 $@
@@ -2574,7 +2574,7 @@
 
 # Define the identity of the package.
  PACKAGE='squid'
- VERSION='3.0.STABLE4'
+ VERSION='3.0.STABLE5'
 
 
 cat >>confdefs.h <<_ACEOF
@@ -22976,7 +22976,7 @@
   SQUID_CPPUNIT_LA=''
   SQUID_CPPUNIT_INC="`$CPPUNITCONFIG --cflags`"
 else
-  echo "cppunit does not apear to be installed. squid does not require this, but code testing with 'make check' will fail."
+  echo "cppunit does not appear to be installed. squid does not require this, but code testing with 'make check' will fail."
   SQUID_CPPUNIT_LA=''
   SQUID_CPPUNIT_LIBS=''
   SQUID_CPPUNIT_INC=''
@@ -43330,6 +43330,92 @@
 
 fi
 
+{ echo "$as_me:$LINENO: checking if strnstr is well implemented" >&5
+echo $ECHO_N "checking if strnstr is well implemented... $ECHO_C" >&6; }
+if test "${ac_cv_func_strnstr+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  if test "$cross_compiling" = yes; then
+  { { echo "$as_me:$LINENO: error: cannot run test program while cross compiling
+See \`config.log' for more details." >&5
+echo "$as_me: error: cannot run test program while cross compiling
+See \`config.log' for more details." >&2;}
+   { (exit 1); exit 1; }; }
+else
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+    // we expect this to succeed, or crash on over-run.
+    // if it passes otherwise we may need a better check.
+int main(int argc, char **argv)
+{
+    int size = 20;
+    char *str = malloc(size);
+    memset(str, 'x', size);
+    strnstr(str, "fubar", size);
+    return 0;
+}
+
+_ACEOF
+rm -f conftest$ac_exeext
+if { (ac_try="$ac_link"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+  (eval "$ac_link") 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } && { ac_try='./conftest$ac_exeext'
+  { (case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+  (eval "$ac_try") 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_func_strnstr="yes"
+else
+  echo "$as_me: program exited with status $ac_status" >&5
+echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+( exit $ac_status )
+ac_cv_func_strnstr="no"
+fi
+rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext
+fi
+
+
+
+fi
+{ echo "$as_me:$LINENO: result: $ac_cv_func_strnstr" >&5
+echo "${ECHO_T}$ac_cv_func_strnstr" >&6; }
+if test "$ac_cv_func_strnstr" = "yes" ; then
+
+cat >>confdefs.h <<\_ACEOF
+#define HAVE_STRNSTR 1
+_ACEOF
+
+else
+
+cat >>confdefs.h <<\_ACEOF
+#define HAVE_STRNSTR 0
+_ACEOF
+
+fi
+
+
 
 
 if false; then
@@ -45406,7 +45492,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.0.STABLE4, which was
+This file was extended by Squid Web Proxy $as_me 3.0.STABLE5, which was
 generated by GNU Autoconf 2.61.  Invocation command line was
 
   CONFIG_FILES    = $CONFIG_FILES
@@ -45459,7 +45545,7 @@
 _ACEOF
 cat >>$CONFIG_STATUS <<_ACEOF
 ac_cs_version="\\
-Squid Web Proxy config.status 3.0.STABLE4
+Squid Web Proxy config.status 3.0.STABLE5
 configured by $0, generated by GNU Autoconf 2.61,
   with options \\"`echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`\\"
 
diff -u -N -r squid-3.0.STABLE4/configure.in squid-3.0.STABLE5/configure.in
--- squid-3.0.STABLE4/configure.in	2008-04-01 23:54:39.000000000 +1200
+++ squid-3.0.STABLE5/configure.in	2008-04-29 15:43:33.000000000 +1200
@@ -5,7 +5,7 @@
 dnl
 dnl
 dnl
-AC_INIT(Squid Web Proxy, 3.0.STABLE4, http://www.squid-cache.org/bugs/, squid)
+AC_INIT(Squid Web Proxy, 3.0.STABLE5, http://www.squid-cache.org/bugs/, squid)
 AC_PREREQ(2.52)
 AM_CONFIG_HEADER(include/autoconf.h)
 AC_CONFIG_AUX_DIR(cfgaux)
@@ -1745,7 +1745,7 @@
   SQUID_CPPUNIT_LA=''
   SQUID_CPPUNIT_INC="`$CPPUNITCONFIG --cflags`"
 else
-  echo "cppunit does not apear to be installed. squid does not require this, but code testing with 'make check' will fail."
+  echo "cppunit does not appear to be installed. squid does not require this, but code testing with 'make check' will fail."
   SQUID_CPPUNIT_LA='' 
   SQUID_CPPUNIT_LIBS=''
   SQUID_CPPUNIT_INC=''
@@ -2666,6 +2666,34 @@
   AC_DEFINE(HAVE_SETRESUID,1,[Yay! Another Linux brokenness.  Its not good enough to know that setresuid() exists, because RedHat 5.0 declare setresuid() but doesn't implement it.])
 fi
 
+dnl Yay!  This one is  a MacOSX brokenness.  Its not good enough
+dnl to know that strnstr() exists, because MacOSX 10.4 have a bad
+dnl copy that crashes with a buffer over-run!
+dnl
+AC_CACHE_CHECK(if strnstr is well implemented, ac_cv_func_strnstr,
+  AC_TRY_RUN([
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+    // we expect this to succeed, or crash on over-run.
+    // if it passes otherwise we may need a better check.
+int main(int argc, char **argv)
+{
+    int size = 20;
+    char *str = malloc(size);
+    memset(str, 'x', size);
+    strnstr(str, "fubar", size);
+    return 0;
+}
+  ],ac_cv_func_strnstr="yes",ac_cv_func_strnstr="no")
+)
+if test "$ac_cv_func_strnstr" = "yes" ; then
+  AC_DEFINE(HAVE_STRNSTR,1,[Yay! We have a working strnstr!])
+else
+  AC_DEFINE(HAVE_STRNSTR,0,[Yay! A MacOS X brokenness. Its not good enough to know that strnstr() exists, because MacOSX 10.4 and earlier may have a buffer overrun.])
+fi
+
+
 AM_CONDITIONAL(NEED_OWN_STRSEP, false)
 if test "$ac_cv_func_strsep" = "no" ; then
   AM_CONDITIONAL(NEED_OWN_STRSEP, true)
diff -u -N -r squid-3.0.STABLE4/include/autoconf.h.in squid-3.0.STABLE5/include/autoconf.h.in
--- squid-3.0.STABLE4/include/autoconf.h.in	2008-04-01 23:54:33.000000000 +1200
+++ squid-3.0.STABLE5/include/autoconf.h.in	2008-04-29 15:43:28.000000000 +1200
@@ -562,6 +562,10 @@
 /* Define to 1 if you have the <string.h> header file. */
 #undef HAVE_STRING_H
 
+/* Yay! A MacOS X brokenness. Its not good enough to know that strnstr()
+   exists, because MacOSX 10.4 and earlier may have a buffer overrun. */
+#undef HAVE_STRNSTR
+
 /* Define to 1 if you have the `strsep' function. */
 #undef HAVE_STRSEP
 
diff -u -N -r squid-3.0.STABLE4/include/config.h squid-3.0.STABLE5/include/config.h
--- squid-3.0.STABLE4/include/config.h	2008-04-01 23:54:33.000000000 +1200
+++ squid-3.0.STABLE5/include/config.h	2008-04-29 15:43:28.000000000 +1200
@@ -461,4 +461,10 @@
 #define RUNNING_ON_VALGRIND 0
 #endif /* WITH_VALGRIND */
 
+
+/*
+ * strnstr() is needed. The OS may not provide a working copy.
+ */
+#include "strnstr.h"
+
 #endif /* SQUID_CONFIG_H */
diff -u -N -r squid-3.0.STABLE4/include/profiling.h squid-3.0.STABLE5/include/profiling.h
--- squid-3.0.STABLE4/include/profiling.h	2008-04-01 23:54:33.000000000 +1200
+++ squid-3.0.STABLE5/include/profiling.h	2008-04-29 15:43:28.000000000 +1200
@@ -30,6 +30,17 @@
     /* Note that "rdtsc" is relatively slow OP and stalls the CPU pipes, so use it wisely */
 }
 
+#elif defined(__x86_64) || defined(__x86_64__)
+static inline hrtime_t
+get_tick(void)
+{
+    uint32_t lo, hi;
+    // Based on an example in Wikipedia
+    /* We cannot use "=A", since this would use %rax on x86_64 */
+    asm volatile ("rdtsc" : "=a" (lo), "=d" (hi));
+    return (hrtime_t)hi << 32 | lo;
+}
+
 #elif defined(__alpha)
 static inline hrtime_t
 get_tick(void)
diff -u -N -r squid-3.0.STABLE4/include/strnstr.h squid-3.0.STABLE5/include/strnstr.h
--- squid-3.0.STABLE4/include/strnstr.h	1970-01-01 12:00:00.000000000 +1200
+++ squid-3.0.STABLE5/include/strnstr.h	2008-04-29 15:43:28.000000000 +1200
@@ -0,0 +1,16 @@
+/*
+ * Squid VCS $Id$
+ */
+#include "config.h"
+
+#if HAVE_STRNSTR
+
+/* Is strnstr exists and is usablewe do so. */
+#define squid_strnstr(a,b,c)	strnstr(a,b,c)
+
+#else /* not HAVE_STRNSTR */
+
+/* If its not usable we have our own copy imported from FreeBSD */
+const char * squid_strnstr(const char *s, const char *find, size_t slen);
+
+#endif /* HAVE_STRNSTR*/
diff -u -N -r squid-3.0.STABLE4/include/version.h squid-3.0.STABLE5/include/version.h
--- squid-3.0.STABLE4/include/version.h	2008-04-01 23:54:39.000000000 +1200
+++ squid-3.0.STABLE5/include/version.h	2008-04-29 15:43:33.000000000 +1200
@@ -9,5 +9,5 @@
  */
 
 #ifndef SQUID_RELEASE_TIME
-#define SQUID_RELEASE_TIME 1207050858
+#define SQUID_RELEASE_TIME 1209440593
 #endif
diff -u -N -r squid-3.0.STABLE4/lib/Makefile.am squid-3.0.STABLE5/lib/Makefile.am
--- squid-3.0.STABLE4/lib/Makefile.am	2008-04-01 23:54:34.000000000 +1200
+++ squid-3.0.STABLE5/lib/Makefile.am	2008-04-29 15:43:28.000000000 +1200
@@ -68,6 +68,7 @@
 	safe_inet_addr.c \
 	$(SNPRINTFSOURCE) \
 	Splay.cc \
+	strnstr.cc \
 	$(STRSEPSOURCE) \
 	$(STRTOLLSOURCE) \
 	stub_memaccount.c \
diff -u -N -r squid-3.0.STABLE4/lib/Makefile.in squid-3.0.STABLE5/lib/Makefile.in
--- squid-3.0.STABLE4/lib/Makefile.in	2008-04-01 23:54:34.000000000 +1200
+++ squid-3.0.STABLE5/lib/Makefile.in	2008-04-29 15:43:28.000000000 +1200
@@ -60,8 +60,8 @@
 am__libmiscutil_a_SOURCES_DIST = MemPool.cc base64.c getfullhostname.c \
 	hash.c heap.c html_quote.c iso3307.c md5.c radix.c rfc1035.c \
 	rfc1123.c rfc1738.c rfc2617.c safe_inet_addr.c Splay.cc \
-	strsep.c strtoll.c stub_memaccount.c util.c uudecode.c \
-	assert.c xusleep.c Profiler.c win32lib.c
+	strnstr.cc strsep.c strtoll.c stub_memaccount.c util.c \
+	uudecode.c assert.c xusleep.c Profiler.c win32lib.c
 @NEED_OWN_STRSEP_TRUE@am__objects_1 = strsep.$(OBJEXT)
 @NEED_OWN_STRTOLL_TRUE@am__objects_2 = strtoll.$(OBJEXT)
 @ENABLE_XPROF_STATS_TRUE@am__objects_3 = Profiler.$(OBJEXT)
@@ -71,10 +71,10 @@
 	html_quote.$(OBJEXT) iso3307.$(OBJEXT) md5.$(OBJEXT) \
 	radix.$(OBJEXT) rfc1035.$(OBJEXT) rfc1123.$(OBJEXT) \
 	rfc1738.$(OBJEXT) rfc2617.$(OBJEXT) safe_inet_addr.$(OBJEXT) \
-	Splay.$(OBJEXT) $(am__objects_1) $(am__objects_2) \
-	stub_memaccount.$(OBJEXT) util.$(OBJEXT) uudecode.$(OBJEXT) \
-	assert.$(OBJEXT) xusleep.$(OBJEXT) $(am__objects_3) \
-	$(am__objects_4)
+	Splay.$(OBJEXT) strnstr.$(OBJEXT) $(am__objects_1) \
+	$(am__objects_2) stub_memaccount.$(OBJEXT) util.$(OBJEXT) \
+	uudecode.$(OBJEXT) assert.$(OBJEXT) xusleep.$(OBJEXT) \
+	$(am__objects_3) $(am__objects_4)
 libmiscutil_a_OBJECTS = $(am_libmiscutil_a_OBJECTS)
 libntlmauth_a_AR = $(AR) $(ARFLAGS)
 libntlmauth_a_DEPENDENCIES = @LIBOBJS@
@@ -396,6 +396,7 @@
 	safe_inet_addr.c \
 	$(SNPRINTFSOURCE) \
 	Splay.cc \
+	strnstr.cc \
 	$(STRSEPSOURCE) \
 	$(STRTOLLSOURCE) \
 	stub_memaccount.c \
@@ -530,6 +531,7 @@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/rfc2617.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/safe_inet_addr.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sspwin32.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/strnstr.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/strsep.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/strtoll.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/stub_memaccount.Po@am__quote@
diff -u -N -r squid-3.0.STABLE4/lib/strnstr.cc squid-3.0.STABLE5/lib/strnstr.cc
--- squid-3.0.STABLE4/lib/strnstr.cc	1970-01-01 12:00:00.000000000 +1200
+++ squid-3.0.STABLE5/lib/strnstr.cc	2008-04-29 15:43:29.000000000 +1200
@@ -0,0 +1,100 @@
+#ifndef _SQUID_COMPAT_STRNSTR_C_
+#define _SQUID_COMPAT_STRNSTR_C_
+/*
+ *  Shamelessly duplicated from the FreeBSD public sources
+ *  for use by the Squid Project under GNU Public License.
+ *
+ * Update/Maintenance History:
+ *
+ *    26-Apr-2008 : Copied from FreeBSD via OpenGrok
+ * 			- added protection around libray headers
+ * 			- added squid_ prefix for uniqueness
+ * 			  so we can use it where OS copy is broken.
+ *
+ * Squid VCS $Id$
+ *
+ *  Original License and code follows.
+ */
+
+#include "config.h"
+#include "strnstr.h"
+
+#if !HAVE_STRNSTR
+
+/*-
+ * Copyright (c) 2001 Mike Barcroft <mike@FreeBSD.org>
+ * Copyright (c) 1990, 1993
+ *	The Regents of the University of California.  All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Chris Torek.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *	This product includes software developed by the University of
+ *	California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * @(#)strstr.c	8.1 (Berkeley) 6/4/93
+ * $FreeBSD: src/lib/libc/string/strnstr.c,v 1.2.2.1 2001/12/09 06:50:03 mike Exp $
+ * $DragonFly: src/lib/libc/string/strnstr.c,v 1.4 2006/03/20 17:24:20 dillon Exp $
+ */
+
+#if HAVE_SYS_TYPES_H
+#include <sys/types.h>
+#endif
+#if HAVE_STRING_H
+#include <string.h>
+#endif
+
+/*
+ * Find the first occurrence of find in s, where the search is limited to the
+ * first slen characters of s.
+ */
+const char *
+squid_strnstr(const char *s, const char *find, size_t slen)
+{
+	char c, sc;
+	size_t len;
+
+	if ((c = *find++) != '\0') {
+		len = strlen(find);
+		do {
+			do {
+				if (slen < 1 || (sc = *s) == '\0')
+					return (NULL);
+				--slen;
+				++s;
+			} while (sc != c);
+			if (len > slen)
+				return (NULL);
+		} while (strncmp(s, find, len) != 0);
+		s--;
+	}
+	return s;
+}
+
+#endif /* !HAVE_STRNSTR */
+#endif /* _SQUID_COMPAT_STRNSTR_C_ */
diff -u -N -r squid-3.0.STABLE4/src/access_log.cc squid-3.0.STABLE5/src/access_log.cc
--- squid-3.0.STABLE4/src/access_log.cc	2008-04-01 23:54:37.000000000 +1200
+++ squid-3.0.STABLE5/src/access_log.cc	2008-04-29 15:43:31.000000000 +1200
@@ -607,7 +607,7 @@
                 spec = fmt->data.timespec;
 
                 if (!spec)
-                    spec = "%d/%b/%Y %H:%M:%S";
+                    spec = "%d/%b/%Y:%H:%M:%S";
 
                 if (fmt->type == LFT_TIME_LOCALTIME)
                     t = localtime(&squid_curtime);
diff -u -N -r squid-3.0.STABLE4/src/BodyPipe.cc squid-3.0.STABLE5/src/BodyPipe.cc
--- squid-3.0.STABLE4/src/BodyPipe.cc	2008-04-01 23:54:35.000000000 +1200
+++ squid-3.0.STABLE5/src/BodyPipe.cc	2008-04-29 15:43:29.000000000 +1200
@@ -370,8 +370,11 @@
 
 BodyPipeCheckout::~BodyPipeCheckout()
 {
-	if (!checkedIn)
-		pipe.undoCheckOut(*this);
+	if (!checkedIn) {
+//		pipe.undoCheckOut(*this);
+                debugs(91, 2, "BodyPipeCheckout will gone without the checkin performed"); 
+                pipe.checkIn(*this);
+        }
 }
 
 void
diff -u -N -r squid-3.0.STABLE4/src/client_side.cc squid-3.0.STABLE5/src/client_side.cc
--- squid-3.0.STABLE4/src/client_side.cc	2008-04-01 23:54:37.000000000 +1200
+++ squid-3.0.STABLE5/src/client_side.cc	2008-04-29 15:43:31.000000000 +1200
@@ -1,6 +1,6 @@
 
 /*
- * $Id: client_side.cc,v 1.770 2007/12/04 03:35:52 hno Exp $
+ * $Id: client_side.cc,v 1.778 2008/02/26 18:43:58 rousskov Exp $
  *
  * DEBUG: section 33    Client-side Routines
  * AUTHOR: Duane Wessels
@@ -55,6 +55,7 @@
  * stream calls occur. Then we simply read as normal.
  */
 
+#include "config.h"
 #include "squid.h"
 #include "client_side.h"
 #include "clientStream.h"
@@ -1406,8 +1407,7 @@
     /* first update "i" if needed */
 
     if (!http->range_iter.debt()) {
-        debugs(33, 5, "ClientSocketContext::canPackMoreRanges: At end of current range spec for FD " <<
-               fd());
+        debugs(33, 5, "ClientSocketContext::canPackMoreRanges: At end of current range spec for FD " << fd());
 
         if (http->range_iter.pos.incrementable())
             ++http->range_iter.pos;
@@ -1463,7 +1463,7 @@
 void
 ClientSocketContext::pullData()
 {
-    debugs(33, 5, "ClientSocketContext::pullData: FD " << fd() << " attempting to pull upstream data");
+    debugs(33, 5, "ClientSocketContext::pullData: FD " << fd() );
 
     /* More data will be coming from the stream. */
     StoreIOBuffer readBuffer;
@@ -1490,8 +1490,7 @@
             /* filter out data according to range specs */
 
             if (!canPackMoreRanges()) {
-                debugs(33, 5, "ClientSocketContext::socketState: Range request has hit end of returnable range sequence on FD " <<
-                       fd());
+                debugs(33, 5, "ClientSocketContext::socketState: Range request has hit end of returnable range sequence on FD " << fd() );
 
                 if (http->request->flags.proxy_keepalive)
                     return STREAM_COMPLETE;
@@ -1921,7 +1920,11 @@
 
     debugs(33, 3, "parseHttpRequest: end = {" << end << "}");
 
-    if (strstr(req_hdr, "\r\r\n")) {
+    /*
+     * Check that the headers don't have double-CR.
+     * NP: strnstr is required so we don't search any possible binary body blobs.
+     */
+    if ( squid_strnstr(req_hdr, "\r\r\n", req_sz) ) {
         debugs(33, 1, "WARNING: suspicious HTTP request contains double CR");
         xfree(url);
         return parseHttpRequestAbort(conn, "error:double-CR");
@@ -1963,6 +1966,9 @@
         /* prepend our name & port */
         http->uri = xstrdup(internalLocalUri(NULL, url));
         http->flags.accel = 1;
+    } else if (conn->port->transparent) {
+	// Fallback on transparent if enabled, useful for "self" requests
+        prepareTransparentURL(conn, http, url, req_hdr);
     }
 
     if (!http->uri) {
diff -u -N -r squid-3.0.STABLE4/src/client_side_reply.cc squid-3.0.STABLE5/src/client_side_reply.cc
--- squid-3.0.STABLE4/src/client_side_reply.cc	2008-04-01 23:54:37.000000000 +1200
+++ squid-3.0.STABLE5/src/client_side_reply.cc	2008-04-29 15:43:31.000000000 +1200
@@ -352,68 +352,47 @@
         sendClientOldEntry();
     }
 
-    // we have a partial reply from the origin
-    else if (STORE_PENDING == http->storeEntry()->store_status && 0 == status) {
-        // header is too large, send old entry
-
-        if (reqsize >= HTTP_REQBUF_SZ) {
-            debugs(88, 3, "handleIMSReply: response from origin is too large '" << http->storeEntry()->url() << "', sending old entry to client" );
-            http->logType = LOG_TCP_REFRESH_FAIL;
-            sendClientOldEntry();
-        }
+    HttpReply *old_rep = (HttpReply *) old_entry->getReply();
 
-        // everything looks fine, we're just waiting for more data
-        else {
-            debugs(88, 3, "handleIMSReply: incomplete headers for '" << http->storeEntry()->url() << "', waiting for more data" );
-            reqofs = reqsize;
-            waitForMoreData();
-        }
-    }
+    // origin replied 304
 
-    // we have a reply from the origin
-    else {
-        HttpReply *old_rep = (HttpReply *) old_entry->getReply();
+    if (status == HTTP_NOT_MODIFIED) {
+	http->logType = LOG_TCP_REFRESH_UNMODIFIED;
 
-        // origin replied 304
+	// update headers on existing entry
+	HttpReply *old_rep = (HttpReply *) old_entry->getReply();
+	old_rep->updateOnNotModified(http->storeEntry()->getReply());
+	old_entry->timestampsSet();
 
-        if (status == HTTP_NOT_MODIFIED) {
-            http->logType = LOG_TCP_REFRESH_UNMODIFIED;
+	// if client sent IMS
 
-            // update headers on existing entry
-            HttpReply *old_rep = (HttpReply *) old_entry->getReply();
-            old_rep->updateOnNotModified(http->storeEntry()->getReply());
-            old_entry->timestampsSet();
-
-            // if client sent IMS
-
-            if (http->request->flags.ims) {
-                // forward the 304 from origin
-                debugs(88, 3, "handleIMSReply: origin replied 304, revalidating existing entry and forwarding 304 to client");
-                sendClientUpstreamResponse();
-            } else {
-                // send existing entry, it's still valid
-                debugs(88, 3, "handleIMSReply: origin replied 304, revalidating existing entry and sending " <<
-                       old_rep->sline.status << " to client");
-                sendClientOldEntry();
-            }
-        }
+	if (http->request->flags.ims) {
+	    // forward the 304 from origin
+	    debugs(88, 3, "handleIMSReply: origin replied 304, revalidating existing entry and forwarding 304 to client");
+	    sendClientUpstreamResponse();
+	} else {
+	    // send existing entry, it's still valid
+	    debugs(88, 3, "handleIMSReply: origin replied 304, revalidating existing entry and sending " <<
+		   old_rep->sline.status << " to client");
+	    sendClientOldEntry();
+	}
+    }
 
-        // origin replied with a non-error code
-        else if (status > HTTP_STATUS_NONE && status < HTTP_INTERNAL_SERVER_ERROR) {
-            // forward response from origin
-            http->logType = LOG_TCP_REFRESH_MODIFIED;
-            debugs(88, 3, "handleIMSReply: origin replied " << status << ", replacing existing entry and forwarding to client");
-            sendClientUpstreamResponse();
-        }
+    // origin replied with a non-error code
+    else if (status > HTTP_STATUS_NONE && status < HTTP_INTERNAL_SERVER_ERROR) {
+	// forward response from origin
+	http->logType = LOG_TCP_REFRESH_MODIFIED;
+	debugs(88, 3, "handleIMSReply: origin replied " << status << ", replacing existing entry and forwarding to client");
+	sendClientUpstreamResponse();
+    }
 
-        // origin replied with an error
-        else {
-            // ignore and let client have old entry
-            http->logType = LOG_TCP_REFRESH_FAIL;
-            debugs(88, 3, "handleIMSReply: origin replied with error " <<
-                   status << ", sending old entry (" << old_rep->sline.status << ") to client");
-            sendClientOldEntry();
-        }
+    // origin replied with an error
+    else {
+	// ignore and let client have old entry
+	http->logType = LOG_TCP_REFRESH_FAIL;
+	debugs(88, 3, "handleIMSReply: origin replied with error " <<
+	       status << ", sending old entry (" << old_rep->sline.status << ") to client");
+	sendClientOldEntry();
     }
 }
 
@@ -472,33 +451,6 @@
     /* update size of the request */
     reqsize = result.length + reqofs;
 
-    if (e->getReply()->sline.status == 0) {
-        /*
-         * we don't have full reply headers yet; either wait for more or
-         * punt to clientProcessMiss.
-         */
-
-        if (e->mem_status == IN_MEMORY || e->store_status == STORE_OK) {
-            processMiss();
-        } else if (result.length + reqofs >= HTTP_REQBUF_SZ
-                   && http->out.offset == 0) {
-            processMiss();
-        } else {
-            debugs(88, 3, "clientCacheHit: waiting for HTTP reply headers");
-            reqofs += result.length;
-            assert(reqofs <= HTTP_REQBUF_SZ);
-            /* get the next users' buffer */
-            StoreIOBuffer tempBuffer;
-            tempBuffer.offset = http->out.offset + reqofs;
-            tempBuffer.length = next()->readBuffer.length - reqofs;
-            tempBuffer.data = next()->readBuffer.data + reqofs;
-            storeClientCopy(sc, e,
-                            tempBuffer, CacheHit, this);
-        }
-
-        return;
-    }
-
     /*
      * Got the headers, now grok them
      */
@@ -1371,32 +1323,14 @@
 
 
 void
-clientReplyContext::buildReply(const char *buf, size_t size)
+clientReplyContext::cloneReply()
 {
-    size_t k = headersEnd(buf, size);
-
-    if (!k)
-        return;
-
     assert(reply == NULL);
 
-    HttpReply *rep = new HttpReply;
+    HttpReply *rep = http->storeEntry()->getReply()->clone();
 
     reply = HTTPMSGLOCK(rep);
 
-    if (!reply->parseCharBuf(buf, k)) {
-        /* parsing failure, get rid of the invalid reply */
-        HTTPMSGUNLOCK(reply);
-
-        if (http->request->range) {
-            debugs(0,0,HERE << "look for bug here");
-            /* this will fail and destroy request->range */
-            //          clientBuildRangeHeader(http, reply);
-        }
-
-        return;
-    }
-
     /* enforce 1.0 reply version */
     reply->sline.version = HttpVersion(1,0);
 
@@ -1703,32 +1637,6 @@
     return getNextNode();
 }
 
-void
-clientReplyContext::waitForMoreData ()
-{
-    debugs(88, 5, "clientReplyContext::waitForMoreData: Waiting for more data to parse reply headers in client side.");
-    /* We don't have enough to parse the metadata yet */
-    /* TODO: the store should give us out of band metadata and
-     * obsolete this routine 
-     */
-    /* wait for more to arrive */
-    startSendProcess();
-}
-
-void
-clientReplyContext::startSendProcess()
-{
-    debugs(88, 5, "clientReplyContext::startSendProcess: triggering store read to SendMoreData");
-    assert(reqofs <= HTTP_REQBUF_SZ);
-    /* TODO: copy into the supplied buffer */
-    StoreIOBuffer tempBuffer;
-    tempBuffer.offset = reqofs;
-    tempBuffer.length = next()->readBuffer.length - reqofs;
-    tempBuffer.data = next()->readBuffer.data + reqofs;
-    storeClientCopy(sc, http->storeEntry(),
-                    tempBuffer, SendMoreData, this);
-}
-
 /*
  * Calculates the maximum size allowed for an HTTP response
  */
@@ -1841,8 +1749,10 @@
     http->loggingEntry(http->storeEntry());
 
     ssize_t body_size = reqofs - reply->hdr_sz;
-
-    assert(body_size >= 0);
+    if (body_size < 0) {
+	reqofs = reply->hdr_sz;
+	body_size = 0;
+    }
 
     debugs(88, 3, "clientReplyContext::sendMoreData: Appending " <<
            (int) body_size << " bytes after " << reply->hdr_sz <<
@@ -1872,7 +1782,7 @@
 
     StoreIOBuffer tempBuffer;
     char *buf = next()->readBuffer.data;
-    char *body_buf = buf + reply->hdr_sz;
+    char *body_buf = buf + reply->hdr_sz - next()->readBuffer.offset;
 
     //Server side may disable ranges under some circumstances.
 
@@ -1916,23 +1826,11 @@
 
     char *body_buf = buf;
 
-    /* This is always valid until we get the headers as metadata from
-     * storeClientCopy. 
-     * Then it becomes reqofs == next->readBuffer.offset()
-     */
-    assert(reqofs == 0 || flags.storelogiccomplete);
-
-    if (flags.headersSent && buf != result.data) {
+    if (buf != result.data) {
         /* we've got to copy some data */
         assert(result.length <= next()->readBuffer.length);
         xmemcpy(buf, result.data, result.length);
         body_buf = buf;
-    } else if (!flags.headersSent &&
-               buf + reqofs !=result.data) {
-        /* we've got to copy some data */
-        assert(result.length + reqofs <= next()->readBuffer.length);
-        xmemcpy(buf + reqofs, result.data, result.length);
-        body_buf = buf;
     }
 
     /* We've got the final data to start pushing... */
@@ -1971,38 +1869,23 @@
         return;
     }
 
-    buildReply(buf, reqofs);
-
-    if (reply) {
+    cloneReply();
 
-        /* handle headers */
+    /* handle headers */
 
-        if (Config.onoff.log_mime_hdrs) {
-            size_t k;
+    if (Config.onoff.log_mime_hdrs) {
+	size_t k;
 
-            if ((k = headersEnd(buf, reqofs))) {
-                safe_free(http->al.headers.reply);
-                http->al.headers.reply = (char *)xcalloc(k + 1, 1);
-                xstrncpy(http->al.headers.reply, buf, k);
-            }
-        }
-
-        holdingBuffer = result;
-        processReplyAccess();
-        return;
-
-    } else if (reqofs < HTTP_REQBUF_SZ && entry->store_status == STORE_PENDING) {
-        waitForMoreData();
-        return;
-    } else {
-        debugs(88, 0, "clientReplyContext::sendMoreData: Unable to parse reply headers within a single HTTP_REQBUF_SZ length buffer");
-        StoreIOBuffer tempBuffer;
-        tempBuffer.flags.error = 1;
-        /* XXX FIXME: make an html error page here */
-        sendStreamError(tempBuffer);
-        return;
+	if ((k = headersEnd(buf, reqofs))) {
+	    safe_free(http->al.headers.reply);
+	    http->al.headers.reply = (char *)xcalloc(k + 1, 1);
+	    xstrncpy(http->al.headers.reply, buf, k);
+	}
     }
-    fatal ("clientReplyContext::sendMoreData: Unreachable code reached \n");
+
+    holdingBuffer = result;
+    processReplyAccess();
+    return;
 }
 
 
diff -u -N -r squid-3.0.STABLE4/src/client_side_reply.h squid-3.0.STABLE5/src/client_side_reply.h
--- squid-3.0.STABLE4/src/client_side_reply.h	2008-04-01 23:54:37.000000000 +1200
+++ squid-3.0.STABLE5/src/client_side_reply.h	2008-04-29 15:43:31.000000000 +1200
@@ -124,15 +124,13 @@
     bool errorInStream(StoreIOBuffer const &result, size_t const &sizeToProcess)const ;
     void sendStreamError(StoreIOBuffer const &result);
     void pushStreamData(StoreIOBuffer const &result, char *source);
-    void waitForMoreData ();
     clientStreamNode * next() const;
-    void startSendProcess();
     StoreIOBuffer holdingBuffer;
     HttpReply *reply;
     void processReplyAccess();
     static PF ProcessReplyAccessResult;
     void processReplyAccessResult(bool accessAllowed);
-    void buildReply(const char *buf, size_t size);
+    void cloneReply();
     void buildReplyHeader ();
     bool alwaysAllowResponse(http_status sline) const;
     int checkTransferDone();
diff -u -N -r squid-3.0.STABLE4/src/debug.cc squid-3.0.STABLE5/src/debug.cc
--- squid-3.0.STABLE4/src/debug.cc	2008-04-01 23:54:38.000000000 +1200
+++ squid-3.0.STABLE5/src/debug.cc	2008-04-29 15:43:31.000000000 +1200
@@ -1,5 +1,5 @@
 /*
- * $Id: debug.cc,v 1.106.2.1 2008/02/25 03:01:01 amosjeffries Exp $
+ * $Id: debug.cc,v 1.109 2008/02/26 18:43:30 rousskov Exp $
  *
  * DEBUG: section 0     Debug Routines
  * AUTHOR: Harvest Derived
@@ -35,7 +35,6 @@
 #include "squid.h"
 #include "Debug.h"
 #include "SquidTime.h"
-#include <sstream>
 
 int Debug::Levels[MAX_DEBUG_SECTIONS];
 int Debug::level;
@@ -735,21 +734,50 @@
     return Ctx_Descrs[ctx] ? Ctx_Descrs[ctx] : "<null>";
 }
 
+int Debug::TheDepth = 0;
+
 std::ostream &
 Debug::getDebugOut() {
-    assert (CurrentDebug == NULL);
-    CurrentDebug = new std::ostringstream();
-    // set default formatting flags
-    CurrentDebug->setf(std::ios::fixed);
-    CurrentDebug->precision(2);
+    assert(TheDepth >= 0);
+    ++TheDepth;
+    if (TheDepth > 1) {
+        assert(CurrentDebug);
+        *CurrentDebug << std::endl << "reentrant debuging " << TheDepth << "-{";
+    } else {
+        assert(!CurrentDebug);
+        CurrentDebug = new std::ostringstream();
+        // set default formatting flags
+        CurrentDebug->setf(std::ios::fixed);
+        CurrentDebug->precision(2);
+    }
     return *CurrentDebug;
 }
 
 void
 Debug::finishDebug() {
-    _db_print("%s\n", CurrentDebug->str().c_str());
-    delete CurrentDebug;
-    CurrentDebug = NULL;
+    assert(TheDepth >= 0);
+    assert(CurrentDebug);
+    if (TheDepth > 1) {
+        *CurrentDebug << "}-" << TheDepth << std::endl;
+    } else {
+        assert(TheDepth == 1);
+        _db_print("%s\n", CurrentDebug->str().c_str());
+        delete CurrentDebug;
+        CurrentDebug = NULL;
+    }
+    --TheDepth;
+}
+
+// Hack: replaces global ::xassert() to debug debugging assertions
+// Relies on assert macro calling xassert() without a specific scope.
+void
+Debug::xassert(const char *msg, const char *file, int line) {
+	
+    if (CurrentDebug) {
+        *CurrentDebug << "assertion failed: " << file << ":" << line <<
+            ": \"" << msg << "\"";
+    }
+    abort();
 }
 
 std::ostringstream (*Debug::CurrentDebug)(NULL);
diff -u -N -r squid-3.0.STABLE4/src/Debug.h squid-3.0.STABLE5/src/Debug.h
--- squid-3.0.STABLE4/src/Debug.h	2008-04-01 23:54:35.000000000 +1200
+++ squid-3.0.STABLE5/src/Debug.h	2008-04-29 15:43:29.000000000 +1200
@@ -1,6 +1,6 @@
 
 /*
- * $Id: Debug.h,v 1.10 2007/08/24 01:02:09 amosjeffries Exp $
+ * $Id: Debug.h,v 1.13 2008/02/26 18:43:30 rousskov Exp $
  *
  * DEBUG: section 0     Debug Routines
  * AUTHOR: Harvest Derived
@@ -64,7 +64,11 @@
     static void parseOptions(char const *);
 
 private:
+    // Hack: replaces global ::xassert() to debug debugging assertions
+    static void xassert(const char *msg, const char *file, int line);
+	
     static std::ostringstream *CurrentDebug;
+    static int TheDepth; // level of nested debugging calls
 };
 
 /* Debug stream */
diff -u -N -r squid-3.0.STABLE4/src/defines.h squid-3.0.STABLE5/src/defines.h
--- squid-3.0.STABLE4/src/defines.h	2008-04-01 23:54:38.000000000 +1200
+++ squid-3.0.STABLE5/src/defines.h	2008-04-29 15:43:31.000000000 +1200
@@ -153,7 +153,7 @@
 
 #define MAX_FILES_PER_DIR (1<<20)
 
-#define MAX_URL  4096
+#define MAX_URL  8192
 #define MAX_LOGIN_SZ  128
 
 #define PEER_MAX_ADDRESSES 10
diff -u -N -r squid-3.0.STABLE4/src/dns_internal.cc squid-3.0.STABLE5/src/dns_internal.cc
--- squid-3.0.STABLE4/src/dns_internal.cc	2008-04-01 23:54:38.000000000 +1200
+++ squid-3.0.STABLE5/src/dns_internal.cc	2008-04-29 15:43:31.000000000 +1200
@@ -288,7 +288,7 @@
 {
     FILE *fp;
     char buf[RESOLV_BUFSZ];
-    char *t;
+    const char *t;
     fp = fopen(_PATH_RESCONF, "r");
 
     if (fp == NULL) {
@@ -315,7 +315,18 @@
             debugs(78, 1, "Adding nameserver " << t << " from " << _PATH_RESCONF);
 
             idnsAddNameserver(t);
+        } else if (strcasecmp(t, "domain") == 0) {
+	    idnsFreeSearchpath();
+	    t = strtok(NULL, w_space);
+
+	    if (NULL == t)
+		continue;
+
+	    debugs(78, 1, "Adding domain " << t << " from " << _PATH_RESCONF);
+
+	    idnsAddPathComponent(t);
         } else if (strcasecmp(t, "search") == 0) {
+	    idnsFreeSearchpath();
             while (NULL != t) {
                 t = strtok(NULL, w_space);
 
@@ -344,6 +355,11 @@
             }
         }
     }
+    if (npc == 0 && (t = getMyHostname())) {
+	t = strchr(t, '.');
+	if (t)
+	    idnsAddPathComponent(t+1);
+    }
 
     fclose(fp);
 }
diff -u -N -r squid-3.0.STABLE4/src/forward.cc squid-3.0.STABLE5/src/forward.cc
--- squid-3.0.STABLE4/src/forward.cc	2008-04-01 23:54:38.000000000 +1200
+++ squid-3.0.STABLE5/src/forward.cc	2008-04-29 15:43:31.000000000 +1200
@@ -681,7 +681,7 @@
     assert(server_fd == aServerFD);
 
     if (Config.onoff.log_ip_on_direct && status != COMM_ERR_DNS && fs->code == HIER_DIRECT)
-        hierarchyNote(&request->hier, fs->code, fd_table[server_fd].ipaddr);
+        updateHierarchyInfo();
 
     if (status == COMM_ERR_DNS) {
         /*
@@ -741,7 +741,7 @@
     assert(fd == server_fd);
 
     if (Config.onoff.log_ip_on_direct && fs->code == HIER_DIRECT && fd_table[fd].ipaddr[0])
-        hierarchyNote(&request->hier, fs->code, fd_table[fd].ipaddr);
+        updateHierarchyInfo();
 
     if (entry->isEmpty()) {
         ErrorState *anErr = errorCon(ERR_CONNECT_FAIL, HTTP_GATEWAY_TIMEOUT, request);
@@ -815,12 +815,10 @@
         server_fd = fd;
         n_tries++;
 
-        if (!fs->_peer) {
+        if (!fs->_peer)
             origin_tries++;
-            hierarchyNote(&request->hier, fs->code, request->host);
-        } else {
-            hierarchyNote(&request->hier, fs->code, fs->_peer->host);
-        }
+
+        updateHierarchyInfo();
 
         comm_add_close_handler(fd, fwdServerClosedWrapper, this);
 
@@ -879,9 +877,7 @@
 
     commSetTimeout(fd, ctimeout, fwdConnectTimeoutWrapper, this);
 
-    if (fs->_peer) {
-        hierarchyNote(&request->hier, fs->code, fs->_peer->host);
-    } else {
+    if (!fs->_peer) {
 #if LINUX_TPROXY
 
         if (request->flags.tproxy) {
@@ -914,9 +910,9 @@
         }
 
 #endif
-        hierarchyNote(&request->hier, fs->code, request->host);
     }
 
+    updateHierarchyInfo();
     commConnectStart(fd, host, port, fwdConnectDoneWrapper, this);
 }
 
@@ -1200,6 +1196,38 @@
     }
 }
 
+// updates HierarchyLogEntry, guessing nextHop and its format
+void
+FwdState::updateHierarchyInfo()
+{
+    assert(request);
+
+    FwdServer *fs = servers;
+    assert(fs);
+
+    // some callers use one condition, some use the other; are they the same?
+    assert((fs->code == HIER_DIRECT) == !fs->_peer);
+
+    const char *nextHop = NULL;
+
+    if (fs->_peer) { 
+        // went to peer, log peer domain name
+        nextHop = fs->_peer->host;
+    } else {
+        // went DIRECT, must honor log_ip_on_direct
+
+        // XXX: or should we use request->host_addr here? how?
+        assert(server_fd >= 0);
+        nextHop = fd_table[server_fd].ipaddr;
+        if (!Config.onoff.log_ip_on_direct || !nextHop[0])
+            nextHop = request->host; // domain name
+	}
+
+    assert(nextHop);
+    hierarchyNote(&request->hier, fs->code, nextHop);
+}
+
+
 /**** PRIVATE NON-MEMBER FUNCTIONS ********************************************/
 
 static void
diff -u -N -r squid-3.0.STABLE4/src/forward.h squid-3.0.STABLE5/src/forward.h
--- squid-3.0.STABLE4/src/forward.h	2008-04-01 23:54:38.000000000 +1200
+++ squid-3.0.STABLE5/src/forward.h	2008-04-29 15:43:31.000000000 +1200
@@ -62,6 +62,7 @@
     void start(Pointer aSelf);
 
     static void logReplyStatus(int tries, http_status status);
+    void updateHierarchyInfo();
     void completed();
     void retryOrBail();
 
diff -u -N -r squid-3.0.STABLE4/src/http.cc squid-3.0.STABLE5/src/http.cc
--- squid-3.0.STABLE4/src/http.cc	2008-04-01 23:54:38.000000000 +1200
+++ squid-3.0.STABLE5/src/http.cc	2008-04-29 15:43:32.000000000 +1200
@@ -1213,12 +1213,16 @@
      * handler until we get a notification from someone that
      * its okay to read again.
      */
-    if (read_sz < 2)
-        return;
+    if (read_sz < 2) {
+	if (flags.headers_parsed)
+	    return;
+	else
+	    read_sz = 1024;
+    }
 
     if (flags.do_next_read) {
-        flags.do_next_read = 0;
-        entry->delayAwareRead(fd, readBuf->space(), read_sz, ReadReplyWrapper, this);
+	flags.do_next_read = 0;
+	entry->delayAwareRead(fd, readBuf->space(read_sz), read_sz, ReadReplyWrapper, this);
     }
 }
 
diff -u -N -r squid-3.0.STABLE4/src/HttpHdrContRange.cc squid-3.0.STABLE5/src/HttpHdrContRange.cc
--- squid-3.0.STABLE4/src/HttpHdrContRange.cc	2008-04-01 23:54:36.000000000 +1200
+++ squid-3.0.STABLE5/src/HttpHdrContRange.cc	2008-04-29 15:43:30.000000000 +1200
@@ -94,11 +94,10 @@
             return 0;
 
         spec->length = size_diff(last_pos + 1, spec->offset);
+        /* Ensure typecast is safe */
+        assert (spec->length >= 0);
     }
 
-    /* Ensure typecast is safe */
-    assert (spec->length >= 0);
-
     /* we managed to parse, check if the result makes sence */
     if (known_spec(spec->length) && spec->length == 0) {
         debugs(68, 2, "invalid range (" << spec->offset << " += " <<
diff -u -N -r squid-3.0.STABLE4/src/HttpHdrRange.cc squid-3.0.STABLE5/src/HttpHdrRange.cc
--- squid-3.0.STABLE4/src/HttpHdrRange.cc	2008-04-01 23:54:36.000000000 +1200
+++ squid-3.0.STABLE5/src/HttpHdrRange.cc	2008-04-29 15:43:30.000000000 +1200
@@ -260,7 +260,7 @@
         return 0;
 
     /* skip "bytes="; hack! */
-    pos = range_spec->buf() + 5;
+    pos = range_spec->buf() + 6;
 
     /* iterate through comma separated list */
     while (strListGetItem(range_spec, ',', &item, &ilen, &pos)) {
diff -u -N -r squid-3.0.STABLE4/src/HttpHeaderTools.cc squid-3.0.STABLE5/src/HttpHeaderTools.cc
--- squid-3.0.STABLE4/src/HttpHeaderTools.cc	2008-04-01 23:54:36.000000000 +1200
+++ squid-3.0.STABLE5/src/HttpHeaderTools.cc	2008-04-29 15:43:30.000000000 +1200
@@ -246,31 +246,26 @@
 strListGetItem(const String * str, char del, const char **item, int *ilen, const char **pos)
 {
     size_t len;
-    static char delim[2][3] = {
-                                  { '"', '?', 0},
-                                  { '"', '\\', 0}};
+    static char delim[3][8] = {
+			"\"?,",
+			"\"\\",
+			" ?,\t\r\n"
+    };
     int quoted = 0;
     assert(str && item && pos);
 
     delim[0][1] = del;
+    delim[2][1] = del;
 
-    if (*pos) {
-        if (!**pos)		/* end of string */
-            return 0;
-        else
-            (*pos)++;
-    } else {
+    if (!*pos) {
         *pos = str->buf();
 
         if (!*pos)
             return 0;
     }
 
-    /* skip leading ws (ltrim) */
-    *pos += xcountws(*pos);
-
-    /* skip leading delimiters */
-    *pos += strspn(*pos, delim[0]);
+    /* skip leading ws and delimiters */
+    *pos += strspn(*pos, delim[2]);
 
     *item = *pos;		/* remember item's start */
 
@@ -338,6 +333,7 @@
 int
 httpHeaderParseOffset(const char *start, int64_t * value)
 {
+    errno = 0;
     int64_t res = strtoll(start, NULL, 10);
     if (!res && EINVAL == errno)	/* maybe not portable? */
 	return 0;
diff -u -N -r squid-3.0.STABLE4/src/HttpMsg.cc squid-3.0.STABLE5/src/HttpMsg.cc
--- squid-3.0.STABLE4/src/HttpMsg.cc	2008-04-01 23:54:36.000000000 +1200
+++ squid-3.0.STABLE5/src/HttpMsg.cc	2008-04-29 15:43:30.000000000 +1200
@@ -1,6 +1,6 @@
 
 /*
- * $Id: HttpMsg.cc,v 1.43 2007/08/13 17:20:51 hno Exp $
+ * $Id: HttpMsg.cc,v 1.44 2007/12/21 23:50:24 hno Exp $
  *
  * DEBUG: section 74    HTTP Message
  * AUTHOR: Alex Rousskov
@@ -153,6 +153,14 @@
     // TODO: Remove? httpReplyParseStep() should do similar checks
     const size_t hdr_len = headersEnd(buf->content(), buf->contentSize());
 
+    // TODO: move to httpReplyParseStep()
+    if (hdr_len > Config.maxReplyHeaderSize || (hdr_len <= 0 && (size_t)buf->contentSize() > Config.maxReplyHeaderSize)) {
+        debugs(58, 1, "HttpMsg::parse: Too large reply header (" <<
+               hdr_len << " > " << Config.maxReplyHeaderSize);
+        *error = HTTP_HEADER_TOO_LARGE;
+        return false;
+    }
+
     if (hdr_len <= 0) {
         debugs(58, 3, "HttpMsg::parse: failed to find end of headers " <<
                "(eof: " << eof << ") in '" << buf->content() << "'");
@@ -163,14 +171,6 @@
         return false;
     }
 
-    // TODO: move to httpReplyParseStep()
-    if (hdr_len > Config.maxReplyHeaderSize) {
-        debugs(58, 1, "HttpMsg::parse: Too large reply header (" <<
-               hdr_len << " > " << Config.maxReplyHeaderSize);
-        *error = HTTP_HEADER_TOO_LARGE;
-        return false;
-    }
-
     if (!sanityCheckStartLine(buf, error)) {
         debugs(58,1, HERE << "first line of HTTP message is invalid");
         *error = HTTP_INVALID_HEADER;
diff -u -N -r squid-3.0.STABLE4/src/HttpReply.cc squid-3.0.STABLE5/src/HttpReply.cc
--- squid-3.0.STABLE4/src/HttpReply.cc	2008-04-01 23:54:36.000000000 +1200
+++ squid-3.0.STABLE5/src/HttpReply.cc	2008-04-29 15:43:30.000000000 +1200
@@ -496,3 +496,17 @@
 
     return expectBody;
 }
+
+HttpReply *
+HttpReply::clone() const
+{
+    HttpReply *rep = new HttpReply();
+    rep->header.append(&header);
+    rep->hdrCacheInit();
+    rep->hdr_sz = hdr_sz;
+    rep->http_ver = http_ver;
+    rep->pstate = pstate;
+    rep->protocol = protocol;
+    rep->sline = sline;
+    return rep;
+}
diff -u -N -r squid-3.0.STABLE4/src/HttpReply.h squid-3.0.STABLE5/src/HttpReply.h
--- squid-3.0.STABLE4/src/HttpReply.h	2008-04-01 23:54:36.000000000 +1200
+++ squid-3.0.STABLE5/src/HttpReply.h	2008-04-29 15:43:30.000000000 +1200
@@ -122,6 +122,11 @@
 
     void packHeadersInto(Packer * p) const;
 
+    /// Clone this reply.
+    /// Could be done as a copy-contructor but we do not want to
+    /// accidently copy a HttpReply..
+    HttpReply *clone() const;
+
 private:
     /* initialize */
     void init();
diff -u -N -r squid-3.0.STABLE4/src/ICAP/ICAPConfig.cc squid-3.0.STABLE5/src/ICAP/ICAPConfig.cc
--- squid-3.0.STABLE4/src/ICAP/ICAPConfig.cc	2008-04-01 23:54:36.000000000 +1200
+++ squid-3.0.STABLE5/src/ICAP/ICAPConfig.cc	2008-04-29 15:43:30.000000000 +1200
@@ -186,6 +186,9 @@
 
         // XXX we don't have access to conn->rfc931 here.
         acl_checklist = aclChecklistCreate(theClass->accessList, req, dash_str);
+        if (rep)
+            acl_checklist->reply = HTTPMSGLOCK(rep); // ACLChecklist unlocks
+
 
         acl_checklist->nonBlockingCheck(ICAPAccessCheckCallbackWrapper, this);
 
diff -u -N -r squid-3.0.STABLE4/src/MemBuf.h squid-3.0.STABLE5/src/MemBuf.h
--- squid-3.0.STABLE4/src/MemBuf.h	2008-04-01 23:54:37.000000000 +1200
+++ squid-3.0.STABLE5/src/MemBuf.h	2008-04-29 15:43:30.000000000 +1200
@@ -1,7 +1,7 @@
 
 
 /*
- * $Id: MemBuf.h,v 1.8 2006/08/21 00:50:41 robertc Exp $
+ * $Id: MemBuf.h,v 1.9 2007/12/21 23:48:04 hno Exp $
  *
  *
  * SQUID Web Proxy Cache          http://www.squid-cache.org/
@@ -60,6 +60,7 @@
 
     // these space-related methods assume no growth and allow 0-termination
     char *space() { return buf + size; } // space to add data
+    char *space(mb_size_t required) { if (size + required > capacity) grow(size + required); return buf + size; } // space to add data
 
     mb_size_t spaceSize() const;
     bool hasSpace() const { return size+1 < capacity; }
diff -u -N -r squid-3.0.STABLE4/src/Parsing.cc squid-3.0.STABLE5/src/Parsing.cc
--- squid-3.0.STABLE4/src/Parsing.cc	2008-04-01 23:54:37.000000000 +1200
+++ squid-3.0.STABLE5/src/Parsing.cc	2008-04-29 15:43:30.000000000 +1200
@@ -89,7 +89,8 @@
     if (token == NULL)
         self_destruct();
 
-    if (sscanf(token, "%d", &i) != 1)
+    // %i honors 0 and 0x prefixes, which are important for things like umask
+    if (sscanf(token, "%i", &i) != 1)
         self_destruct();
 
     return i;
diff -u -N -r squid-3.0.STABLE4/src/WinSvc.cc squid-3.0.STABLE5/src/WinSvc.cc
--- squid-3.0.STABLE4/src/WinSvc.cc	2008-04-01 23:54:37.000000000 +1200
+++ squid-3.0.STABLE5/src/WinSvc.cc	2008-04-29 15:43:31.000000000 +1200
@@ -344,7 +344,7 @@
 	    if (osvi.wProductType == VER_NT_WORKSTATION)
 		WIN32_OS_string = xstrdup("Windows Vista");
 	    else
-		WIN32_OS_string = xstrdup("Windows Server \"Longhorn\"");
+		WIN32_OS_string = xstrdup("Windows Server 2008");
 	    return _WIN_OS_WINLON;
 	}
 	break;
diff -u -N -r squid-3.0.STABLE4/test-suite/test_tools.cc squid-3.0.STABLE5/test-suite/test_tools.cc
--- squid-3.0.STABLE4/test-suite/test_tools.cc	2008-04-01 23:54:39.000000000 +1200
+++ squid-3.0.STABLE5/test-suite/test_tools.cc	2008-04-29 15:43:33.000000000 +1200
@@ -1,6 +1,6 @@
 
 /*
- * $Id: test_tools.cc,v 1.9 2006/09/03 21:05:22 hno Exp $
+ * $Id: test_tools.cc,v 1.10 2008/02/26 18:44:16 rousskov Exp $
  *
  * AUTHOR: Robert Collins
  *
@@ -161,18 +161,48 @@
     fatal(message);
 }
 
+int Debug::TheDepth = 0;
+
 std::ostream &
 Debug::getDebugOut() {
-    assert (CurrentDebug == NULL);
-    CurrentDebug = new std::ostringstream();
+    assert(TheDepth >= 0);
+    ++TheDepth;
+    if (TheDepth > 1) {
+        assert(CurrentDebug);
+        *CurrentDebug << std::endl << "reentrant debuging " << TheDepth << "-{";
+    } else {
+        assert(!CurrentDebug);
+        CurrentDebug = new std::ostringstream();
+        // set default formatting flags
+        CurrentDebug->setf(std::ios::fixed);
+        CurrentDebug->precision(2);
+    }
     return *CurrentDebug;
 }
 
 void
 Debug::finishDebug() {
-    _db_print("%s\n", CurrentDebug->str().c_str());
-    delete CurrentDebug;
-    CurrentDebug = NULL;
+    assert(TheDepth >= 0);
+    assert(CurrentDebug);
+    if (TheDepth > 1) {
+        *CurrentDebug << "}-" << TheDepth << std::endl;
+    } else {
+        assert(TheDepth == 1);
+        _db_print("%s\n", CurrentDebug->str().c_str());
+        delete CurrentDebug;
+        CurrentDebug = NULL;
+    }
+    --TheDepth;
+}
+
+void
+Debug::xassert(const char *msg, const char *file, int line) {
+	
+    if (CurrentDebug) {
+        *CurrentDebug << "assertion failed: " << file << ":" << line <<
+            ": \"" << msg << "\"";
+    }
+    abort();
 }
 
 std::ostringstream *Debug::CurrentDebug (NULL);
