diff -u -r -N squid-3.0.STABLE7/ChangeLog squid-3.0.STABLE8/ChangeLog
--- squid-3.0.STABLE7/ChangeLog	2008-06-22 15:35:44.000000000 +1200
+++ squid-3.0.STABLE8/ChangeLog	2008-07-18 22:02:45.000000000 +1200
@@ -1,3 +1,22 @@
+Changes to squid-3.0.STABLE8 (18 Jul 2008):
+
+	- Port from 2.6: Support for cachemgr sub-actions
+	- Port from 2.6: userhash peer selection method
+	- Port from 2.6: sourcehash peer selection method
+	- Bug 2376: round-robin balancing fixes
+	- Bug 2388: acl documentation cleanup
+	- Bug 2365: cachemgr.cgi HTML output encoding
+	- Bug 2301: Regression: Log format size options
+	- Bug 2396: Correct the opening of PF device file.
+	- Bug 2400: ICAP accept mechanism
+	- Bug 2411: Regression: fakeauth_auth crashes
+	- Many fixes to the Windows support (not complete yet).
+	- Boost error pages HTML standards.
+	- Fixes several issues on 64-bit systems
+	- Fixes several issues on older or stricter compilers
+	- Linux-2.6.24/2.6.25 netfilter_ipv4.h __u32 workaround
+	- Update Release Notes: 'all' ACL is built-in since 3.0.STABLE1
+
 Changes to squid-3.0.STABLE7 (22 Jun 2008):
 
 	- Fix several ASN issues
diff -u -r -N squid-3.0.STABLE7/configure squid-3.0.STABLE8/configure
--- squid-3.0.STABLE7/configure	2008-06-22 15:35:54.000000000 +1200
+++ squid-3.0.STABLE8/configure	2008-07-18 22:02:55.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.STABLE7.
+# Generated by GNU Autoconf 2.61 for Squid Web Proxy 3.0.STABLE8.
 #
 # 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.STABLE7'
-PACKAGE_STRING='Squid Web Proxy 3.0.STABLE7'
+PACKAGE_VERSION='3.0.STABLE8'
+PACKAGE_STRING='Squid Web Proxy 3.0.STABLE8'
 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.STABLE7 to adapt to many kinds of systems.
+\`configure' configures Squid Web Proxy 3.0.STABLE8 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.STABLE7:";;
+     short | recursive ) echo "Configuration of Squid Web Proxy 3.0.STABLE8:";;
    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.STABLE7
+Squid Web Proxy configure 3.0.STABLE8
 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.STABLE7, which was
+It was created by Squid Web Proxy $as_me 3.0.STABLE8, 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.STABLE7'
+ VERSION='3.0.STABLE8'
 
 
 cat >>confdefs.h <<_ACEOF
@@ -22134,11 +22134,17 @@
 	if test -z "$buildmodel"; then
 		echo "WARNING: No suitable build environment found for large files. Trying to use _FILE_OFFSET_BITS=64"
 		sleep 1
+	fi
+fi
+case "$buildmodel" in
+default|"")
+	if test "$needlargefiles"; then
+		echo "Enabling -D_FILE_OFFSET_BITS=64"
 		CFLAGS="-D_FILE_OFFSET_BITS=64 $CFLAGS"
 		CXXFLAGS="-D_FILE_OFFSET_BITS=64 $CXXFLAGS"
 	fi
-fi
-if test -n "$buildmodel" && test "$buildmodel" != "default"; then
+	;;
+*)
 	echo "Using $buildmodel build environment"
 	if test "`getconf _$buildmodel 2>/dev/null || true`" = 1 || test "`getconf $buildmodel 2>/dev/null || true`" ; then
 	    : # All fine
@@ -22156,6 +22162,9 @@
 		    echo "Removing -Xa for gcc on $host"
 		    CFLAGS="`echo $CFLAGS | sed -e 's/-Xa//'`"
 		    CXXFLAGS="`echo $CXXFLAGS | sed -e 's/-Xa//'`"
+		    echo "Replacing -xarch=generic64 with -m64 for gcc on $host"
+		    CFLAGS="`echo $CFLAGS | sed -e 's/-xarch=generic64/-m64/'`"
+		    LDFLAGS="`echo $LDFLAGS | sed -e 's/-xarch=generic64//'`"
 		fi
 		echo "Removing -Usun on $host"
 		CFLAGS="`echo $CFLAGS | sed -e 's/-Usun//'`"
@@ -22174,7 +22183,8 @@
 	    *)
 	        ;;
 	esac
-fi
+	;;
+esac
 
 # Check whether --enable-linux-tproxy was given.
 if test "${enable_linux_tproxy+set}" = set; then
@@ -41527,6 +41537,299 @@
     done
     { echo "$as_me:$LINENO: result: $have_winsock" >&5
 echo "${ECHO_T}$have_winsock" >&6; }
+    if test $have_winsock = winsock2; then
+
+for ac_header in winsock2.h
+do
+as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh`
+if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then
+  { echo "$as_me:$LINENO: checking for $ac_header" >&5
+echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6; }
+if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+fi
+ac_res=`eval echo '${'$as_ac_Header'}'`
+	       { echo "$as_me:$LINENO: result: $ac_res" >&5
+echo "${ECHO_T}$ac_res" >&6; }
+else
+  # Is the header compilable?
+{ echo "$as_me:$LINENO: checking $ac_header usability" >&5
+echo $ECHO_N "checking $ac_header usability... $ECHO_C" >&6; }
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+$ac_includes_default
+#include <$ac_header>
+_ACEOF
+rm -f conftest.$ac_objext
+if { (ac_try="$ac_compile"
+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_compile") 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } && {
+	 test -z "$ac_c_werror_flag" ||
+	 test ! -s conftest.err
+       } && test -s conftest.$ac_objext; then
+  ac_header_compiler=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+	ac_header_compiler=no
+fi
+
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+{ echo "$as_me:$LINENO: result: $ac_header_compiler" >&5
+echo "${ECHO_T}$ac_header_compiler" >&6; }
+
+# Is the header present?
+{ echo "$as_me:$LINENO: checking $ac_header presence" >&5
+echo $ECHO_N "checking $ac_header presence... $ECHO_C" >&6; }
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <$ac_header>
+_ACEOF
+if { (ac_try="$ac_cpp conftest.$ac_ext"
+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_cpp conftest.$ac_ext") 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } >/dev/null && {
+	 test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" ||
+	 test ! -s conftest.err
+       }; then
+  ac_header_preproc=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+  ac_header_preproc=no
+fi
+
+rm -f conftest.err conftest.$ac_ext
+{ echo "$as_me:$LINENO: result: $ac_header_preproc" >&5
+echo "${ECHO_T}$ac_header_preproc" >&6; }
+
+# So?  What about this header?
+case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in
+  yes:no: )
+    { echo "$as_me:$LINENO: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&5
+echo "$as_me: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&2;}
+    { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the compiler's result" >&5
+echo "$as_me: WARNING: $ac_header: proceeding with the compiler's result" >&2;}
+    ac_header_preproc=yes
+    ;;
+  no:yes:* )
+    { echo "$as_me:$LINENO: WARNING: $ac_header: present but cannot be compiled" >&5
+echo "$as_me: WARNING: $ac_header: present but cannot be compiled" >&2;}
+    { echo "$as_me:$LINENO: WARNING: $ac_header:     check for missing prerequisite headers?" >&5
+echo "$as_me: WARNING: $ac_header:     check for missing prerequisite headers?" >&2;}
+    { echo "$as_me:$LINENO: WARNING: $ac_header: see the Autoconf documentation" >&5
+echo "$as_me: WARNING: $ac_header: see the Autoconf documentation" >&2;}
+    { echo "$as_me:$LINENO: WARNING: $ac_header:     section \"Present But Cannot Be Compiled\"" >&5
+echo "$as_me: WARNING: $ac_header:     section \"Present But Cannot Be Compiled\"" >&2;}
+    { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5
+echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;}
+    { echo "$as_me:$LINENO: WARNING: $ac_header: in the future, the compiler will take precedence" >&5
+echo "$as_me: WARNING: $ac_header: in the future, the compiler will take precedence" >&2;}
+    ( cat <<\_ASBOX
+## ----------------------------------------------- ##
+## Report this to http://www.squid-cache.org/bugs/ ##
+## ----------------------------------------------- ##
+_ASBOX
+     ) | sed "s/^/$as_me: WARNING:     /" >&2
+    ;;
+esac
+{ echo "$as_me:$LINENO: checking for $ac_header" >&5
+echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6; }
+if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  eval "$as_ac_Header=\$ac_header_preproc"
+fi
+ac_res=`eval echo '${'$as_ac_Header'}'`
+	       { echo "$as_me:$LINENO: result: $ac_res" >&5
+echo "${ECHO_T}$ac_res" >&6; }
+
+fi
+if test `eval echo '${'$as_ac_Header'}'` = yes; then
+  cat >>confdefs.h <<_ACEOF
+#define `echo "HAVE_$ac_header" | $as_tr_cpp` 1
+_ACEOF
+
+fi
+
+done
+
+    else
+
+for ac_header in winsock.h
+do
+as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh`
+if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then
+  { echo "$as_me:$LINENO: checking for $ac_header" >&5
+echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6; }
+if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+fi
+ac_res=`eval echo '${'$as_ac_Header'}'`
+	       { echo "$as_me:$LINENO: result: $ac_res" >&5
+echo "${ECHO_T}$ac_res" >&6; }
+else
+  # Is the header compilable?
+{ echo "$as_me:$LINENO: checking $ac_header usability" >&5
+echo $ECHO_N "checking $ac_header usability... $ECHO_C" >&6; }
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+$ac_includes_default
+#include <$ac_header>
+_ACEOF
+rm -f conftest.$ac_objext
+if { (ac_try="$ac_compile"
+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_compile") 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } && {
+	 test -z "$ac_c_werror_flag" ||
+	 test ! -s conftest.err
+       } && test -s conftest.$ac_objext; then
+  ac_header_compiler=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+	ac_header_compiler=no
+fi
+
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+{ echo "$as_me:$LINENO: result: $ac_header_compiler" >&5
+echo "${ECHO_T}$ac_header_compiler" >&6; }
+
+# Is the header present?
+{ echo "$as_me:$LINENO: checking $ac_header presence" >&5
+echo $ECHO_N "checking $ac_header presence... $ECHO_C" >&6; }
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <$ac_header>
+_ACEOF
+if { (ac_try="$ac_cpp conftest.$ac_ext"
+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_cpp conftest.$ac_ext") 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } >/dev/null && {
+	 test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" ||
+	 test ! -s conftest.err
+       }; then
+  ac_header_preproc=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+  ac_header_preproc=no
+fi
+
+rm -f conftest.err conftest.$ac_ext
+{ echo "$as_me:$LINENO: result: $ac_header_preproc" >&5
+echo "${ECHO_T}$ac_header_preproc" >&6; }
+
+# So?  What about this header?
+case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in
+  yes:no: )
+    { echo "$as_me:$LINENO: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&5
+echo "$as_me: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&2;}
+    { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the compiler's result" >&5
+echo "$as_me: WARNING: $ac_header: proceeding with the compiler's result" >&2;}
+    ac_header_preproc=yes
+    ;;
+  no:yes:* )
+    { echo "$as_me:$LINENO: WARNING: $ac_header: present but cannot be compiled" >&5
+echo "$as_me: WARNING: $ac_header: present but cannot be compiled" >&2;}
+    { echo "$as_me:$LINENO: WARNING: $ac_header:     check for missing prerequisite headers?" >&5
+echo "$as_me: WARNING: $ac_header:     check for missing prerequisite headers?" >&2;}
+    { echo "$as_me:$LINENO: WARNING: $ac_header: see the Autoconf documentation" >&5
+echo "$as_me: WARNING: $ac_header: see the Autoconf documentation" >&2;}
+    { echo "$as_me:$LINENO: WARNING: $ac_header:     section \"Present But Cannot Be Compiled\"" >&5
+echo "$as_me: WARNING: $ac_header:     section \"Present But Cannot Be Compiled\"" >&2;}
+    { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5
+echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;}
+    { echo "$as_me:$LINENO: WARNING: $ac_header: in the future, the compiler will take precedence" >&5
+echo "$as_me: WARNING: $ac_header: in the future, the compiler will take precedence" >&2;}
+    ( cat <<\_ASBOX
+## ----------------------------------------------- ##
+## Report this to http://www.squid-cache.org/bugs/ ##
+## ----------------------------------------------- ##
+_ASBOX
+     ) | sed "s/^/$as_me: WARNING:     /" >&2
+    ;;
+esac
+{ echo "$as_me:$LINENO: checking for $ac_header" >&5
+echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6; }
+if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  eval "$as_ac_Header=\$ac_header_preproc"
+fi
+ac_res=`eval echo '${'$as_ac_Header'}'`
+	       { echo "$as_me:$LINENO: result: $ac_res" >&5
+echo "${ECHO_T}$ac_res" >&6; }
+
+fi
+if test `eval echo '${'$as_ac_Header'}'` = yes; then
+  cat >>confdefs.h <<_ACEOF
+#define `echo "HAVE_$ac_header" | $as_tr_cpp` 1
+_ACEOF
+
+fi
+
+done
+
+    fi
     ;;
 esac
 
@@ -44398,6 +44701,12 @@
 #if HAVE_SYS_TYPES_H
 #include <sys/types.h>
 #endif
+#if HAVE_WINSOCK_H
+#include <winsock.h>
+#endif
+#if HAVE_WINSOCK2_H
+#include <winsock2.h>
+#endif
 main() {
 	FILE *fp = fopen("conftestval", "w");
 	fprintf (fp, "%d\n", FD_SETSIZE);
@@ -44609,14 +44918,31 @@
 #include <stdlib.h>
 #include <stdio.h>
 #include <sys/types.h>
+#if HAVE_SYS_SOCKET_H
 #include <sys/socket.h>
+#endif
+#if HAVE_NETINET_IN_H
 #include <netinet/in.h>
+#endif
+#if HAVE_WINSOCK_H
+#include <winsock.h>
+#endif
+#if HAVE_WINSOCK2_H
+#include <winsock2.h>
+#endif
 main ()
 {
 	FILE *fp;
         int fd,val=0,len=sizeof(int);
+#if (defined(WIN32) || defined(__WIN32__) || defined(__WIN32)) && !(defined(__CYGWIN32__) || defined(__CYGWIN__))
+	WSADATA wsaData;
+	WSAStartup(2, &wsaData);
+#endif
 	if ((fd = socket(AF_INET, SOCK_DGRAM, 0)) < 0) exit(1);
         if (getsockopt(fd, SOL_SOCKET, SO_SNDBUF, &val, &len) < 0) exit(1);
+#if (defined(WIN32) || defined(__WIN32__) || defined(__WIN32)) && !(defined(__CYGWIN32__) || defined(__CYGWIN__))
+	WSACleanup();
+#endif
 	if (val<=0) exit(1);
         fp = fopen("conftestval", "w");
         fprintf (fp, "%d\n", val);
@@ -44680,14 +45006,31 @@
 #include <stdlib.h>
 #include <stdio.h>
 #include <sys/types.h>
+#if HAVE_SYS_SOCKET_H
 #include <sys/socket.h>
+#endif
+#if HAVE_NETINET_IN_H
 #include <netinet/in.h>
+#endif
+#if HAVE_WINSOCK_H
+#include <winsock.h>
+#endif
+#if HAVE_WINSOCK2_H
+#include <winsock2.h>
+#endif
 main ()
 {
 	FILE *fp;
         int fd,val=0,len=sizeof(int);
+#if (defined(WIN32) || defined(__WIN32__) || defined(__WIN32)) && !(defined(__CYGWIN32__) || defined(__CYGWIN__))
+	WSADATA wsaData;
+	WSAStartup(2, &wsaData);
+#endif
 	if ((fd = socket(AF_INET, SOCK_DGRAM, 0)) < 0) exit(1);
         if (getsockopt(fd, SOL_SOCKET, SO_RCVBUF, &val, &len) < 0) exit(1);
+#if (defined(WIN32) || defined(__WIN32__) || defined(__WIN32)) && !(defined(__CYGWIN32__) || defined(__CYGWIN__))
+	WSACleanup();
+#endif
 	if (val <= 0) exit(1);
 	fp = fopen("conftestval", "w");
 	fprintf (fp, "%d\n", val);
@@ -44751,14 +45094,31 @@
 #include <stdlib.h>
 #include <stdio.h>
 #include <sys/types.h>
+#if HAVE_SYS_SOCKET_H
 #include <sys/socket.h>
+#endif
+#if HAVE_NETINET_IN_H
 #include <netinet/in.h>
+#endif
+#if HAVE_WINSOCK_H
+#include <winsock.h>
+#endif
+#if HAVE_WINSOCK2_H
+#include <winsock2.h>
+#endif
 main ()
 {
 	FILE *fp;
         int fd,val=0,len=sizeof(int);
+#if (defined(WIN32) || defined(__WIN32__) || defined(__WIN32)) && !(defined(__CYGWIN32__) || defined(__CYGWIN__))
+	WSADATA wsaData;
+	WSAStartup(2, &wsaData);
+#endif
 	if ((fd = socket(AF_INET, SOCK_STREAM, 0)) < 0) exit(1);
         if (getsockopt(fd, SOL_SOCKET, SO_SNDBUF, &val, &len) < 0) exit(1);
+#if (defined(WIN32) || defined(__WIN32__) || defined(__WIN32)) && !(defined(__CYGWIN32__) || defined(__CYGWIN__))
+	WSACleanup();
+#endif
 	if (val <= 0) exit(1);
 	fp = fopen("conftestval", "w");
 	fprintf (fp, "%d\n", val);
@@ -44826,14 +45186,31 @@
 #include <stdlib.h>
 #include <stdio.h>
 #include <sys/types.h>
+#if HAVE_SYS_SOCKET_H
 #include <sys/socket.h>
+#endif
+#if HAVE_NETINET_IN_H
 #include <netinet/in.h>
+#endif
+#if HAVE_WINSOCK_H
+#include <winsock.h>
+#endif
+#if HAVE_WINSOCK2_H
+#include <winsock2.h>
+#endif
 main ()
 {
 	FILE *fp;
         int fd,val=0,len=sizeof(int);
+#if (defined(WIN32) || defined(__WIN32__) || defined(__WIN32)) && !(defined(__CYGWIN32__) || defined(__CYGWIN__))
+	WSADATA wsaData;
+	WSAStartup(2, &wsaData);
+#endif
 	if ((fd = socket(AF_INET, SOCK_STREAM, 0)) < 0) exit(1);
         if (getsockopt(fd, SOL_SOCKET, SO_RCVBUF, &val, &len) < 0) exit(1);
+#if (defined(WIN32) || defined(__WIN32__) || defined(__WIN32)) && !(defined(__CYGWIN32__) || defined(__CYGWIN__))
+	WSACleanup();
+#endif
 	if (val <= 0) exit(1);
 	fp = fopen("conftestval", "w");
 	fprintf (fp, "%d\n", val);
@@ -46041,7 +46418,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.STABLE7, which was
+This file was extended by Squid Web Proxy $as_me 3.0.STABLE8, which was
 generated by GNU Autoconf 2.61.  Invocation command line was
 
   CONFIG_FILES    = $CONFIG_FILES
@@ -46094,7 +46471,7 @@
 _ACEOF
 cat >>$CONFIG_STATUS <<_ACEOF
 ac_cs_version="\\
-Squid Web Proxy config.status 3.0.STABLE7
+Squid Web Proxy config.status 3.0.STABLE8
 configured by $0, generated by GNU Autoconf 2.61,
   with options \\"`echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`\\"
 
diff -u -r -N squid-3.0.STABLE7/configure.in squid-3.0.STABLE8/configure.in
--- squid-3.0.STABLE7/configure.in	2008-06-22 15:35:54.000000000 +1200
+++ squid-3.0.STABLE8/configure.in	2008-07-18 22:02:55.000000000 +1200
@@ -5,7 +5,7 @@
 dnl
 dnl
 dnl
-AC_INIT(Squid Web Proxy, 3.0.STABLE7, http://www.squid-cache.org/bugs/, squid)
+AC_INIT(Squid Web Proxy, 3.0.STABLE8, http://www.squid-cache.org/bugs/, squid)
 AC_PREREQ(2.52)
 AM_CONFIG_HEADER(include/autoconf.h)
 AC_CONFIG_AUX_DIR(cfgaux)
@@ -1182,11 +1182,17 @@
 	if test -z "$buildmodel"; then
 		echo "WARNING: No suitable build environment found for large files. Trying to use _FILE_OFFSET_BITS=64"
 		sleep 1
+	fi
+fi
+case "$buildmodel" in
+default|"")
+	if test "$needlargefiles"; then
+		echo "Enabling -D_FILE_OFFSET_BITS=64"
 		CFLAGS="-D_FILE_OFFSET_BITS=64 $CFLAGS"
 		CXXFLAGS="-D_FILE_OFFSET_BITS=64 $CXXFLAGS"
 	fi
-fi
-if test -n "$buildmodel" && test "$buildmodel" != "default"; then
+	;;
+*)
 	echo "Using $buildmodel build environment"
 	if test "`getconf _$buildmodel 2>/dev/null || true`" = 1 || test "`getconf $buildmodel 2>/dev/null || true`" ; then
 	    : # All fine
@@ -1200,14 +1206,19 @@
 	LDFLAGS="`getconf ${buildmodel}_LDFLAGS` $LDFLAGS"
 	case "$host" in
 dnl
-dnl On Solaris getconf returns for CFLAGS -Xa and -Usun options, but:
-dnl   -Xa is supported only by Sun cc, so we need to remove it when using gcc
-dnl   The 'sun' define is needed by ipfilter includes, so we must remove -Usun
+dnl On Solaris getconf returns for CFLAGS -xarch=generic64, -Xa and -Usun options, and
+dnl for LDFLAGS -xarch=generic64, but:
+dnl   "-Xa" is supported only by Sun cc, so we need to remove it when using gcc
+dnl   For gcc "-xarch=generic64" must be replaced with "-m64"
+dnl   The 'sun' define is needed by ipfilter includes, so we must remove "-Usun"
 	    *-solaris*)
     		if test "$GCC" = "yes"; then
 		    echo "Removing -Xa for gcc on $host"
 		    CFLAGS="`echo $CFLAGS | sed -e 's/-Xa//'`"
 		    CXXFLAGS="`echo $CXXFLAGS | sed -e 's/-Xa//'`"
+		    echo "Replacing -xarch=generic64 with -m64 for gcc on $host"
+		    CFLAGS="`echo $CFLAGS | sed -e 's/-xarch=generic64/-m64/'`"
+		    LDFLAGS="`echo $LDFLAGS | sed -e 's/-xarch=generic64//'`"
 		fi
 		echo "Removing -Usun on $host"
 		CFLAGS="`echo $CFLAGS | sed -e 's/-Usun//'`"
@@ -1233,7 +1244,8 @@
 	    *)
 	        ;;
 	esac
-fi
+	;;
+esac
 
 dnl Enable Linux transparent proxy support
 AC_ARG_ENABLE(linux-tproxy,
@@ -2195,6 +2207,7 @@
 dnl Check for needed libraries
 AC_CHECK_LIB(nsl, main)
 AC_CHECK_LIB(socket, main)
+dnl Check for Winsock only on MinGW, on Cygwin we must use emulated BSD socket API
 case "$host_os" in
   mingw|mingw32)
     AC_MSG_CHECKING(for winsock)
@@ -2225,6 +2238,11 @@
 	LIBS="$save_LIBS"
     done
     AC_MSG_RESULT($have_winsock)
+    if test $have_winsock = winsock2; then
+       AC_CHECK_HEADERS(winsock2.h)
+    else
+       AC_CHECK_HEADERS(winsock.h)
+    fi
     ;;
 esac
 
@@ -2923,6 +2941,12 @@
 #if HAVE_SYS_TYPES_H
 #include <sys/types.h>
 #endif
+#if HAVE_WINSOCK_H
+#include <winsock.h>
+#endif
+#if HAVE_WINSOCK2_H
+#include <winsock2.h>
+#endif
 main() {
 	FILE *fp = fopen("conftestval", "w");
 	fprintf (fp, "%d\n", FD_SETSIZE);
@@ -3045,14 +3069,31 @@
 #include <stdlib.h>
 #include <stdio.h>
 #include <sys/types.h>
+#if HAVE_SYS_SOCKET_H
 #include <sys/socket.h>
+#endif
+#if HAVE_NETINET_IN_H
 #include <netinet/in.h>
+#endif
+#if HAVE_WINSOCK_H
+#include <winsock.h>
+#endif
+#if HAVE_WINSOCK2_H
+#include <winsock2.h>
+#endif
 main ()
 {
 	FILE *fp;
         int fd,val=0,len=sizeof(int);
+#if (defined(WIN32) || defined(__WIN32__) || defined(__WIN32)) && !(defined(__CYGWIN32__) || defined(__CYGWIN__))
+	WSADATA wsaData;
+	WSAStartup(2, &wsaData);
+#endif
 	if ((fd = socket(AF_INET, SOCK_DGRAM, 0)) < 0) exit(1);
         if (getsockopt(fd, SOL_SOCKET, SO_SNDBUF, &val, &len) < 0) exit(1);
+#if (defined(WIN32) || defined(__WIN32__) || defined(__WIN32)) && !(defined(__CYGWIN32__) || defined(__CYGWIN__))
+	WSACleanup();
+#endif
 	if (val<=0) exit(1);
         fp = fopen("conftestval", "w");
         fprintf (fp, "%d\n", val);
@@ -3071,14 +3112,31 @@
 #include <stdlib.h>
 #include <stdio.h>
 #include <sys/types.h>
+#if HAVE_SYS_SOCKET_H
 #include <sys/socket.h>
+#endif
+#if HAVE_NETINET_IN_H
 #include <netinet/in.h>
+#endif
+#if HAVE_WINSOCK_H
+#include <winsock.h>
+#endif
+#if HAVE_WINSOCK2_H
+#include <winsock2.h>
+#endif
 main ()
 {
 	FILE *fp;
         int fd,val=0,len=sizeof(int);
+#if (defined(WIN32) || defined(__WIN32__) || defined(__WIN32)) && !(defined(__CYGWIN32__) || defined(__CYGWIN__))
+	WSADATA wsaData;
+	WSAStartup(2, &wsaData);
+#endif
 	if ((fd = socket(AF_INET, SOCK_DGRAM, 0)) < 0) exit(1);
         if (getsockopt(fd, SOL_SOCKET, SO_RCVBUF, &val, &len) < 0) exit(1);
+#if (defined(WIN32) || defined(__WIN32__) || defined(__WIN32)) && !(defined(__CYGWIN32__) || defined(__CYGWIN__))
+	WSACleanup();
+#endif
 	if (val <= 0) exit(1);
 	fp = fopen("conftestval", "w"); 
 	fprintf (fp, "%d\n", val);
@@ -3097,14 +3155,31 @@
 #include <stdlib.h>
 #include <stdio.h>
 #include <sys/types.h>
+#if HAVE_SYS_SOCKET_H
 #include <sys/socket.h>
+#endif
+#if HAVE_NETINET_IN_H
 #include <netinet/in.h>
+#endif
+#if HAVE_WINSOCK_H
+#include <winsock.h>
+#endif
+#if HAVE_WINSOCK2_H
+#include <winsock2.h>
+#endif
 main ()
 {
 	FILE *fp;
         int fd,val=0,len=sizeof(int);
+#if (defined(WIN32) || defined(__WIN32__) || defined(__WIN32)) && !(defined(__CYGWIN32__) || defined(__CYGWIN__))
+	WSADATA wsaData;
+	WSAStartup(2, &wsaData);
+#endif
 	if ((fd = socket(AF_INET, SOCK_STREAM, 0)) < 0) exit(1);
         if (getsockopt(fd, SOL_SOCKET, SO_SNDBUF, &val, &len) < 0) exit(1);
+#if (defined(WIN32) || defined(__WIN32__) || defined(__WIN32)) && !(defined(__CYGWIN32__) || defined(__CYGWIN__))
+	WSACleanup();
+#endif
 	if (val <= 0) exit(1);
 	fp = fopen("conftestval", "w"); 
 	fprintf (fp, "%d\n", val);
@@ -3127,14 +3202,31 @@
 #include <stdlib.h>
 #include <stdio.h>
 #include <sys/types.h>
+#if HAVE_SYS_SOCKET_H
 #include <sys/socket.h>
+#endif
+#if HAVE_NETINET_IN_H
 #include <netinet/in.h>
+#endif
+#if HAVE_WINSOCK_H
+#include <winsock.h>
+#endif
+#if HAVE_WINSOCK2_H
+#include <winsock2.h>
+#endif
 main ()
 {
 	FILE *fp;
         int fd,val=0,len=sizeof(int);
+#if (defined(WIN32) || defined(__WIN32__) || defined(__WIN32)) && !(defined(__CYGWIN32__) || defined(__CYGWIN__))
+	WSADATA wsaData;
+	WSAStartup(2, &wsaData);
+#endif
 	if ((fd = socket(AF_INET, SOCK_STREAM, 0)) < 0) exit(1);
         if (getsockopt(fd, SOL_SOCKET, SO_RCVBUF, &val, &len) < 0) exit(1);
+#if (defined(WIN32) || defined(__WIN32__) || defined(__WIN32)) && !(defined(__CYGWIN32__) || defined(__CYGWIN__))
+	WSACleanup();
+#endif
 	if (val <= 0) exit(1);
 	fp = fopen("conftestval", "w"); 
 	fprintf (fp, "%d\n", val);
diff -u -r -N squid-3.0.STABLE7/CREDITS squid-3.0.STABLE8/CREDITS
--- squid-3.0.STABLE7/CREDITS	2008-06-22 15:35:44.000000000 +1200
+++ squid-3.0.STABLE8/CREDITS	2008-07-18 22:02:45.000000000 +1200
@@ -318,6 +318,41 @@
 
 ==============================================================================
 
+lib/getopt.c:
+
+/*
+ * Copyright (c) 1987, 1993, 1994
+ *	The Regents of the University of California.  All rights reserved.
+ *
+ * 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. 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.
+ */
+
+static char sccsid[] = "@(#)getopt.c	8.3 (Berkeley) 4/27/95";
+
+==============================================================================
+
 src/external_acl.c
 
 Copyright (C) 2002 MARA Systems AB, Sweden <info@marasystems.com>
diff -u -r -N squid-3.0.STABLE7/helpers/basic_auth/MSNT/confload.c squid-3.0.STABLE8/helpers/basic_auth/MSNT/confload.c
--- squid-3.0.STABLE7/helpers/basic_auth/MSNT/confload.c	2008-06-22 15:35:48.000000000 +1200
+++ squid-3.0.STABLE8/helpers/basic_auth/MSNT/confload.c	2008-07-18 22:02:50.000000000 +1200
@@ -10,6 +10,9 @@
  * authenticating function.
  */
 
+/* Squid provides a number of portability overrides */
+#include "config.h"
+
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
diff -u -r -N squid-3.0.STABLE7/helpers/basic_auth/squid_radius_auth/squid_rad_auth.c squid-3.0.STABLE8/helpers/basic_auth/squid_radius_auth/squid_rad_auth.c
--- squid-3.0.STABLE7/helpers/basic_auth/squid_radius_auth/squid_rad_auth.c	2008-06-22 15:35:49.000000000 +1200
+++ squid-3.0.STABLE8/helpers/basic_auth/squid_radius_auth/squid_rad_auth.c	2008-07-18 22:02:50.000000000 +1200
@@ -65,6 +65,9 @@
 #if HAVE_FCNTL_H
 #include	<fcntl.h>
 #endif
+#ifdef _SQUID_WIN32_
+#include <io.h>
+#endif
 
 #if HAVE_CTYPE_H
 #include	<ctype.h>
@@ -90,6 +93,12 @@
 #if HAVE_STRING_H
 #include	<string.h>
 #endif
+#if HAVE_GETOPT_H
+#include <getopt.h>
+#endif
+#if HAVE_ERRNO_H
+#include <errno.h>
+#endif
 
 #include	"md5.h"
 #include	"radius.h"
@@ -120,6 +129,15 @@
 char *progname = "squid_rad_auth";
 int debug_flag = 0;
 
+#ifdef _SQUID_MSWIN_
+void
+Win32SockCleanup(void)
+{
+    WSACleanup();
+    return;
+}
+#endif /* ifdef _SQUID_MSWIN_ */
+
 /*
  *    Diff two timeval, b - a
  */
@@ -174,12 +192,10 @@
 	    totallen, length);
 	return -1;
     }
-
     if (auth->id != request_id) {
 	/* Duplicate response of an earlier query, ignore */
 	return -1;
     }
-
     /* Verify the reply digest */
     memcpy(reply_digest, auth->vector, AUTH_VECTOR_LEN);
     memcpy(auth->vector, vector, AUTH_VECTOR_LEN);
@@ -191,7 +207,6 @@
 	fprintf(stderr, "Warning: Received invalid reply digest from server\n");
 	return -1;
     }
-
     if (auth->code != PW_AUTHENTICATION_ACK)
 	return 1;
 
@@ -242,9 +257,9 @@
 	    crt = sscanf(line, "secret %s", secretkey);
 	if (!memcmp(line, "identifier", 10))
 	    sscanf(line, "identifier %s", identifier);
-       if (!memcmp(line, "service", 7))
+	if (!memcmp(line, "service", 7))
 	    sscanf(line, "service %s", svc_name);
-       if (!memcmp(line, "port", 4))
+	if (!memcmp(line, "port", 4))
 	    sscanf(line, "port %s", svc_name);
     }
     if (srv && crt)
@@ -338,7 +353,7 @@
     memcpy(cbc, auth->vector, AUTH_VECTOR_LEN);
     for (j = 0; j < length; j += AUTH_VECTOR_LEN) {
 	/* Calculate the MD5 Digest */
-	strcpy((char *)md5buf, secretkey);
+	strcpy((char *) md5buf, secretkey);
 	memcpy(md5buf + secretlen, cbc, AUTH_VECTOR_LEN);
 	md5_calc(cbc, md5buf, secretlen + AUTH_VECTOR_LEN);
 
@@ -391,7 +406,7 @@
      */
     auth->length = htons(total_length);
 
-    while(retry--) {
+    while (retry--) {
 	int time_spent;
 	struct timeval sent;
 	/*
@@ -424,7 +439,7 @@
 	    if (rc == 0)
 		return 1;
 	    if (rc == 1)
-	    	return 0;
+		return 0;
 	}
     }
 
@@ -450,7 +465,7 @@
     int c;
 
     while ((c = getopt(argc, argv, "h:p:f:w:i:t:")) != -1) {
-	switch(c) {
+	switch (c) {
 	case 'f':
 	    cfname = optarg;
 	    break;
@@ -481,17 +496,21 @@
 	    exit(1);
 	}
     }
-
     if (!*server) {
 	fprintf(stderr, "%s: Server not specified\n", argv[0]);
 	exit(1);
     }
-
     if (!*secretkey) {
 	fprintf(stderr, "%s: Shared secret not specified\n", argv[0]);
 	exit(1);
     }
-
+#ifdef _SQUID_MSWIN_
+    {
+	WSADATA wsaData;
+	WSAStartup(2, &wsaData);
+	atexit(Win32SockCleanup);
+    }
+#endif
     /*
      *    Open a connection to the server.
      */
diff -u -r -N squid-3.0.STABLE7/helpers/negotiate_auth/squid_kerb_auth/spnegohelp/spnegohelp.c squid-3.0.STABLE8/helpers/negotiate_auth/squid_kerb_auth/spnegohelp/spnegohelp.c
--- squid-3.0.STABLE7/helpers/negotiate_auth/squid_kerb_auth/spnegohelp/spnegohelp.c	2008-06-22 15:35:49.000000000 +1200
+++ squid-3.0.STABLE8/helpers/negotiate_auth/squid_kerb_auth/spnegohelp/spnegohelp.c	2008-07-18 22:02:50.000000000 +1200
@@ -1,263 +1,263 @@
-/* -----------------------------------------------------------------------------
- * spnegohelp.c defines RFC 2478 SPNEGO GSS-API mechanism APIs.
- *
- * Author: Frank Balluffi
- *
- * Copyright (C) 2002-2003 All rights reserved.
- *
- *   This program is free software; you can redistribute it and/or modify
- *   it under the terms of the GNU General Public License as published by
- *   the Free Software Foundation; either version 2 of the License, or
- *   (at your option) any later version.
- *
- *   This program is distributed in the hope that it will be useful,
- *   but WITHOUT ANY WARRANTY; without even the implied warranty of
- *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *   GNU General Public License for more details.
- *
- *   You should have received a copy of the GNU General Public License
- *   along with this program; if not, write to the Free Software
- *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307, USA.
- *
- * -----------------------------------------------------------------------------
- */
-
-#include "spnegohelp.h"
-#include "spnego.h"
-
-#include <stdlib.h>
-
-int makeNegTokenTarg (const unsigned char *  kerberosToken,
-                      size_t                 kerberosTokenLength,
-                      const unsigned char ** negTokenTarg,
-                      size_t *               negTokenTargLength)
-{
-    SPNEGO_TOKEN_HANDLE hSpnegoToken = NULL;
-    int                 rc1          = 1;
-    int                 rc2          = SPNEGO_E_SUCCESS;
-
-    /* Check arguments. */
-
-    if (!kerberosToken ||
-        !negTokenTarg  ||
-        !negTokenTargLength)
-        return 10;
-
-    /* Does IIS reply with 1.2.840.48018.1.2.2 or 1.2.840.113554.1.2.2? */
-
-    /* Does IIS always reply with accept_completed? */
-
-    /* IIS does not include a MIC. */
-
-    rc2 = spnegoCreateNegTokenTarg (spnego_mech_oid_Kerberos_V5_Legacy,
-                                    spnego_negresult_success,
-                                    (unsigned char *) kerberosToken,
-                                    kerberosTokenLength,
-                                    NULL,
-                                    0,
-                                    &hSpnegoToken);
-
-    if (rc2 != SPNEGO_E_SUCCESS)
-    {
-        rc1 = abs(rc2)+100;
-        goto cleanup;
-    }
-
-    /* Get NegTokenTarg length. */
-
-    rc2 = spnegoTokenGetBinary (hSpnegoToken,
-                                NULL,
-                                (unsigned long*) negTokenTargLength);
-
-    if (rc2 != SPNEGO_E_BUFFER_TOO_SMALL)
-    {
-        rc1 = abs(rc2)+200;
-        goto cleanup;
-    }
-
-    *negTokenTarg = malloc (*negTokenTargLength);
-
-    if (!*negTokenTarg)
-    {
-        rc1 = abs(rc2)+300;
-        goto cleanup;
-    }
-
-    /* Get NegTokenTarg data. */
-
-    rc2 = spnegoTokenGetBinary (hSpnegoToken,
-                              (unsigned char *) *negTokenTarg,
-                              (unsigned long*) negTokenTargLength);
-
-
-    if (rc2 != SPNEGO_E_SUCCESS)
-    {
-        rc1 = abs(rc2)+400;
-        goto error;
-    }
-
-    rc1 = 0;
-
-    goto cleanup;
-
-error:
-
-    if (*negTokenTarg)
-    {
-        free ((unsigned char *) *negTokenTarg);
-        *negTokenTarg = NULL;
-        *negTokenTargLength = 0;
-    }
-
-cleanup:
-
-    if (hSpnegoToken)
-        spnegoFreeData (hSpnegoToken);
-
-    LOG(("makeNegTokenTarg returned %d\n",rc1));
-    return rc1;
-}
-
-int parseNegTokenInit (const unsigned char *  negTokenInit,
-                       size_t                 negTokenInitLength,
-                       const unsigned char ** kerberosToken,
-                       size_t *               kerberosTokenLength)
-{
-    SPNEGO_TOKEN_HANDLE hSpnegoToken = NULL;
-    int                 pindex       = -1;
-    int                 rc1          = 1;
-    int                 rc2          = SPNEGO_E_SUCCESS;
-    unsigned char       reqFlags     = 0;
-    int                 tokenType    = 0;
-
-    /* Check arguments. */
-
-    if (!negTokenInit  ||
-        !kerberosToken ||
-        !kerberosTokenLength)
-        return 10;
-
-    /* Decode SPNEGO token. */
-
-    rc2 = spnegoInitFromBinary ((unsigned char *) negTokenInit,
-                                negTokenInitLength,
-                                &hSpnegoToken);
-
-    if (rc2 != SPNEGO_E_SUCCESS)
-    {
-        rc1 = abs(rc2)+100;
-        goto cleanup;
-    }
-
-    /* Check for negTokenInit choice. */
-
-    rc2 = spnegoGetTokenType (hSpnegoToken,
-                              &tokenType);
-
-    if (rc2 != SPNEGO_E_SUCCESS)
-    {
-        rc1 = abs(rc2)+200;
-        goto cleanup;
-    }
-
-    if (tokenType != SPNEGO_TOKEN_INIT)
-    {
-        rc1 = abs(rc2)+300;
-        goto cleanup;
-    }
-
-   /*
-    Check that first mechType is 1.2.840.113554.1.2.2 or 1.2.840.48018.1.2.2.
-    */
-
-   /*
-    IE seems to reply with 1.2.840.48018.1.2.2 and then 1.2.840.113554.1.2.2.
-    */
-
-    rc2 = spnegoIsMechTypeAvailable (hSpnegoToken,
-                                     spnego_mech_oid_Kerberos_V5_Legacy,
-                                     &pindex);
-
-    if (rc2 != SPNEGO_E_SUCCESS ||
-        pindex != 0)
-    {
-        rc2 = spnegoIsMechTypeAvailable (hSpnegoToken,
-                                         spnego_mech_oid_Kerberos_V5,
-                                         &pindex);
-
-        if (rc2 != SPNEGO_E_SUCCESS ||
-            pindex != 0)
-        {
-            rc1 = abs(rc2)+400;
-            goto cleanup;
-        }
-    }
-
-    /* Check for no reqFlags. */
-
-    /* Does IE ever send reqFlags? */
-
-    rc2 = spnegoGetContextFlags (hSpnegoToken,
-                                 &reqFlags);
-
-    if (rc2 == SPNEGO_E_SUCCESS)
-    {
-        rc1 = abs(rc2)+500;
-        goto cleanup;
-    }
-
-    /* Get mechanism token length. */
-
-    rc2 = spnegoGetMechToken (hSpnegoToken,
-                              NULL,
-                              (unsigned long*) kerberosTokenLength);
-
-    if (rc2 != SPNEGO_E_BUFFER_TOO_SMALL)
-    {
-        rc1 = abs(rc2)+600;
-        goto cleanup;
-    }
-
-    *kerberosToken = malloc (*kerberosTokenLength);
-
-    if (!*kerberosToken)
-    {
-        rc1 = abs(rc2)+700;
-        goto cleanup;
-    }
-
-    /* Get mechanism token data. */
-
-    rc2 = spnegoGetMechToken (hSpnegoToken,
-                              (unsigned char *) *kerberosToken,
-                              (unsigned long*) kerberosTokenLength);
-
-    if (rc2 != SPNEGO_E_SUCCESS)
-    {
-        rc1 = abs(rc2)+800;
-        goto error;
-    }
-
-    /* According to Microsoft, IE does not send a MIC. */
-
-    rc1 = 0;
-
-    goto cleanup;
-
-error:
-
-    if (*kerberosToken)
-    {
-        free ((unsigned char *) *kerberosToken);
-        *kerberosToken = NULL;
-        *kerberosTokenLength = 0;
-    }
-
-cleanup:
-
-    if (hSpnegoToken)
-        spnegoFreeData (hSpnegoToken);
-
-    LOG(("parseNegTokenInit returned %d\n",rc1));
-    return rc1;
-}
+/* -----------------------------------------------------------------------------
+ * spnegohelp.c defines RFC 2478 SPNEGO GSS-API mechanism APIs.
+ *
+ * Author: Frank Balluffi
+ *
+ * Copyright (C) 2002-2003 All rights reserved.
+ *
+ *   This program is free software; you can redistribute it and/or modify
+ *   it under the terms of the GNU General Public License as published by
+ *   the Free Software Foundation; either version 2 of the License, or
+ *   (at your option) any later version.
+ *
+ *   This program is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *   GNU General Public License for more details.
+ *
+ *   You should have received a copy of the GNU General Public License
+ *   along with this program; if not, write to the Free Software
+ *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307, USA.
+ *
+ * -----------------------------------------------------------------------------
+ */
+
+#include "spnegohelp.h"
+#include "spnego.h"
+
+#include <stdlib.h>
+
+int makeNegTokenTarg (const unsigned char *  kerberosToken,
+                      size_t                 kerberosTokenLength,
+                      const unsigned char ** negTokenTarg,
+                      size_t *               negTokenTargLength)
+{
+    SPNEGO_TOKEN_HANDLE hSpnegoToken = NULL;
+    int                 rc1          = 1;
+    int                 rc2          = SPNEGO_E_SUCCESS;
+
+    /* Check arguments. */
+
+    if (!kerberosToken ||
+        !negTokenTarg  ||
+        !negTokenTargLength)
+        return 10;
+
+    /* Does IIS reply with 1.2.840.48018.1.2.2 or 1.2.840.113554.1.2.2? */
+
+    /* Does IIS always reply with accept_completed? */
+
+    /* IIS does not include a MIC. */
+
+    rc2 = spnegoCreateNegTokenTarg (spnego_mech_oid_Kerberos_V5_Legacy,
+                                    spnego_negresult_success,
+                                    (unsigned char *) kerberosToken,
+                                    kerberosTokenLength,
+                                    NULL,
+                                    0,
+                                    &hSpnegoToken);
+
+    if (rc2 != SPNEGO_E_SUCCESS)
+    {
+        rc1 = abs(rc2)+100;
+        goto cleanup;
+    }
+
+    /* Get NegTokenTarg length. */
+
+    rc2 = spnegoTokenGetBinary (hSpnegoToken,
+                                NULL,
+                                (unsigned long*) negTokenTargLength);
+
+    if (rc2 != SPNEGO_E_BUFFER_TOO_SMALL)
+    {
+        rc1 = abs(rc2)+200;
+        goto cleanup;
+    }
+
+    *negTokenTarg = malloc (*negTokenTargLength);
+
+    if (!*negTokenTarg)
+    {
+        rc1 = abs(rc2)+300;
+        goto cleanup;
+    }
+
+    /* Get NegTokenTarg data. */
+
+    rc2 = spnegoTokenGetBinary (hSpnegoToken,
+                              (unsigned char *) *negTokenTarg,
+                              (unsigned long*) negTokenTargLength);
+
+
+    if (rc2 != SPNEGO_E_SUCCESS)
+    {
+        rc1 = abs(rc2)+400;
+        goto error;
+    }
+
+    rc1 = 0;
+
+    goto cleanup;
+
+error:
+
+    if (*negTokenTarg)
+    {
+        free ((unsigned char *) *negTokenTarg);
+        *negTokenTarg = NULL;
+        *negTokenTargLength = 0;
+    }
+
+cleanup:
+
+    if (hSpnegoToken)
+        spnegoFreeData (hSpnegoToken);
+
+    LOG(("makeNegTokenTarg returned %d\n",rc1));
+    return rc1;
+}
+
+int parseNegTokenInit (const unsigned char *  negTokenInit,
+                       size_t                 negTokenInitLength,
+                       const unsigned char ** kerberosToken,
+                       size_t *               kerberosTokenLength)
+{
+    SPNEGO_TOKEN_HANDLE hSpnegoToken = NULL;
+    int                 pindex       = -1;
+    int                 rc1          = 1;
+    int                 rc2          = SPNEGO_E_SUCCESS;
+    unsigned char       reqFlags     = 0;
+    int                 tokenType    = 0;
+
+    /* Check arguments. */
+
+    if (!negTokenInit  ||
+        !kerberosToken ||
+        !kerberosTokenLength)
+        return 10;
+
+    /* Decode SPNEGO token. */
+
+    rc2 = spnegoInitFromBinary ((unsigned char *) negTokenInit,
+                                negTokenInitLength,
+                                &hSpnegoToken);
+
+    if (rc2 != SPNEGO_E_SUCCESS)
+    {
+        rc1 = abs(rc2)+100;
+        goto cleanup;
+    }
+
+    /* Check for negTokenInit choice. */
+
+    rc2 = spnegoGetTokenType (hSpnegoToken,
+                              &tokenType);
+
+    if (rc2 != SPNEGO_E_SUCCESS)
+    {
+        rc1 = abs(rc2)+200;
+        goto cleanup;
+    }
+
+    if (tokenType != SPNEGO_TOKEN_INIT)
+    {
+        rc1 = abs(rc2)+300;
+        goto cleanup;
+    }
+
+   /*
+    Check that first mechType is 1.2.840.113554.1.2.2 or 1.2.840.48018.1.2.2.
+    */
+
+   /*
+    IE seems to reply with 1.2.840.48018.1.2.2 and then 1.2.840.113554.1.2.2.
+    */
+
+    rc2 = spnegoIsMechTypeAvailable (hSpnegoToken,
+                                     spnego_mech_oid_Kerberos_V5_Legacy,
+                                     &pindex);
+
+    if (rc2 != SPNEGO_E_SUCCESS ||
+        pindex != 0)
+    {
+        rc2 = spnegoIsMechTypeAvailable (hSpnegoToken,
+                                         spnego_mech_oid_Kerberos_V5,
+                                         &pindex);
+
+        if (rc2 != SPNEGO_E_SUCCESS ||
+            pindex != 0)
+        {
+            rc1 = abs(rc2)+400;
+            goto cleanup;
+        }
+    }
+
+    /* Check for no reqFlags. */
+
+    /* Does IE ever send reqFlags? */
+
+    rc2 = spnegoGetContextFlags (hSpnegoToken,
+                                 &reqFlags);
+
+    if (rc2 == SPNEGO_E_SUCCESS)
+    {
+        rc1 = abs(rc2)+500;
+        goto cleanup;
+    }
+
+    /* Get mechanism token length. */
+
+    rc2 = spnegoGetMechToken (hSpnegoToken,
+                              NULL,
+                              (unsigned long*) kerberosTokenLength);
+
+    if (rc2 != SPNEGO_E_BUFFER_TOO_SMALL)
+    {
+        rc1 = abs(rc2)+600;
+        goto cleanup;
+    }
+
+    *kerberosToken = malloc (*kerberosTokenLength);
+
+    if (!*kerberosToken)
+    {
+        rc1 = abs(rc2)+700;
+        goto cleanup;
+    }
+
+    /* Get mechanism token data. */
+
+    rc2 = spnegoGetMechToken (hSpnegoToken,
+                              (unsigned char *) *kerberosToken,
+                              (unsigned long*) kerberosTokenLength);
+
+    if (rc2 != SPNEGO_E_SUCCESS)
+    {
+        rc1 = abs(rc2)+800;
+        goto error;
+    }
+
+    /* According to Microsoft, IE does not send a MIC. */
+
+    rc1 = 0;
+
+    goto cleanup;
+
+error:
+
+    if (*kerberosToken)
+    {
+        free ((unsigned char *) *kerberosToken);
+        *kerberosToken = NULL;
+        *kerberosTokenLength = 0;
+    }
+
+cleanup:
+
+    if (hSpnegoToken)
+        spnegoFreeData (hSpnegoToken);
+
+    LOG(("parseNegTokenInit returned %d\n",rc1));
+    return rc1;
+}
diff -u -r -N squid-3.0.STABLE7/helpers/negotiate_auth/squid_kerb_auth/spnegohelp/spnegohelp.h squid-3.0.STABLE8/helpers/negotiate_auth/squid_kerb_auth/spnegohelp/spnegohelp.h
--- squid-3.0.STABLE7/helpers/negotiate_auth/squid_kerb_auth/spnegohelp/spnegohelp.h	2008-06-22 15:35:49.000000000 +1200
+++ squid-3.0.STABLE8/helpers/negotiate_auth/squid_kerb_auth/spnegohelp/spnegohelp.h	2008-07-18 22:02:50.000000000 +1200
@@ -1,58 +1,58 @@
-/* -----------------------------------------------------------------------------
- * spnegohelp.c declares RFC 2478 SPNEGO GSS-API mechanism APIs.
- *
- * Author: Frank Balluffi
- *
- * Copyright (C) 2002-2003. All rights reserved.
- * -----------------------------------------------------------------------------
- */
-
-#ifndef SPNEGOHELP_H
-#define SPNEGOHELP_H
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-#include <stddef.h>
-
-/* -----------------------------------------------------------------------------
- * makeNegTokenTarg makes an RFC 2478 SPNEGO NegTokenTarg (token) from an
- * RFC 1964 Kerberos GSS-API token.
- *
- * If makeNegTokenTarg is successful, call free (*negTokenTarg) to free the
- * memory allocated by parseNegTokenInit.
- *
- * Returns 0 if successful, 1 otherwise.
- * -----------------------------------------------------------------------------
- */
-
-int makeNegTokenTarg (const unsigned char *  kerberosToken,
-                      size_t                 kerberosTokenLength,
-                      const unsigned char ** negTokenTarg,
-                      size_t *               negTokenTargLength);
-
-/* -----------------------------------------------------------------------------
- * parseNegTokenInit parses an RFC 2478 SPNEGO NegTokenInit (token) to extract
- * an RFC 1964 Kerberos GSS-API token.
- *
- * If the NegTokenInit does cotain a Kerberos GSS-API token, parseNegTokenInit
- * returns an error.
- *
- * If parseNegTokenInit is successful, call free (*kerberosToken) to
- * free the memory allocated by parseNegTokenInit.
- *
- * Returns 0 if successful, 1 otherwise.
- * -----------------------------------------------------------------------------
- */
-
-int parseNegTokenInit (const unsigned char *  negTokenInit,
-                       size_t                 negTokenInitLength,
-                       const unsigned char ** kerberosToken,
-                       size_t *               kerberosTokenLength);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* SPNEGOHELP_H */
+/* -----------------------------------------------------------------------------
+ * spnegohelp.c declares RFC 2478 SPNEGO GSS-API mechanism APIs.
+ *
+ * Author: Frank Balluffi
+ *
+ * Copyright (C) 2002-2003. All rights reserved.
+ * -----------------------------------------------------------------------------
+ */
+
+#ifndef SPNEGOHELP_H
+#define SPNEGOHELP_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <stddef.h>
+
+/* -----------------------------------------------------------------------------
+ * makeNegTokenTarg makes an RFC 2478 SPNEGO NegTokenTarg (token) from an
+ * RFC 1964 Kerberos GSS-API token.
+ *
+ * If makeNegTokenTarg is successful, call free (*negTokenTarg) to free the
+ * memory allocated by parseNegTokenInit.
+ *
+ * Returns 0 if successful, 1 otherwise.
+ * -----------------------------------------------------------------------------
+ */
+
+int makeNegTokenTarg (const unsigned char *  kerberosToken,
+                      size_t                 kerberosTokenLength,
+                      const unsigned char ** negTokenTarg,
+                      size_t *               negTokenTargLength);
+
+/* -----------------------------------------------------------------------------
+ * parseNegTokenInit parses an RFC 2478 SPNEGO NegTokenInit (token) to extract
+ * an RFC 1964 Kerberos GSS-API token.
+ *
+ * If the NegTokenInit does cotain a Kerberos GSS-API token, parseNegTokenInit
+ * returns an error.
+ *
+ * If parseNegTokenInit is successful, call free (*kerberosToken) to
+ * free the memory allocated by parseNegTokenInit.
+ *
+ * Returns 0 if successful, 1 otherwise.
+ * -----------------------------------------------------------------------------
+ */
+
+int parseNegTokenInit (const unsigned char *  negTokenInit,
+                       size_t                 negTokenInitLength,
+                       const unsigned char ** kerberosToken,
+                       size_t *               kerberosTokenLength);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* SPNEGOHELP_H */
diff -u -r -N squid-3.0.STABLE7/helpers/ntlm_auth/fakeauth/fakeauth_auth.c squid-3.0.STABLE8/helpers/ntlm_auth/fakeauth/fakeauth_auth.c
--- squid-3.0.STABLE7/helpers/ntlm_auth/fakeauth/fakeauth_auth.c	2008-06-22 15:35:49.000000000 +1200
+++ squid-3.0.STABLE8/helpers/ntlm_auth/fakeauth/fakeauth_auth.c	2008-07-18 22:02:51.000000000 +1200
@@ -299,9 +299,12 @@
     buf += (s - 1);
     *buf++ = '\\';		/* Using \ is more consistent with MS-proxy */
 
-    p = ntlmGetString(&auth->hdr, &auth->user, auth->flags);
+    if( (p = ntlmGetString(&auth->hdr, &auth->user, auth->flags)) == NULL)
+        return 1;
+
     if ((s = strlen(p) + 1) >= size)
 	return 1;
+
     while (*p)
 	*buf++ = (*p++);	//tolower
 
@@ -429,7 +432,10 @@
 		if (!ntlmDecodeAuth((struct ntlm_authenticate *) decoded, user, 256)) {
 		    lc(user);
 		    if (strip_domain_enabled) {
-			strtok_r(user, "\\", &p);
+			strtok(user, "\\");
+			p = strtok(NULL, "\\");
+			if (!p)
+			    p = user;
 			SEND2("AF %s", p);
 			} else {
 		    SEND2("AF %s", user);
diff -u -r -N squid-3.0.STABLE7/include/autoconf.h.in squid-3.0.STABLE8/include/autoconf.h.in
--- squid-3.0.STABLE7/include/autoconf.h.in	2008-06-22 15:35:50.000000000 +1200
+++ squid-3.0.STABLE8/include/autoconf.h.in	2008-07-18 22:02:51.000000000 +1200
@@ -736,6 +736,12 @@
 /* Define if you have PSAPI.DLL on Windows systems */
 #undef HAVE_WIN32_PSAPI
 
+/* Define to 1 if you have the <winsock2.h> header file. */
+#undef HAVE_WINSOCK2_H
+
+/* Define to 1 if you have the <winsock.h> header file. */
+#undef HAVE_WINSOCK_H
+
 /* __int64 is defined in system headers */
 #undef HAVE___INT64
 
diff -u -r -N squid-3.0.STABLE7/include/squid_mswin.h squid-3.0.STABLE8/include/squid_mswin.h
--- squid-3.0.STABLE7/include/squid_mswin.h	2008-06-22 15:35:50.000000000 +1200
+++ squid-3.0.STABLE8/include/squid_mswin.h	2008-07-18 22:02:51.000000000 +1200
@@ -70,7 +70,6 @@
 #include "default_config_file.h"
 /* Some tricks for MS Compilers */
 #define __STDC__ 1
-#pragma include_alias(<dirent.h>, <direct.h>)
 #define THREADLOCAL __declspec(thread)
 
 #elif defined(__GNUC__) /* gcc environment */
@@ -221,12 +220,9 @@
 #include <ws2spi.h>
 #if defined(_MSC_VER) /* Microsoft C Compiler ONLY */
 #pragma warning (pop)
-#include "readdir.h"
-#else
+#endif
 #include <io.h>
 #include <stdlib.h>
-#include <sys/types.h> 
-#endif
 
 typedef char * caddr_t;
 
@@ -250,7 +246,7 @@
 #undef FD_CLR
 #define FD_CLR(fd, set) do { \
     u_int __i; \
-    SOCKET __sock = fd_table[fd].win32.handle; \
+    SOCKET __sock = _get_osfhandle(fd); \
     for (__i = 0; __i < ((fd_set FAR *)(set))->fd_count ; __i++) { \
         if (((fd_set FAR *)(set))->fd_array[__i] == __sock) { \
             while (__i < ((fd_set FAR *)(set))->fd_count-1) { \
@@ -267,7 +263,7 @@
 #undef FD_SET
 #define FD_SET(fd, set) do { \
     u_int __i; \
-    SOCKET __sock = fd_table[fd].win32.handle; \
+    SOCKET __sock = _get_osfhandle(fd); \
     for (__i = 0; __i < ((fd_set FAR *)(set))->fd_count; __i++) { \
         if (((fd_set FAR *)(set))->fd_array[__i] == (__sock)) { \
             break; \
diff -u -r -N squid-3.0.STABLE7/include/version.h squid-3.0.STABLE8/include/version.h
--- squid-3.0.STABLE7/include/version.h	2008-06-22 15:35:54.000000000 +1200
+++ squid-3.0.STABLE8/include/version.h	2008-07-18 22:02:55.000000000 +1200
@@ -9,5 +9,5 @@
  */
 
 #ifndef SQUID_RELEASE_TIME
-#define SQUID_RELEASE_TIME 1214105735
+#define SQUID_RELEASE_TIME 1216375359
 #endif
diff -u -r -N squid-3.0.STABLE7/lib/dirent.c squid-3.0.STABLE8/lib/dirent.c
--- squid-3.0.STABLE7/lib/dirent.c	1970-01-01 12:00:00.000000000 +1200
+++ squid-3.0.STABLE8/lib/dirent.c	2008-07-18 22:02:51.000000000 +1200
@@ -0,0 +1,316 @@
+/*
+ * $Id$
+ *
+ * Implement dirent-style opendir(), readdir(), closedir(), rewinddir(),
+ * seekdir() and telldir on Windows - Based on mingw-runtime package sources.
+ * AUTHOR: Guido Serassio <serassio@squid-cache.org>
+ *
+ * SQUID Web Proxy Cache          http://www.squid-cache.org/
+ * ----------------------------------------------------------
+ *
+ *  Squid is the result of efforts by numerous individuals from
+ *  the Internet community; see the CONTRIBUTORS file for full
+ *  details.   Many organizations have provided support for Squid's
+ *  development; see the SPONSORS file for full details.  Squid is
+ *  Copyrighted (C) 2001 by the Regents of the University of
+ *  California; see the COPYRIGHT file for full details.  Squid
+ *  incorporates software developed and/or copyrighted by other
+ *  sources; see the CREDITS file for full details.
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *  
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *  
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111, USA.
+ *
+ * Original file info follow:
+ *
+ * dirent.c
+ * This file has no copyright assigned and is placed in the Public Domain.
+ * This file is a part of the mingw-runtime package.
+ * No warranty is given; refer to the file DISCLAIMER within the package.
+ *
+ * Derived from DIRLIB.C by Matt J. Weinstein 
+ * This note appears in the DIRLIB.H
+ * DIRLIB.H by M. J. Weinstein   Released to public domain 1-Jan-89
+ *
+ * Updated by Jeremy Bettis <jeremy@hksys.com>
+ * Significantly revised and rewinddir, seekdir and telldir added by Colin
+ * Peters <colin@fu.is.saga-u.ac.jp>
+ *      
+ */
+
+#include "util.h"
+
+/* The following code section is part of the native Windows Squid port */
+#if defined(_SQUID_MSWIN_)
+#include <stdlib.h>
+#include <errno.h>
+#include <string.h>
+#include <io.h>
+#include <dirent.h>
+
+#define WIN32_LEAN_AND_MEAN
+#include <windows.h>		/* for GetFileAttributes */
+
+#define SUFFIX	("*")
+#define	SLASH	("\\")
+
+
+/*
+ * opendir
+ *
+ * Returns a pointer to a DIR structure appropriately filled in to begin
+ * searching a directory.
+ */
+DIR *
+opendir(const CHAR * szPath)
+{
+    DIR *nd;
+    unsigned int rc;
+    CHAR szFullPath[MAX_PATH];
+
+    errno = 0;
+
+    if (!szPath) {
+	errno = EFAULT;
+	return (DIR *) 0;
+    }
+    if (szPath[0] == '\0') {
+	errno = ENOTDIR;
+	return (DIR *) 0;
+    }
+    /* Attempt to determine if the given path really is a directory. */
+    rc = GetFileAttributes(szPath);
+    if (rc == (unsigned int) -1) {
+	/* call GetLastError for more error info */
+	errno = ENOENT;
+	return (DIR *) 0;
+    }
+    if (!(rc & FILE_ATTRIBUTE_DIRECTORY)) {
+	/* Error, entry exists but not a directory. */
+	errno = ENOTDIR;
+	return (DIR *) 0;
+    }
+    /* Make an absolute pathname.  */
+    _fullpath(szFullPath, szPath, MAX_PATH);
+
+    /* Allocate enough space to store DIR structure and the complete
+     * directory path given. */
+    nd = (DIR *) malloc(sizeof(DIR) + (strlen(szFullPath)
+	    + strlen(SLASH)
+	    + strlen(SUFFIX) + 1)
+	* sizeof(CHAR));
+
+    if (!nd) {
+	/* Error, out of memory. */
+	errno = ENOMEM;
+	return (DIR *) 0;
+    }
+    /* Create the search expression. */
+    strcpy(nd->dd_name, szFullPath);
+
+    /* Add on a slash if the path does not end with one. */
+    if (nd->dd_name[0] != '\0'
+	&& strchr(nd->dd_name, '/') != nd->dd_name
+	+ strlen(nd->dd_name) - 1
+	&& strchr(nd->dd_name, '\\') != nd->dd_name
+	+ strlen(nd->dd_name) - 1) {
+	strcat(nd->dd_name, SLASH);
+    }
+    /* Add on the search pattern */
+    strcat(nd->dd_name, SUFFIX);
+
+    /* Initialize handle to -1 so that a premature closedir doesn't try
+     * to call _findclose on it. */
+    nd->dd_handle = -1;
+
+    /* Initialize the status. */
+    nd->dd_stat = 0;
+
+    /* Initialize the dirent structure. ino and reclen are invalid under
+     * Win32, and name simply points at the appropriate part of the
+     * findfirst_t structure. */
+    nd->dd_dir.d_ino = 0;
+    nd->dd_dir.d_reclen = 0;
+    nd->dd_dir.d_namlen = 0;
+    memset(nd->dd_dir.d_name, 0, FILENAME_MAX);
+
+    return nd;
+}
+
+
+/*
+ * readdir
+ *
+ * Return a pointer to a dirent structure filled with the information on the
+ * next entry in the directory.
+ */
+struct dirent *
+readdir(DIR * dirp)
+{
+    errno = 0;
+
+    /* Check for valid DIR struct. */
+    if (!dirp) {
+	errno = EFAULT;
+	return (struct dirent *) 0;
+    }
+    if (dirp->dd_stat < 0) {
+	/* We have already returned all files in the directory
+	 * (or the structure has an invalid dd_stat). */
+	return (struct dirent *) 0;
+    } else if (dirp->dd_stat == 0) {
+	/* We haven't started the search yet. */
+	/* Start the search */
+	dirp->dd_handle = _findfirst(dirp->dd_name, &(dirp->dd_dta));
+
+	if (dirp->dd_handle == -1) {
+	    /* Whoops! Seems there are no files in that
+	     * directory. */
+	    dirp->dd_stat = -1;
+	} else {
+	    dirp->dd_stat = 1;
+	}
+    } else {
+	/* Get the next search entry. */
+	if (_findnext(dirp->dd_handle, &(dirp->dd_dta))) {
+	    /* We are off the end or otherwise error.     
+	     * _findnext sets errno to ENOENT if no more file
+	     * Undo this. */
+	    DWORD winerr = GetLastError();
+	    if (winerr == ERROR_NO_MORE_FILES)
+		errno = 0;
+	    _findclose(dirp->dd_handle);
+	    dirp->dd_handle = -1;
+	    dirp->dd_stat = -1;
+	} else {
+	    /* Update the status to indicate the correct
+	     * number. */
+	    dirp->dd_stat++;
+	}
+    }
+
+    if (dirp->dd_stat > 0) {
+	/* Successfully got an entry. Everything about the file is
+	 * already appropriately filled in except the length of the
+	 * file name. */
+	dirp->dd_dir.d_namlen = strlen(dirp->dd_dta.name);
+	strcpy(dirp->dd_dir.d_name, dirp->dd_dta.name);
+	return &dirp->dd_dir;
+    }
+    return (struct dirent *) 0;
+}
+
+
+/*
+ * closedir
+ *
+ * Frees up resources allocated by opendir.
+ */
+int
+closedir(DIR * dirp)
+{
+    int rc;
+
+    errno = 0;
+    rc = 0;
+
+    if (!dirp) {
+	errno = EFAULT;
+	return -1;
+    }
+    if (dirp->dd_handle != -1) {
+	rc = _findclose(dirp->dd_handle);
+    }
+    /* Delete the dir structure. */
+    free(dirp);
+
+    return rc;
+}
+
+/*
+ * rewinddir
+ *
+ * Return to the beginning of the directory "stream". We simply call findclose
+ * and then reset things like an opendir.
+ */
+void
+rewinddir(DIR * dirp)
+{
+    errno = 0;
+
+    if (!dirp) {
+	errno = EFAULT;
+	return;
+    }
+    if (dirp->dd_handle != -1) {
+	_findclose(dirp->dd_handle);
+    }
+    dirp->dd_handle = -1;
+    dirp->dd_stat = 0;
+}
+
+/*
+ * telldir
+ *
+ * Returns the "position" in the "directory stream" which can be used with
+ * seekdir to go back to an old entry. We simply return the value in stat.
+ */
+long
+telldir(DIR * dirp)
+{
+    errno = 0;
+
+    if (!dirp) {
+	errno = EFAULT;
+	return -1;
+    }
+    return dirp->dd_stat;
+}
+
+/*
+ * seekdir
+ *
+ * Seek to an entry previously returned by telldir. We rewind the directory
+ * and call readdir repeatedly until either dd_stat is the position number
+ * or -1 (off the end). This is not perfect, in that the directory may
+ * have changed while we weren't looking. But that is probably the case with
+ * any such system.
+ */
+void
+seekdir(DIR * dirp, long lPos)
+{
+    errno = 0;
+
+    if (!dirp) {
+	errno = EFAULT;
+	return;
+    }
+    if (lPos < -1) {
+	/* Seeking to an invalid position. */
+	errno = EINVAL;
+	return;
+    } else if (lPos == -1) {
+	/* Seek past end. */
+	if (dirp->dd_handle != -1) {
+	    _findclose(dirp->dd_handle);
+	}
+	dirp->dd_handle = -1;
+	dirp->dd_stat = -1;
+    } else {
+	/* Rewind and read forward to the appropriate index. */
+	rewinddir(dirp);
+
+	while ((dirp->dd_stat < lPos) && readdir(dirp));
+    }
+}
+#endif /* _SQUID_MSWIN_ */
diff -u -r -N squid-3.0.STABLE7/lib/encrypt.c squid-3.0.STABLE8/lib/encrypt.c
--- squid-3.0.STABLE7/lib/encrypt.c	1970-01-01 12:00:00.000000000 +1200
+++ squid-3.0.STABLE8/lib/encrypt.c	2008-07-18 22:02:51.000000000 +1200
@@ -0,0 +1,309 @@
+/* encrypt.c - providing 56 bit DES encryption
+ * Copyright (C) 1991 Jochen Obalek
+ * 
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ * 
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.  */
+
+#include <time.h>
+#include <string.h>
+#include <stdlib.h>
+
+#define BS  64
+#define BS2 32
+#define KS  48
+#define KS2 24
+#define IS  56
+#define IS2 28
+
+static char schluessel[16][KS];
+
+
+static char PC1[] =
+{
+    56, 48, 40, 32, 24, 16, 8, 0,
+    57, 49, 41, 33, 25, 17, 9, 1,
+    58, 50, 42, 34, 26, 18, 10, 2,
+    59, 51, 43, 35,
+    62, 54, 46, 38, 30, 22, 14, 6,
+    61, 53, 45, 37, 29, 21, 13, 5,
+    60, 52, 44, 36, 28, 20, 12, 4,
+    27, 19, 11, 3
+};
+
+
+static char PC2[] =
+{
+    13, 16, 10, 23, 0, 4, 2, 27,
+    14, 5, 20, 9, 22, 18, 11, 3,
+    25, 7, 15, 6, 26, 19, 12, 1,
+    40, 51, 30, 36, 46, 54, 29, 39,
+    50, 44, 32, 47, 43, 48, 38, 55,
+    33, 52, 45, 41, 49, 35, 28, 31
+};
+
+
+static char IP[] =
+{
+    57, 49, 41, 33, 25, 17, 9, 1,
+    59, 51, 43, 35, 27, 19, 11, 3,
+    61, 53, 45, 37, 29, 21, 13, 5,
+    63, 55, 47, 39, 31, 23, 15, 7,
+    56, 48, 40, 32, 24, 16, 8, 0,
+    58, 50, 42, 34, 26, 18, 10, 2,
+    60, 52, 44, 36, 28, 20, 12, 4,
+    62, 54, 46, 38, 30, 22, 14, 6
+};
+
+
+static char EP[] =
+{
+    7, 39, 15, 47, 23, 55, 31, 63,
+    6, 38, 14, 46, 22, 54, 30, 62,
+    5, 37, 13, 45, 21, 53, 29, 61,
+    4, 36, 12, 44, 20, 52, 28, 60,
+    3, 35, 11, 43, 19, 51, 27, 59,
+    2, 34, 10, 42, 18, 50, 26, 58,
+    1, 33, 9, 41, 17, 49, 25, 57,
+    0, 32, 8, 40, 16, 48, 24, 56
+};
+
+
+static char E0[] =
+{
+    31, 0, 1, 2, 3, 4, 3, 4,
+    5, 6, 7, 8, 7, 8, 9, 10,
+    11, 12, 11, 12, 13, 14, 15, 16,
+    15, 16, 17, 18, 19, 20, 19, 20,
+    21, 22, 23, 24, 23, 24, 25, 26,
+    27, 28, 27, 28, 29, 30, 31, 0
+};
+
+
+static char E[KS];
+
+
+static char PERM[] =
+{
+    15, 6, 19, 20, 28, 11, 27, 16,
+    0, 14, 22, 25, 4, 17, 30, 9,
+    1, 7, 23, 13, 31, 26, 2, 8,
+    18, 12, 29, 5, 21, 10, 3, 24
+};
+
+
+static char S_BOX[][64] =
+{
+    {
+	14, 0, 4, 15, 13, 7, 1, 4, 2, 14, 15, 2, 11, 13, 8, 1,
+	3, 10, 10, 6, 6, 12, 12, 11, 5, 9, 9, 5, 0, 3, 7, 8,
+	4, 15, 1, 12, 14, 8, 8, 2, 13, 4, 6, 9, 2, 1, 11, 7,
+	15, 5, 12, 11, 9, 3, 7, 14, 3, 10, 10, 0, 5, 6, 0, 13
+    },
+    {
+	15, 3, 1, 13, 8, 4, 14, 7, 6, 15, 11, 2, 3, 8, 4, 14,
+	9, 12, 7, 0, 2, 1, 13, 10, 12, 6, 0, 9, 5, 11, 10, 5,
+	0, 13, 14, 8, 7, 10, 11, 1, 10, 3, 4, 15, 13, 4, 1, 2,
+	5, 11, 8, 6, 12, 7, 6, 12, 9, 0, 3, 5, 2, 14, 15, 9
+    },
+    {
+	10, 13, 0, 7, 9, 0, 14, 9, 6, 3, 3, 4, 15, 6, 5, 10,
+	1, 2, 13, 8, 12, 5, 7, 14, 11, 12, 4, 11, 2, 15, 8, 1,
+	13, 1, 6, 10, 4, 13, 9, 0, 8, 6, 15, 9, 3, 8, 0, 7,
+	11, 4, 1, 15, 2, 14, 12, 3, 5, 11, 10, 5, 14, 2, 7, 12
+    },
+    {
+	7, 13, 13, 8, 14, 11, 3, 5, 0, 6, 6, 15, 9, 0, 10, 3,
+	1, 4, 2, 7, 8, 2, 5, 12, 11, 1, 12, 10, 4, 14, 15, 9,
+	10, 3, 6, 15, 9, 0, 0, 6, 12, 10, 11, 1, 7, 13, 13, 8,
+	15, 9, 1, 4, 3, 5, 14, 11, 5, 12, 2, 7, 8, 2, 4, 14
+    },
+    {
+	2, 14, 12, 11, 4, 2, 1, 12, 7, 4, 10, 7, 11, 13, 6, 1,
+	8, 5, 5, 0, 3, 15, 15, 10, 13, 3, 0, 9, 14, 8, 9, 6,
+	4, 11, 2, 8, 1, 12, 11, 7, 10, 1, 13, 14, 7, 2, 8, 13,
+	15, 6, 9, 15, 12, 0, 5, 9, 6, 10, 3, 4, 0, 5, 14, 3
+    },
+    {
+	12, 10, 1, 15, 10, 4, 15, 2, 9, 7, 2, 12, 6, 9, 8, 5,
+	0, 6, 13, 1, 3, 13, 4, 14, 14, 0, 7, 11, 5, 3, 11, 8,
+	9, 4, 14, 3, 15, 2, 5, 12, 2, 9, 8, 5, 12, 15, 3, 10,
+	7, 11, 0, 14, 4, 1, 10, 7, 1, 6, 13, 0, 11, 8, 6, 13
+    },
+    {
+	4, 13, 11, 0, 2, 11, 14, 7, 15, 4, 0, 9, 8, 1, 13, 10,
+	3, 14, 12, 3, 9, 5, 7, 12, 5, 2, 10, 15, 6, 8, 1, 6,
+	1, 6, 4, 11, 11, 13, 13, 8, 12, 1, 3, 4, 7, 10, 14, 7,
+	10, 9, 15, 5, 6, 0, 8, 15, 0, 14, 5, 2, 9, 3, 2, 12
+    },
+    {
+	13, 1, 2, 15, 8, 13, 4, 8, 6, 10, 15, 3, 11, 7, 1, 4,
+	10, 12, 9, 5, 3, 6, 14, 11, 5, 0, 0, 14, 12, 9, 7, 2,
+	7, 2, 11, 1, 4, 14, 1, 7, 9, 4, 12, 10, 14, 8, 2, 13,
+	0, 15, 6, 12, 10, 9, 13, 0, 15, 3, 3, 5, 5, 6, 8, 11
+    }
+};
+
+static void
+perm(a, e, pc, n)
+     register char *a, *e;
+     register char *pc;
+     int n;
+{
+    for (; n--; pc++, a++)
+	*a = e[*pc];
+}
+
+static void
+crypt_main(nachr_l, nachr_r, schl)
+     register char *nachr_l, *nachr_r;
+     register char *schl;
+{
+    char tmp[KS];
+    register int sbval;
+    register char *tp = tmp;
+    register char *e = E;
+    register int i, j;
+
+    for (i = 0; i < 8; i++) {
+	for (j = 0, sbval = 0; j < 6; j++)
+	    sbval = (sbval << 1) | (nachr_r[*e++] ^ *schl++);
+	sbval = S_BOX[i][sbval];
+	for (tp += 4, j = 4; j--; sbval >>= 1)
+	    *--tp = sbval & 1;
+	tp += 4;
+    }
+
+    e = PERM;
+    for (i = 0; i < BS2; i++)
+	*nachr_l++ ^= tmp[*e++];
+}
+
+void
+encrypt(char *nachr, int decr)
+{
+    char (*schl)[KS] = decr ? schluessel + 15 : schluessel;
+    char tmp[BS];
+    int i;
+
+    perm(tmp, nachr, IP, BS);
+
+    for (i = 8; i--;) {
+	crypt_main(tmp, tmp + BS2, *schl);
+	if (decr)
+	    schl--;
+	else
+	    schl++;
+	crypt_main(tmp + BS2, tmp, *schl);
+	if (decr)
+	    schl--;
+	else
+	    schl++;
+    }
+
+    perm(nachr, tmp, EP, BS);
+}
+
+void
+setkey(char *schl)
+{
+    char tmp1[IS];
+    register unsigned int ls = 0x7efc;
+    register int i, j, k;
+    register int shval = 0;
+    register char *akt_schl;
+
+    memcpy(E, E0, KS);
+    perm(tmp1, schl, PC1, IS);
+
+    for (i = 0; i < 16; i++) {
+	shval += 1 + (ls & 1);
+	akt_schl = schluessel[i];
+	for (j = 0; j < KS; j++) {
+	    if ((k = PC2[j]) >= IS2) {
+		if ((k += shval) >= IS)
+		    k = (k - IS2) % IS2 + IS2;
+	    } else if ((k += shval) >= IS2)
+		k %= IS2;
+	    *akt_schl++ = tmp1[k];
+	}
+	ls >>= 1;
+    }
+}
+
+char *
+crypt(const char *wort, const char *salt)
+{
+    static char retkey[14];
+    char key[BS + 2];
+    char *k;
+    int tmp, keybyte;
+    int i, j;
+
+    memset(key, 0, BS + 2);
+
+    for (k = key, i = 0; i < BS; i++) {
+	if (!(keybyte = *wort++))
+	    break;
+	k += 7;
+	for (j = 0; j < 7; j++, i++) {
+	    *--k = keybyte & 1;
+	    keybyte >>= 1;
+	}
+	k += 8;
+    }
+
+    setkey(key);
+    memset(key, 0, BS + 2);
+
+    for (k = E, i = 0; i < 2; i++) {
+	retkey[i] = keybyte = *salt++;
+	if (keybyte > 'Z')
+	    keybyte -= 'a' - 'Z' - 1;
+	if (keybyte > '9')
+	    keybyte -= 'A' - '9' - 1;
+	keybyte -= '.';
+
+	for (j = 0; j < 6; j++, keybyte >>= 1, k++) {
+	    if (!(keybyte & 1))
+		continue;
+	    tmp = *k;
+	    *k = k[24];
+	    k[24] = tmp;
+	}
+    }
+
+    for (i = 0; i < 25; i++)
+	encrypt(key, 0);
+
+    for (k = key, i = 0; i < 11; i++) {
+	for (j = keybyte = 0; j < 6; j++) {
+	    keybyte <<= 1;
+	    keybyte |= *k++;
+	}
+
+	keybyte += '.';
+	if (keybyte > '9')
+	    keybyte += 'A' - '9' - 1;
+	if (keybyte > 'Z')
+	    keybyte += 'a' - 'Z' - 1;
+	retkey[i + 2] = keybyte;
+    }
+
+    retkey[i + 2] = 0;
+
+    if (!retkey[1])
+	retkey[1] = *retkey;
+
+    return retkey;
+}
diff -u -r -N squid-3.0.STABLE7/lib/getopt.c squid-3.0.STABLE8/lib/getopt.c
--- squid-3.0.STABLE7/lib/getopt.c	1970-01-01 12:00:00.000000000 +1200
+++ squid-3.0.STABLE8/lib/getopt.c	2008-07-18 22:02:51.000000000 +1200
@@ -0,0 +1,110 @@
+/*
+ * Copyright (c) 1987, 1993, 1994
+ *      The Regents of the University of California.  All rights reserved.
+ *
+ * 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. 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.
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+static char sccsid[] = "@(#)getopt.c	8.3 (Berkeley) 4/27/95";
+#endif /* LIBC_SCCS and not lint */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+int opterr = 1,			/* if error message should be printed */
+    optind = 1,			/* index into parent argv vector */
+    optopt,			/* character checked for validity */
+    optreset;			/* reset getopt */
+char *optarg;			/* argument associated with option */
+
+#define	BADCH	(int)'?'
+#define	BADARG	(int)':'
+#define	EMSG	""
+
+/*
+ * getopt --
+ *      Parse argc/argv argument vector.
+ */
+int
+getopt(nargc, nargv, ostr)
+     int nargc;
+     char *const *nargv;
+     const char *ostr;
+{
+    static char *place = EMSG;	/* option letter processing */
+    char *oli;			/* option letter list index */
+
+    if (optreset || !*place) {	/* update scanning pointer */
+	optreset = 0;
+	if (optind >= nargc || *(place = nargv[optind]) != '-') {
+	    place = EMSG;
+	    return (-1);
+	}
+	if (place[1] && *++place == '-') {	/* found "--" */
+	    ++optind;
+	    place = EMSG;
+	    return (-1);
+	}
+    }				/* option letter okay? */
+    if ((optopt = (int) *place++) == (int) ':' ||
+	!(oli = strchr(ostr, optopt))) {
+	/*
+	 * if the user didn't specify '-' as an option,
+	 * assume it means -1.
+	 */
+	if (optopt == (int) '-')
+	    return (-1);
+	if (!*place)
+	    ++optind;
+	if (opterr && *ostr != ':')
+	    (void) fprintf(stderr,
+		"%s: illegal option -- %c\n", __FILE__, optopt);
+	return (BADCH);
+    }
+    if (*++oli != ':') {	/* don't need argument */
+	optarg = NULL;
+	if (!*place)
+	    ++optind;
+    } else {			/* need an argument */
+	if (*place)		/* no white space */
+	    optarg = place;
+	else if (nargc <= ++optind) {	/* no arg */
+	    place = EMSG;
+	    if (*ostr == ':')
+		return (BADARG);
+	    if (opterr)
+		(void) fprintf(stderr,
+		    "%s: option requires an argument -- %c\n",
+		    __FILE__, optopt);
+	    return (BADCH);
+	} else			/* white space */
+	    optarg = nargv[optind];
+	place = EMSG;
+	++optind;
+    }
+    return (optopt);		/* dump back option letter */
+}
diff -u -r -N squid-3.0.STABLE7/lib/Makefile.am squid-3.0.STABLE8/lib/Makefile.am
--- squid-3.0.STABLE7/lib/Makefile.am	2008-06-22 15:35:50.000000000 +1200
+++ squid-3.0.STABLE8/lib/Makefile.am	2008-07-18 22:02:51.000000000 +1200
@@ -45,7 +45,13 @@
 	libntlmauth.a \
 	$(LIBSSPWIN32) \
 	@LIBREGEX@
+#
+# dirent.c, encrypt.c and getopt.c are needed for native Windows support.
+#
 EXTRA_libmiscutil_a_SOURCES = \
+	dirent.c \
+	encrypt.c \
+	getopt.c \
 	md5.c \
 	Profiler.c \
 	strsep.c \
diff -u -r -N squid-3.0.STABLE7/lib/Makefile.in squid-3.0.STABLE8/lib/Makefile.in
--- squid-3.0.STABLE7/lib/Makefile.in	2008-06-22 15:35:50.000000000 +1200
+++ squid-3.0.STABLE8/lib/Makefile.in	2008-07-18 22:02:51.000000000 +1200
@@ -372,7 +372,13 @@
 	$(LIBSSPWIN32) \
 	@LIBREGEX@
 
+#
+# dirent.c, encrypt.c and getopt.c are needed for native Windows support.
+#
 EXTRA_libmiscutil_a_SOURCES = \
+	dirent.c \
+	encrypt.c \
+	getopt.c \
 	md5.c \
 	Profiler.c \
 	strsep.c \
@@ -517,7 +523,10 @@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/Splay.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/assert.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/base64.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dirent.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/encrypt.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/getfullhostname.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/getopt.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/hash.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/heap.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/html_quote.Po@am__quote@
diff -u -r -N squid-3.0.STABLE7/lib/util.c squid-3.0.STABLE8/lib/util.c
--- squid-3.0.STABLE7/lib/util.c	2008-06-22 15:35:50.000000000 +1200
+++ squid-3.0.STABLE8/lib/util.c	2008-07-18 22:02:51.000000000 +1200
@@ -931,8 +931,8 @@
 void
 default_failure_notify(const char *message)
 {
-    write(2, message, strlen(message));
-    write(2, "\n", 1);
+    if(write(2, message, strlen(message))) {}
+    if(write(2, "\n", 1)) {}
     abort();
 }
 
diff -u -r -N squid-3.0.STABLE7/README squid-3.0.STABLE8/README
--- squid-3.0.STABLE7/README	2008-06-22 15:35:44.000000000 +1200
+++ squid-3.0.STABLE8/README	2008-07-18 22:02:45.000000000 +1200
@@ -22,7 +22,8 @@
 
 Please use our mailing lists for questions, feedback and bug fixes:
 
-        squid-users@squid-cache.org	# general questions, pubilc forum
+        squid-users@squid-cache.org	# general questions, public forum
         squid-bugs@squid-cache.org	# bugs and fixes
+        squid-dev@squid-cache.org	# developers forum
         squid@squid-cache.org		# other feedback
 
diff -u -r -N squid-3.0.STABLE7/RELEASENOTES.html squid-3.0.STABLE8/RELEASENOTES.html
--- squid-3.0.STABLE7/RELEASENOTES.html	2008-06-22 15:36:54.000000000 +1200
+++ squid-3.0.STABLE8/RELEASENOTES.html	2008-07-18 22:03:49.000000000 +1200
@@ -1,11 +1,11 @@
 <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
 <HTML>
 <HEAD>
- <META NAME="GENERATOR" CONTENT="LinuxDoc-Tools 0.9.50">
- <TITLE>Squid 3.0.STABLE7 release notes</TITLE>
+ <META NAME="GENERATOR" CONTENT="LinuxDoc-Tools 0.9.21">
+ <TITLE>Squid 3.0.STABLE8 release notes</TITLE>
 </HEAD>
 <BODY>
-<H1>Squid 3.0.STABLE7 release notes</H1>
+<H1>Squid 3.0.STABLE8 release notes</H1>
 
 <H2>Squid Developers</H2>$Id: release-3.0.sgml,v 1.30.2.5 2008/02/28 00:26:31 amosjeffries Exp $
 <HR>
@@ -15,7 +15,7 @@
 <HR>
 <H2><A NAME="s1">1. Notice</A></H2>
 
-<P>The Squid Team are pleased to announce the release of Squid-3.0.STABLE7.</P>
+<P>The Squid Team are pleased to announce the release of Squid-3.0.STABLE8.</P>
 <P>This new release is available for download from 
 <A HREF="http://www.squid-cache.org/Versions/v3/3.0/">http://www.squid-cache.org/Versions/v3/3.0/</A> or the 
 <A HREF="http://www.squid-cache.org/Mirrors/http-mirrors.html">mirrors</A>.</P>
@@ -505,10 +505,6 @@
 </P>
 <P>Removed options:
 <PRE>
-    userhash, not yet ported to Squid-3
-
-    sourcehash, not yet ported to Squid-2
-
     monitorurl, monitorsize etc, not yet ported to Squid-3
 
     connection-auth=, not yet ported to Squid-3
@@ -520,7 +516,7 @@
 <PRE>
     no-store, replaces the older read-only option
 
-    min-size, not yet portedto Squid-3
+    min-size, not yet ported to Squid-3
         
 </PRE>
 </P>
@@ -597,7 +593,9 @@
         
 </PRE>
 </P>
+
 <DT><B>acl</B><DD>
+<P>The 'all' ACL is now provided as a built-in. Warnings will be displayed if any attempt is made to redefine it.</P>
 <P>New types:
 <PRE>
     acl aclname http_status 200 301 500- 400-403 ...     # status code in reply
@@ -615,6 +613,7 @@
         
 </PRE>
 </P>
+
 <DT><B>short_icon_urls</B><DD>
 <P>New default:
 <PRE>
@@ -679,15 +678,6 @@
 </PRE>
 </P>
 
-<P>Removed format tags:
-<PRE>
-    &gt;st     Request size including HTTP headers, not yet ported to Squid-3.
-
-    st      Request+Reply size including HTTP headers, not yet ported to Squid-3.
-        
-</PRE>
-</P>
-
 <DT><B>reply_body_max_size</B><DD>
 <P>Syntax changed:
 <PRE>
diff -u -r -N squid-3.0.STABLE7/src/access_log.cc squid-3.0.STABLE8/src/access_log.cc
--- squid-3.0.STABLE7/src/access_log.cc	2008-06-22 15:35:52.000000000 +1200
+++ squid-3.0.STABLE8/src/access_log.cc	2008-07-18 22:02:53.000000000 +1200
@@ -368,7 +368,7 @@
     /*LFT_REQUEST_QUERY, * // * this is not needed. see strip_query_terms */
     LFT_REQUEST_VERSION,
 
-    /*LFT_REQUEST_SIZE_TOTAL, */
+    LFT_REQUEST_SIZE_TOTAL,
     /*LFT_REQUEST_SIZE_LINE, */
     /*LFT_REQUEST_SIZE_HEADERS, */
     /*LFT_REQUEST_SIZE_BODY, */
@@ -383,6 +383,7 @@
     /*LFT_REPLY_SIZE_BODY_NO_TE, */
 
     LFT_TAG,
+    LFT_IO_SIZE_TOTAL,
     LFT_EXT_LOG,
 
     LFT_PERCENT			/* special string cases for escaped chars */
@@ -488,7 +489,7 @@
         {">v", LFT_REQUEST_VERSION},
         {"rv", LFT_REQUEST_VERSION},
 
-        /*{ ">st", LFT_REQUEST_SIZE_TOTAL }, */
+        { ">st", LFT_REQUEST_SIZE_TOTAL },
         /*{ ">sl", LFT_REQUEST_SIZE_LINE }, * / / * the request line "GET ... " */
         /*{ ">sh", LFT_REQUEST_SIZE_HEADERS }, */
         /*{ ">sb", LFT_REQUEST_SIZE_BODY }, */
@@ -503,6 +504,7 @@
         /*{ "<sB", LFT_REPLY_SIZE_BODY_NO_TE }, */
 
         {"et", LFT_TAG},
+        {"st", LFT_IO_SIZE_TOTAL},
         {"ea", LFT_EXT_LOG},
 
         {"%", LFT_PERCENT},
@@ -777,22 +779,22 @@
 
         case LFT_REQUEST_VERSION:
             snprintf(tmp, sizeof(tmp), "%d.%d", (int) al->http.version.major, (int) al->http.version.minor);
-
             out = tmp;
+            break;
 
+        case LFT_REQUEST_SIZE_TOTAL:
+            outint = al->cache.requestSize;
+            dooff = 1;
             break;
 
-            /*case LFT_REQUEST_SIZE_TOTAL: */
             /*case LFT_REQUEST_SIZE_LINE: */
             /*case LFT_REQUEST_SIZE_HEADERS: */
             /*case LFT_REQUEST_SIZE_BODY: */
             /*case LFT_REQUEST_SIZE_BODY_NO_TE: */
 
         case LFT_REPLY_SIZE_TOTAL:
-            outoff = al->cache.size;
-
+            outoff = al->cache.replySize;
             dooff = 1;
-
             break;
 
         case LFT_REPLY_HIGHOFFSET:
@@ -822,6 +824,11 @@
 
             break;
 
+        case LFT_IO_SIZE_TOTAL:
+            outint = al->cache.requestSize + al->cache.replySize;
+            doint = 1;
+            break;
+
         case LFT_EXT_LOG:
             if (al->request)
                 out = al->request->extacl_log.buf();
@@ -1303,7 +1310,7 @@
                       client,
                       log_tags[al->cache.code],
                       al->http.code,
-                      al->cache.size,
+                      al->cache.replySize,
                       al->_private.method_str,
                       al->url,
                       user ? user : dash_str,
@@ -1321,7 +1328,7 @@
                       client,
                       log_tags[al->cache.code],
                       al->http.code,
-                      al->cache.size,
+                      al->cache.replySize,
                       al->_private.method_str,
                       al->url,
                       user ? user : dash_str,
@@ -1362,7 +1369,7 @@
                   al->url,
                   al->http.version.major, al->http.version.minor,
                   al->http.code,
-                  al->cache.size,
+                  al->cache.replySize,
                   log_tags[al->cache.code],
                   hier_strings[al->hier.code]);
 
diff -u -r -N squid-3.0.STABLE7/src/AccessLogEntry.h squid-3.0.STABLE8/src/AccessLogEntry.h
--- squid-3.0.STABLE7/src/AccessLogEntry.h	2008-06-22 15:35:51.000000000 +1200
+++ squid-3.0.STABLE8/src/AccessLogEntry.h	2008-07-18 22:02:52.000000000 +1200
@@ -79,7 +79,9 @@
     {
 
     public:
-        CacheDetails() : size(0),
+        CacheDetails() :
+                requestSize(0),
+                replySize(0),
                 highOffset(0),
                 objectSize(0),
                 code (LOG_TAG_NONE),
@@ -95,7 +97,8 @@
         }
 
         struct IN_ADDR caddr;
-        int64_t size;
+        int64_t requestSize;
+        int64_t replySize;
         int64_t highOffset;
         int64_t objectSize;
         log_type code;
diff -u -r -N squid-3.0.STABLE7/src/cache_cf.cc squid-3.0.STABLE8/src/cache_cf.cc
--- squid-3.0.STABLE7/src/cache_cf.cc	2008-06-22 15:35:52.000000000 +1200
+++ squid-3.0.STABLE8/src/cache_cf.cc	2008-07-18 22:02:53.000000000 +1200
@@ -1723,6 +1723,18 @@
             p->options.carp = 1;
 
 #endif
+        } else if (!strcasecmp(token, "userhash")) {
+            if (p->type != PEER_PARENT)
+                fatalf("parse_peer: non-parent userhash peer %s/%d\n", p->host, p->http_port);
+
+            p->options.userhash = 1;
+
+        } else if (!strcasecmp(token, "sourcehash")) {
+            if (p->type != PEER_PARENT)
+                fatalf("parse_peer: non-parent sourcehash peer %s/%d\n", p->host, p->http_port);
+
+            p->options.sourcehash = 1;
+
 #if DELAY_POOLS
 
         } else if (!strcasecmp(token, "no-delay")) {
@@ -1831,8 +1843,7 @@
     *head = p;
 
     Config.npeers++;
-
-    peerClearRR(p);
+    peerClearRRStart();
 }
 
 static void
diff -u -r -N squid-3.0.STABLE7/src/cf.data.pre squid-3.0.STABLE8/src/cf.data.pre
--- squid-3.0.STABLE7/src/cf.data.pre	2008-06-22 15:35:53.000000000 +1200
+++ squid-3.0.STABLE8/src/cf.data.pre	2008-07-18 22:02:53.000000000 +1200
@@ -455,12 +455,14 @@
 DOC_START
 	Defining an Access List
 
-	acl aclname acltype string1 ...
-	acl aclname acltype "file" ...
+	Every access list definition must begin with an aclname and acltype, 
+	followed by either type-specific arguments or a quoted filename that
+	they are read from.
 
-	when using "file", the file should contain one item per line
+	   acl aclname acltype argument ...
+	   acl aclname acltype "file" ...
 
-	acltype is one of the types described below
+	When using "file", the file should contain one item per line.
 
 	By default, regular expressions are CASE-SENSITIVE.  To make
 	them case-insensitive, use the -i option.
@@ -468,10 +470,10 @@
 
 	***** ACL TYPES AVAILABLE *****
 
-	acl aclname src      ip-address/netmask ... (clients IP address)
-	acl aclname src      addr1-addr2/netmask ... (range of addresses)
-	acl aclname dst      ip-address/netmask ... (URL host's IP address)
-	acl aclname myip     ip-address/netmask ... (local socket IP address)
+	acl aclname src ip-address/netmask ...		# clients IP address
+	acl aclname src addr1-addr2/netmask ...		# range of addresses
+	acl aclname dst ip-address/netmask ...		# URL host's IP address
+	acl aclname myip ip-address/netmask ...		# local socket IP address
 
 	acl aclname arp      mac-address ... (xx:xx:xx:xx:xx:xx notation)
 	  # The arp ACL requires the special configure option --enable-arp-acl.
@@ -482,16 +484,16 @@
 	  # the same subnet. If the client is on a different subnet, then Squid cannot
 	  # find out its MAC address.
 
-	acl aclname srcdomain   .foo.com ...    # reverse lookup, from client IP
-	acl aclname dstdomain   .foo.com ...    # Destination server from URL
-	acl aclname srcdom_regex [-i] xxx ...   # regex matching client name
-	acl aclname dstdom_regex [-i] xxx ...   # regex matching server
+	acl aclname srcdomain   .foo.com ...    	# reverse lookup, from client IP
+	acl aclname dstdomain   .foo.com ...    	# Destination server from URL
+	acl aclname srcdom_regex [-i] \.foo\.com ...	# regex matching client name
+	acl aclname dstdom_regex [-i] \.foo\.com ...	# regex matching server
 	  # For dstdomain and dstdom_regex a reverse lookup is tried if a IP
 	  # based URL is used and no match is found. The name "none" is used
 	  # if the reverse lookup fails.
 
-	acl aclname src_as   number ...
-	acl aclname dst_as   number ...
+	acl aclname src_as number ...
+	acl aclname dst_as number ...
 	  # Except for access control, AS numbers can be used for
 	  # routing of requests to specific caches. Here's an
 	  # example for routing all requests for AS#1241 and only
@@ -500,39 +502,39 @@
 	  # cache_peer_access mycache.mydomain.net allow asexample
 	  # cache_peer_access mycache_mydomain.net deny all
 
-	acl aclname time     [day-abbrevs]  [h1:m1-h2:m2]
-	    day-abbrevs:
-		S - Sunday
-		M - Monday
-		T - Tuesday
-		W - Wednesday
-		H - Thursday
-		F - Friday
-		A - Saturday
-	    h1:m1 must be less than h2:m2
+	acl aclname time [day-abbrevs] [h1:m1-h2:m2]
+	  #  day-abbrevs:
+	  #	S - Sunday
+	  #	M - Monday
+	  #	T - Tuesday
+	  #	W - Wednesday
+	  #	H - Thursday
+	  #	F - Friday
+	  #	A - Saturday
+	  #  h1:m1 must be less than h2:m2
 
-	acl aclname url_regex [-i] ^http:// ...	# regex matching on whole URL
+	acl aclname url_regex [-i] ^http:// ...		# regex matching on whole URL
 	acl aclname urlpath_regex [-i] \.gif$ ...	# regex matching on URL path
 
-	acl aclname port     80 70 21 ...
-	acl aclname port     0-1024 ...		# ranges allowed
-	acl aclname myport   3128 ...		# (local socket TCP port)
+	acl aclname port 80 70 21 ...
+	acl aclname port 0-1024 ...		# ranges allowed
+	acl aclname myport 3128 ...		# (local socket TCP port)
 	acl aclname myportname 3128 ...		# http(s)_port name
 
-	acl aclname proto    HTTP FTP ...
+	acl aclname proto HTTP FTP ...
 
-	acl aclname method   GET POST ...
+	acl aclname method GET POST ...
 
 	acl aclname http_status 200 301 500- 400-403 ...     # status code in reply
 
-	acl aclname browser  [-i] regexp ...
+	acl aclname browser [-i] regexp ...
 	  # pattern match on User-Agent header (see also req_header below)
 
-	acl aclname referer_regex  [-i] regexp ...
+	acl aclname referer_regex [-i] regexp ...
 	  # pattern match on Referer header
 	  # Referer is highly unreliable, so use with care
 
-	acl aclname ident    username ...
+	acl aclname ident username ...
 	acl aclname ident_regex [-i] pattern ...
 	  # string match on ident output.
 	  # use REQUIRED to accept any non-null ident.
@@ -577,7 +579,7 @@
 	  # clients may appear to come from multiple addresses if they are
 	  # going through proxy farms, so a limit of 1 may cause user problems.
 
-	acl aclname req_mime_type [-i] mime-type1 ...
+	acl aclname req_mime_type [-i] mime-type ...
 	  # regex match against the mime type of the request generated
 	  # by the client. Can be used to detect file upload or some
 	  # types HTTP tunneling requests.
@@ -589,7 +591,7 @@
 	  # thought of as a superset of "browser", "referer" and "mime-type"
 	  # ACLs.
 
-	acl aclname rep_mime_type [-i] mime-type1 ...
+	acl aclname rep_mime_type [-i] mime-type ...
 	  # regex match against the mime type of the reply received by
 	  # squid. Can be used to detect file download or some
 	  # types HTTP tunneling requests.
@@ -602,7 +604,7 @@
 	  # thought of as a superset of "browser", "referer" and "mime-type"
 	  # ACLs.
 
-	acl acl_name external class_name [arguments...]
+	acl aclname external class_name [arguments...]
 	  # external ACL lookup via a helper class defined by the
 	  # external_acl_type directive.
 
@@ -1309,6 +1311,8 @@
 		     round-robin
 		     weighted-round-robin
 		     carp
+		     userhash
+		     sourcehash
 		     multicast-responder
 		     closest-only
 		     no-digest
@@ -1383,6 +1387,12 @@
 		     distributed among the parents based on the CARP load
 		     balancing hash function based on their weight.
 
+		     use 'userhash' to load-balance amongst a set of parents
+		     based on the client proxy_auth or ident username.
+
+		     use 'sourcehash' to load-balance amongst a set of parents
+		     based on the client source ip.
+
 		     'multicast-responder' indicates the named peer
 		     is a member of a multicast group.  ICP queries will
 		     not be sent directly to the peer, but ICP replies
@@ -2006,6 +2016,8 @@
 		et	Tag returned by external acl
 		ea	Log string returned by external acl
 		<st	Reply size including HTTP headers
+		>st	Request size including HTTP headers
+		st	Request+Reply size including HTTP headers
 		<sH	Reply high offset sent
 		<sS	Upstream object size
 		%	a literal % character
@@ -4579,7 +4591,6 @@
 	requests, except those in your local domain use something like:
 
 		acl local-servers dstdomain .foo.net
-		acl all src 0.0.0.0/0.0.0.0
 		never_direct deny local-servers
 		never_direct allow all
 
@@ -5229,6 +5240,7 @@
 		offline_toggle *
 		pconn
 		peer_select
+		reconfigure *
 		redirector
 		refresh
 		server_list
@@ -5473,4 +5485,18 @@
 	rounded to 1000.
 DOC_END
 
+NAME: windows_ipaddrchangemonitor
+COMMENT: on|off
+TYPE: onoff
+DEFAULT: on
+LOC: Config.onoff.WIN32_IpAddrChangeMonitor
+DOC_START
+	On Windows Squid by default will monitor IP address changes and will 
+	reconfigure itself after any detected event. This is very useful for
+	proxies connected to internet with dial-up interfaces.
+	In some cases (a Proxy server acting as VPN gateway is one) it could be
+	desiderable to disable this behaviour setting this to 'off'.
+	Note: after changing this, Squid service must be restarted.
+DOC_END
+
 EOF
diff -u -r -N squid-3.0.STABLE7/src/client_side.cc squid-3.0.STABLE8/src/client_side.cc
--- squid-3.0.STABLE7/src/client_side.cc	2008-06-22 15:35:53.000000000 +1200
+++ squid-3.0.STABLE8/src/client_side.cc	2008-07-18 22:02:54.000000000 +1200
@@ -459,7 +459,7 @@
     aLogEntry->http.method = request->method;
     aLogEntry->http.version = request->http_ver;
     aLogEntry->hier = request->hier;
-
+    aLogEntry->cache.requestSize += request->content_length;
     aLogEntry->cache.extuser = request->extacl_user.buf();
 
     if (request->auth_user_request) {
@@ -495,7 +495,9 @@
 
         al.cache.caddr = getConn() != NULL ? getConn()->log_addr : no_addr;
 
-        al.cache.size = out.size;
+        al.cache.requestSize = req_sz;
+
+        al.cache.replySize = out.size;
 
         al.cache.highOffset = out.offset;
 
diff -u -r -N squid-3.0.STABLE7/src/comm.cc squid-3.0.STABLE8/src/comm.cc
--- squid-3.0.STABLE7/src/comm.cc	2008-06-22 15:35:53.000000000 +1200
+++ squid-3.0.STABLE8/src/comm.cc	2008-07-18 22:02:54.000000000 +1200
@@ -2220,7 +2220,7 @@
 void CommIO::Initialise() {
     /* Initialize done pipe signal */
     int DonePipe[2];
-    pipe(DonePipe);
+    if(pipe(DonePipe)) {}
     DoneFD = DonePipe[1];
     DoneReadFD = DonePipe[0];
     fd_open(DoneReadFD, FD_PIPE, "async-io completetion event: main");
diff -u -r -N squid-3.0.STABLE7/src/dns_internal.cc squid-3.0.STABLE8/src/dns_internal.cc
--- squid-3.0.STABLE7/src/dns_internal.cc	2008-06-22 15:35:53.000000000 +1200
+++ squid-3.0.STABLE8/src/dns_internal.cc	2008-07-18 22:02:54.000000000 +1200
@@ -388,7 +388,7 @@
 	    t = (char *) xmalloc(Size);
 	    RegQueryValueEx(hndKey, "Domain", NULL, &Type, (LPBYTE) t,
 		&Size);
-	    debugs(78, 1, "Adding domain " << token << " from Registry");
+	    debugs(78, 1, "Adding domain " << t << " from Registry");
 	    idnsAddPathComponent(t);
 	    xfree(t);
 	}
@@ -412,7 +412,7 @@
 
         RegCloseKey(hndKey);
     }
-    if (npc == 0 && ((const char *) t = getMyHostname())) {
+    if (npc == 0 && (t = (char *) getMyHostname())) {
 	t = strchr(t, '.');
 	if (t)
 	    idnsAddPathComponent(t + 1);
@@ -443,7 +443,7 @@
 
             if (Result == ERROR_SUCCESS && Size) {
                 t = (char *) xmalloc(Size);
-                RegQueryValueEx(hndKey, "DhcpNameServer", NULL, &Type, t,
+                RegQueryValueEx(hndKey, "DhcpNameServer", NULL, &Type, (LPBYTE) t,
                                 &Size);
                 token = strtok(t, ", ");
 
@@ -460,7 +460,7 @@
 
             if (Result == ERROR_SUCCESS && Size) {
                 t = (char *) xmalloc(Size);
-                RegQueryValueEx(hndKey, "NameServer", NULL, &Type, t, &Size);
+                RegQueryValueEx(hndKey, "NameServer", NULL, &Type, (LPBYTE) t, &Size);
                 token = strtok(t, ", ");
 
                 while (token) {
@@ -514,7 +514,7 @@
                         if (Result == ERROR_SUCCESS && Size) {
                             t = (char *) xmalloc(Size);
                             RegQueryValueEx(hndKey2, "DhcpNameServer", NULL,
-                                            &Type, t, &Size);
+                                            &Type, (LPBYTE) t, &Size);
                             token = strtok(t, ", ");
 
                             while (token) {
@@ -532,7 +532,7 @@
                         if (Result == ERROR_SUCCESS && Size) {
                             t = (char *) xmalloc(Size);
                             RegQueryValueEx(hndKey2, "NameServer", NULL, &Type,
-                                            t, &Size);
+                                            (LPBYTE) t, &Size);
                             token = strtok(t, ", ");
 
                             while (token) {
@@ -573,7 +573,7 @@
 
             if (Result == ERROR_SUCCESS && Size) {
                 t = (char *) xmalloc(Size);
-                RegQueryValueEx(hndKey, "NameServer", NULL, &Type, t, &Size);
+                RegQueryValueEx(hndKey, "NameServer", NULL, &Type, (LPBYTE) t, &Size);
                 token = strtok(t, ", ");
 
                 while (token) {
diff -u -r -N squid-3.0.STABLE7/src/dnsserver.cc squid-3.0.STABLE8/src/dnsserver.cc
--- squid-3.0.STABLE7/src/dnsserver.cc	2008-06-22 15:35:53.000000000 +1200
+++ squid-3.0.STABLE8/src/dnsserver.cc	2008-07-18 22:02:54.000000000 +1200
@@ -399,8 +399,12 @@
     for (;;) {
         memset(request, '\0', REQ_SZ);
 
-        if (fgets(request, REQ_SZ, stdin) == NULL)
-            exit(1);
+	if (fgets(request, REQ_SZ, stdin) == NULL) {
+#ifdef _SQUID_MSWIN_
+	    WSACleanup();
+#endif
+	    exit(1);
+	}
 
         t = strrchr(request, '\n');
 
diff -u -r -N squid-3.0.STABLE7/src/enums.h squid-3.0.STABLE8/src/enums.h
--- squid-3.0.STABLE7/src/enums.h	2008-06-22 15:35:53.000000000 +1200
+++ squid-3.0.STABLE8/src/enums.h	2008-07-18 22:02:54.000000000 +1200
@@ -176,6 +176,8 @@
     CARP,
 #endif
     ANY_OLD_PARENT,
+    USERHASH_PARENT,
+    SOURCEHASH_PARENT,
     HIER_MAX
 } hier_code;
 
diff -u -r -N squid-3.0.STABLE7/src/errorpage.cc squid-3.0.STABLE8/src/errorpage.cc
--- squid-3.0.STABLE7/src/errorpage.cc	2008-06-22 15:35:53.000000000 +1200
+++ squid-3.0.STABLE8/src/errorpage.cc	2008-07-18 22:02:54.000000000 +1200
@@ -81,12 +81,12 @@
 
                         {
                             ERR_SQUID_SIGNATURE,
-                            "\n<BR clear=\"all\">\n"
-                            "<HR noshade size=\"1px\">\n"
-                            "<ADDRESS>\n"
+                            "\n<br>\n"
+                            "<hr>\n"
+                            "<div id=\"footer\">\n"
                             "Generated %T by %h (%s)\n"
-                            "</ADDRESS>\n"
-                            "</BODY></HTML>\n"
+                            "</div>\n"
+                            "</body></html>\n"
                         },
                         {
                             TCP_RESET,
diff -u -r -N squid-3.0.STABLE7/src/ICAP/ICAPConfig.cc squid-3.0.STABLE8/src/ICAP/ICAPConfig.cc
--- squid-3.0.STABLE7/src/ICAP/ICAPConfig.cc	2008-06-22 15:35:52.000000000 +1200
+++ squid-3.0.STABLE8/src/ICAP/ICAPConfig.cc	2008-07-18 22:02:53.000000000 +1200
@@ -218,7 +218,7 @@
         debugs(93, 5, "ICAPAccessCheckCallbackWrapper matchedClass = " << ac->matchedClass.buf());
     }
 
-    if (!answer) {
+    if (answer!=ACCESS_ALLOWED) {
         ac->checkCandidates();
         return;
     }
diff -u -r -N squid-3.0.STABLE7/src/icp_v2.cc squid-3.0.STABLE8/src/icp_v2.cc
--- squid-3.0.STABLE7/src/icp_v2.cc	2008-06-22 15:35:53.000000000 +1200
+++ squid-3.0.STABLE8/src/icp_v2.cc	2008-07-18 22:02:54.000000000 +1200
@@ -179,7 +179,7 @@
 
     al.cache.caddr = caddr;
 
-    al.cache.size = len;
+    al.cache.replySize = len;
 
     al.cache.code = logcode;
 
diff -u -r -N squid-3.0.STABLE7/src/IPInterception.cc squid-3.0.STABLE8/src/IPInterception.cc
--- squid-3.0.STABLE7/src/IPInterception.cc	2008-06-22 15:35:52.000000000 +1200
+++ squid-3.0.STABLE8/src/IPInterception.cc	2008-07-18 22:02:53.000000000 +1200
@@ -85,6 +85,7 @@
 #endif
 
 #if LINUX_NETFILTER
+#include <linux/types.h>
 #include <linux/netfilter_ipv4.h>
 #endif
 
@@ -235,7 +236,7 @@
     static time_t last_reported = 0;
 
     if (pffd < 0)
-        pffd = open("/dev/pf", O_RDWR);
+        pffd = open("/dev/pf", O_RDONLY);
 
     if (pffd < 0)
     {
diff -u -r -N squid-3.0.STABLE7/src/main.cc squid-3.0.STABLE8/src/main.cc
--- squid-3.0.STABLE7/src/main.cc	2008-06-22 15:35:53.000000000 +1200
+++ squid-3.0.STABLE8/src/main.cc	2008-07-18 22:02:54.000000000 +1200
@@ -567,6 +567,8 @@
 
     carpInit();
 #endif
+    peerUserHashInit();
+    peerSourceHashInit();
 }
 
 void
@@ -912,6 +914,8 @@
         carpRegisterWithCacheManager(manager);
 #endif
 
+	peerUserHashRegisterWithCacheManager(manager);
+	peerSourceHashRegisterWithCacheManager(manager);
         cbdataRegisterWithCacheManager(manager);
         /* These use separate calls so that the comm loops can eventually
          * coexist.
diff -u -r -N squid-3.0.STABLE7/src/Makefile.am squid-3.0.STABLE8/src/Makefile.am
--- squid-3.0.STABLE7/src/Makefile.am	2008-06-22 15:35:52.000000000 +1200
+++ squid-3.0.STABLE8/src/Makefile.am	2008-07-18 22:02:53.000000000 +1200
@@ -543,6 +543,8 @@
 	PeerDigest.h \
 	peer_digest.cc \
 	peer_select.cc \
+	peer_sourcehash.cc \
+	peer_userhash.cc \
 	PeerSelectState.h \
 	PingData.h \
 	protos.h \
@@ -840,6 +842,8 @@
 	pconn.cc \
 	peer_digest.cc \
 	peer_select.cc \
+	peer_sourcehash.cc \
+	peer_userhash.cc \
 	protos.h \
 	redirect.cc \
 	referer.cc \
@@ -1361,6 +1365,8 @@
 	pconn.cc \
 	peer_digest.cc \
 	peer_select.cc \
+	peer_sourcehash.cc \
+	peer_userhash.cc \
 	redirect.cc \
 	referer.cc \
 	refresh.cc \
@@ -1527,6 +1533,8 @@
 	pconn.cc \
 	peer_digest.cc \
 	peer_select.cc \
+	peer_sourcehash.cc \
+	peer_userhash.cc \
 	redirect.cc \
 	referer.cc \
 	refresh.cc \
@@ -1679,6 +1687,8 @@
 	pconn.cc \
 	peer_digest.cc \
 	peer_select.cc \
+	peer_sourcehash.cc \
+	peer_userhash.cc \
 	redirect.cc \
 	referer.cc \
 	refresh.cc \
@@ -1857,6 +1867,8 @@
 	Parsing.cc \
 	peer_digest.cc \
 	peer_select.cc \
+	peer_sourcehash.cc \
+	peer_userhash.cc \
 	pconn.cc \
 	redirect.cc \
 	referer.cc \
@@ -2014,6 +2026,8 @@
 	pconn.cc \
 	peer_digest.cc \
 	peer_select.cc \
+	peer_sourcehash.cc \
+	peer_userhash.cc \
 	redirect.cc \
 	referer.cc \
 	refresh.cc \
@@ -2353,6 +2367,8 @@
 	pconn.cc \
 	peer_digest.cc \
 	peer_select.cc \
+	peer_sourcehash.cc \
+	peer_userhash.cc \
 	redirect.cc \
 	referer.cc \
 	refresh.cc \
diff -u -r -N squid-3.0.STABLE7/src/Makefile.in squid-3.0.STABLE8/src/Makefile.in
--- squid-3.0.STABLE7/src/Makefile.in	2008-06-22 15:35:52.000000000 +1200
+++ squid-3.0.STABLE8/src/Makefile.in	2008-07-18 22:02:53.000000000 +1200
@@ -247,22 +247,23 @@
 	mem_node.h Mem.h MemBuf.cc MemObject.cc MemObject.h mime.cc \
 	multicast.cc neighbors.cc net_db.cc Packer.cc Packer.h \
 	Parsing.cc Parsing.h ProfStats.cc pconn.cc pconn.h \
-	PeerDigest.h peer_digest.cc peer_select.cc PeerSelectState.h \
-	PingData.h protos.h redirect.cc referer.cc refresh.cc \
-	RemovalPolicy.cc RemovalPolicy.h send-announce.cc snmp_core.cc \
-	snmp_agent.cc squid.h SquidNew.cc ACLCertificateData.cc \
-	ACLCertificateData.h ACLCertificate.cc ACLCertificate.h \
-	ssl_support.cc ssl_support.h stat.cc StatHist.cc String.cc \
-	stmem.cc stmem.h store.cc Store.h StoreFileSystem.cc \
-	StoreFileSystem.h StoreHashIndex.h store_io.cc StoreIOBuffer.h \
-	StoreIOState.cc StoreIOState.h store_client.cc StoreClient.h \
-	store_digest.cc store_dir.cc store_key_md5.cc store_log.cc \
-	store_rebuild.cc store_swapin.cc store_swapmeta.cc \
-	store_swapout.cc StoreMeta.cc StoreMeta.h StoreMetaMD5.cc \
-	StoreMetaMD5.h StoreMetaSTD.cc StoreMetaSTD.h \
-	StoreMetaSTDLFS.cc StoreMetaSTDLFS.h StoreMetaObjSize.h \
-	StoreMetaUnpacker.cc StoreMetaUnpacker.h StoreMetaURL.cc \
-	StoreMetaURL.h StoreMetaVary.cc StoreMetaVary.h StoreSearch.h \
+	PeerDigest.h peer_digest.cc peer_select.cc peer_sourcehash.cc \
+	peer_userhash.cc PeerSelectState.h PingData.h protos.h \
+	redirect.cc referer.cc refresh.cc RemovalPolicy.cc \
+	RemovalPolicy.h send-announce.cc snmp_core.cc snmp_agent.cc \
+	squid.h SquidNew.cc ACLCertificateData.cc ACLCertificateData.h \
+	ACLCertificate.cc ACLCertificate.h ssl_support.cc \
+	ssl_support.h stat.cc StatHist.cc String.cc stmem.cc stmem.h \
+	store.cc Store.h StoreFileSystem.cc StoreFileSystem.h \
+	StoreHashIndex.h store_io.cc StoreIOBuffer.h StoreIOState.cc \
+	StoreIOState.h store_client.cc StoreClient.h store_digest.cc \
+	store_dir.cc store_key_md5.cc store_log.cc store_rebuild.cc \
+	store_swapin.cc store_swapmeta.cc store_swapout.cc \
+	StoreMeta.cc StoreMeta.h StoreMetaMD5.cc StoreMetaMD5.h \
+	StoreMetaSTD.cc StoreMetaSTD.h StoreMetaSTDLFS.cc \
+	StoreMetaSTDLFS.h StoreMetaObjSize.h StoreMetaUnpacker.cc \
+	StoreMetaUnpacker.h StoreMetaURL.cc StoreMetaURL.h \
+	StoreMetaVary.cc StoreMetaVary.h StoreSearch.h \
 	StoreSwapLogData.cc StoreSwapLogData.h Server.cc Server.h \
 	structs.h SwapDir.cc SwapDir.h time.cc tools.cc tunnel.cc \
 	typedefs.h unlinkd.cc url.cc URL.h URLScheme.cc URLScheme.h \
@@ -352,7 +353,8 @@
 	mime.$(OBJEXT) multicast.$(OBJEXT) neighbors.$(OBJEXT) \
 	net_db.$(OBJEXT) Packer.$(OBJEXT) Parsing.$(OBJEXT) \
 	$(am__objects_19) pconn.$(OBJEXT) peer_digest.$(OBJEXT) \
-	peer_select.$(OBJEXT) redirect.$(OBJEXT) referer.$(OBJEXT) \
+	peer_select.$(OBJEXT) peer_sourcehash.$(OBJEXT) \
+	peer_userhash.$(OBJEXT) redirect.$(OBJEXT) referer.$(OBJEXT) \
 	refresh.$(OBJEXT) RemovalPolicy.$(OBJEXT) \
 	send-announce.$(OBJEXT) $(am__objects_21) SquidNew.$(OBJEXT) \
 	$(am__objects_23) stat.$(OBJEXT) StatHist.$(OBJEXT) \
@@ -488,15 +490,16 @@
 	ipc.cc ipc_win32.cc ipcache.cc int.cc internal.cc list.cc \
 	logfile.cc multicast.cc mem_node.cc MemBuf.cc MemObject.cc \
 	mime.cc neighbors.cc net_db.cc Packer.cc Parsing.cc pconn.cc \
-	peer_digest.cc peer_select.cc redirect.cc referer.cc \
-	refresh.cc RemovalPolicy.cc Server.cc snmp_core.cc \
-	snmp_agent.cc ACLCertificateData.cc ACLCertificateData.h \
-	ACLCertificate.cc ACLCertificate.h ssl_support.cc \
-	ssl_support.h stat.cc StatHist.cc stmem.cc store.cc \
-	store_client.cc store_digest.cc store_dir.cc store_io.cc \
-	store_key_md5.cc store_log.cc store_rebuild.cc store_swapin.cc \
-	store_swapmeta.cc store_swapout.cc StoreFileSystem.cc \
-	StoreIOState.cc StoreMeta.cc StoreMetaMD5.cc StoreMetaSTD.cc \
+	peer_digest.cc peer_select.cc peer_sourcehash.cc \
+	peer_userhash.cc redirect.cc referer.cc refresh.cc \
+	RemovalPolicy.cc Server.cc snmp_core.cc snmp_agent.cc \
+	ACLCertificateData.cc ACLCertificateData.h ACLCertificate.cc \
+	ACLCertificate.h ssl_support.cc ssl_support.h stat.cc \
+	StatHist.cc stmem.cc store.cc store_client.cc store_digest.cc \
+	store_dir.cc store_io.cc store_key_md5.cc store_log.cc \
+	store_rebuild.cc store_swapin.cc store_swapmeta.cc \
+	store_swapout.cc StoreFileSystem.cc StoreIOState.cc \
+	StoreMeta.cc StoreMetaMD5.cc StoreMetaSTD.cc \
 	StoreMetaSTDLFS.cc StoreMetaUnpacker.cc StoreMetaURL.cc \
 	StoreMetaVary.cc StoreSwapLogData.cc tools.cc tunnel.cc \
 	SwapDir.cc url.cc URLScheme.cc urn.cc useragent.cc wccp2.cc \
@@ -533,7 +536,8 @@
 	MemBuf.$(OBJEXT) MemObject.$(OBJEXT) mime.$(OBJEXT) \
 	neighbors.$(OBJEXT) net_db.$(OBJEXT) Packer.$(OBJEXT) \
 	Parsing.$(OBJEXT) pconn.$(OBJEXT) peer_digest.$(OBJEXT) \
-	peer_select.$(OBJEXT) redirect.$(OBJEXT) referer.$(OBJEXT) \
+	peer_select.$(OBJEXT) peer_sourcehash.$(OBJEXT) \
+	peer_userhash.$(OBJEXT) redirect.$(OBJEXT) referer.$(OBJEXT) \
 	refresh.$(OBJEXT) RemovalPolicy.$(OBJEXT) Server.$(OBJEXT) \
 	$(am__objects_21) $(am__objects_23) stat.$(OBJEXT) \
 	StatHist.$(OBJEXT) stmem.$(OBJEXT) store.$(OBJEXT) \
@@ -710,19 +714,20 @@
 	ipc.cc ipc_win32.cc ipcache.cc int.cc internal.cc list.cc \
 	logfile.cc multicast.cc mem_node.cc MemBuf.cc MemObject.cc \
 	mime.cc neighbors.cc net_db.cc Packer.cc Parsing.cc pconn.cc \
-	peer_digest.cc peer_select.cc redirect.cc referer.cc \
-	refresh.cc Server.cc snmp_core.cc snmp_agent.cc \
-	ACLCertificateData.cc ACLCertificateData.h ACLCertificate.cc \
-	ACLCertificate.h ssl_support.cc ssl_support.h stat.cc \
-	StatHist.cc stmem.cc store.cc store_client.cc store_digest.cc \
-	store_dir.cc store_io.cc store_key_md5.cc store_log.cc \
-	store_rebuild.cc store_swapin.cc store_swapmeta.cc \
-	store_swapout.cc StoreFileSystem.cc StoreIOState.cc \
-	StoreMeta.cc StoreMetaMD5.cc StoreMetaSTD.cc \
-	StoreMetaSTDLFS.cc StoreMetaUnpacker.cc StoreMetaURL.cc \
-	StoreMetaVary.cc StoreSwapLogData.cc tools.cc tunnel.cc \
-	SwapDir.cc url.cc URLScheme.cc urn.cc useragent.cc wccp2.cc \
-	whois.cc win32.cc wordlist.cc
+	peer_digest.cc peer_select.cc peer_sourcehash.cc \
+	peer_userhash.cc redirect.cc referer.cc refresh.cc Server.cc \
+	snmp_core.cc snmp_agent.cc ACLCertificateData.cc \
+	ACLCertificateData.h ACLCertificate.cc ACLCertificate.h \
+	ssl_support.cc ssl_support.h stat.cc StatHist.cc stmem.cc \
+	store.cc store_client.cc store_digest.cc store_dir.cc \
+	store_io.cc store_key_md5.cc store_log.cc store_rebuild.cc \
+	store_swapin.cc store_swapmeta.cc store_swapout.cc \
+	StoreFileSystem.cc StoreIOState.cc StoreMeta.cc \
+	StoreMetaMD5.cc StoreMetaSTD.cc StoreMetaSTDLFS.cc \
+	StoreMetaUnpacker.cc StoreMetaURL.cc StoreMetaVary.cc \
+	StoreSwapLogData.cc tools.cc tunnel.cc SwapDir.cc url.cc \
+	URLScheme.cc urn.cc useragent.cc wccp2.cc whois.cc win32.cc \
+	wordlist.cc
 am_tests_testEvent_OBJECTS = debug.$(OBJEXT) EventLoop.$(OBJEXT) \
 	globals.$(OBJEXT) HttpRequest.$(OBJEXT) \
 	HttpRequestMethod.$(OBJEXT) mem.$(OBJEXT) \
@@ -756,7 +761,8 @@
 	MemBuf.$(OBJEXT) MemObject.$(OBJEXT) mime.$(OBJEXT) \
 	neighbors.$(OBJEXT) net_db.$(OBJEXT) Packer.$(OBJEXT) \
 	Parsing.$(OBJEXT) pconn.$(OBJEXT) peer_digest.$(OBJEXT) \
-	peer_select.$(OBJEXT) redirect.$(OBJEXT) referer.$(OBJEXT) \
+	peer_select.$(OBJEXT) peer_sourcehash.$(OBJEXT) \
+	peer_userhash.$(OBJEXT) redirect.$(OBJEXT) referer.$(OBJEXT) \
 	refresh.$(OBJEXT) Server.$(OBJEXT) $(am__objects_21) \
 	$(am__objects_23) stat.$(OBJEXT) StatHist.$(OBJEXT) \
 	stmem.$(OBJEXT) store.$(OBJEXT) store_client.$(OBJEXT) \
@@ -812,19 +818,20 @@
 	ipc.cc ipc_win32.cc ipcache.cc int.cc internal.cc list.cc \
 	logfile.cc multicast.cc mem_node.cc MemBuf.cc MemObject.cc \
 	mime.cc neighbors.cc net_db.cc Packer.cc Parsing.cc pconn.cc \
-	peer_digest.cc peer_select.cc redirect.cc referer.cc \
-	refresh.cc Server.cc snmp_core.cc snmp_agent.cc \
-	ACLCertificateData.cc ACLCertificateData.h ACLCertificate.cc \
-	ACLCertificate.h ssl_support.cc ssl_support.h stat.cc \
-	StatHist.cc stmem.cc store.cc store_client.cc store_digest.cc \
-	store_dir.cc store_io.cc store_key_md5.cc store_log.cc \
-	store_rebuild.cc store_swapin.cc store_swapmeta.cc \
-	store_swapout.cc StoreFileSystem.cc StoreIOState.cc \
-	StoreMeta.cc StoreMetaMD5.cc StoreMetaSTD.cc \
-	StoreMetaSTDLFS.cc StoreMetaUnpacker.cc StoreMetaURL.cc \
-	StoreMetaVary.cc StoreSwapLogData.cc tools.cc tunnel.cc \
-	SwapDir.cc url.cc URLScheme.cc urn.cc useragent.cc wccp2.cc \
-	whois.cc win32.cc wordlist.cc
+	peer_digest.cc peer_select.cc peer_sourcehash.cc \
+	peer_userhash.cc redirect.cc referer.cc refresh.cc Server.cc \
+	snmp_core.cc snmp_agent.cc ACLCertificateData.cc \
+	ACLCertificateData.h ACLCertificate.cc ACLCertificate.h \
+	ssl_support.cc ssl_support.h stat.cc StatHist.cc stmem.cc \
+	store.cc store_client.cc store_digest.cc store_dir.cc \
+	store_io.cc store_key_md5.cc store_log.cc store_rebuild.cc \
+	store_swapin.cc store_swapmeta.cc store_swapout.cc \
+	StoreFileSystem.cc StoreIOState.cc StoreMeta.cc \
+	StoreMetaMD5.cc StoreMetaSTD.cc StoreMetaSTDLFS.cc \
+	StoreMetaUnpacker.cc StoreMetaURL.cc StoreMetaVary.cc \
+	StoreSwapLogData.cc tools.cc tunnel.cc SwapDir.cc url.cc \
+	URLScheme.cc urn.cc useragent.cc wccp2.cc whois.cc win32.cc \
+	wordlist.cc
 am_tests_testEventLoop_OBJECTS = debug.$(OBJEXT) EventLoop.$(OBJEXT) \
 	globals.$(OBJEXT) HttpRequest.$(OBJEXT) \
 	HttpRequestMethod.$(OBJEXT) mem.$(OBJEXT) \
@@ -858,7 +865,8 @@
 	MemBuf.$(OBJEXT) MemObject.$(OBJEXT) mime.$(OBJEXT) \
 	neighbors.$(OBJEXT) net_db.$(OBJEXT) Packer.$(OBJEXT) \
 	Parsing.$(OBJEXT) pconn.$(OBJEXT) peer_digest.$(OBJEXT) \
-	peer_select.$(OBJEXT) redirect.$(OBJEXT) referer.$(OBJEXT) \
+	peer_select.$(OBJEXT) peer_sourcehash.$(OBJEXT) \
+	peer_userhash.$(OBJEXT) redirect.$(OBJEXT) referer.$(OBJEXT) \
 	refresh.$(OBJEXT) Server.$(OBJEXT) $(am__objects_21) \
 	$(am__objects_23) stat.$(OBJEXT) StatHist.$(OBJEXT) \
 	stmem.$(OBJEXT) store.$(OBJEXT) store_client.$(OBJEXT) \
@@ -940,15 +948,16 @@
 	ipc.cc ipc_win32.cc ipcache.cc int.cc internal.cc list.cc \
 	logfile.cc multicast.cc mem_node.cc MemBuf.cc MemObject.cc \
 	mime.cc neighbors.cc net_db.cc Packer.cc Parsing.cc pconn.cc \
-	peer_digest.cc peer_select.cc redirect.cc referer.cc \
-	refresh.cc RemovalPolicy.cc Server.cc snmp_core.cc \
-	snmp_agent.cc ACLCertificateData.cc ACLCertificateData.h \
-	ACLCertificate.cc ACLCertificate.h ssl_support.cc \
-	ssl_support.h stat.cc StatHist.cc stmem.cc store.cc \
-	store_client.cc store_digest.cc store_dir.cc store_io.cc \
-	store_key_md5.cc store_log.cc store_rebuild.cc store_swapin.cc \
-	store_swapmeta.cc store_swapout.cc StoreFileSystem.cc \
-	StoreIOState.cc StoreMeta.cc StoreMetaMD5.cc StoreMetaSTD.cc \
+	peer_digest.cc peer_select.cc peer_sourcehash.cc \
+	peer_userhash.cc redirect.cc referer.cc refresh.cc \
+	RemovalPolicy.cc Server.cc snmp_core.cc snmp_agent.cc \
+	ACLCertificateData.cc ACLCertificateData.h ACLCertificate.cc \
+	ACLCertificate.h ssl_support.cc ssl_support.h stat.cc \
+	StatHist.cc stmem.cc store.cc store_client.cc store_digest.cc \
+	store_dir.cc store_io.cc store_key_md5.cc store_log.cc \
+	store_rebuild.cc store_swapin.cc store_swapmeta.cc \
+	store_swapout.cc StoreFileSystem.cc StoreIOState.cc \
+	StoreMeta.cc StoreMetaMD5.cc StoreMetaSTD.cc \
 	StoreMetaSTDLFS.cc StoreMetaUnpacker.cc StoreMetaURL.cc \
 	StoreMetaVary.cc StoreSwapLogData.cc tools.cc tunnel.cc \
 	SwapDir.cc url.cc URLScheme.cc urn.cc useragent.cc wccp2.cc \
@@ -985,7 +994,8 @@
 	MemBuf.$(OBJEXT) MemObject.$(OBJEXT) mime.$(OBJEXT) \
 	neighbors.$(OBJEXT) net_db.$(OBJEXT) Packer.$(OBJEXT) \
 	Parsing.$(OBJEXT) pconn.$(OBJEXT) peer_digest.$(OBJEXT) \
-	peer_select.$(OBJEXT) redirect.$(OBJEXT) referer.$(OBJEXT) \
+	peer_select.$(OBJEXT) peer_sourcehash.$(OBJEXT) \
+	peer_userhash.$(OBJEXT) redirect.$(OBJEXT) referer.$(OBJEXT) \
 	refresh.$(OBJEXT) RemovalPolicy.$(OBJEXT) Server.$(OBJEXT) \
 	$(am__objects_21) $(am__objects_23) stat.$(OBJEXT) \
 	StatHist.$(OBJEXT) stmem.$(OBJEXT) store.$(OBJEXT) \
@@ -1123,19 +1133,19 @@
 	ipc.cc ipc_win32.cc ipcache.cc int.cc internal.cc list.cc \
 	logfile.cc multicast.cc mem_node.cc MemBuf.cc MemObject.cc \
 	mime.cc neighbors.cc net_db.cc Packer.cc Parsing.cc pconn.cc \
-	peer_digest.cc peer_select.cc redirect.cc referer.cc \
-	refresh.cc Server.cc snmp_core.cc snmp_agent.cc \
-	ACLCertificateData.cc ACLCertificateData.h ACLCertificate.cc \
-	ACLCertificate.h ssl_support.cc ssl_support.h stat.cc \
-	StatHist.cc stmem.cc store.cc store_client.cc store_digest.cc \
-	store_dir.cc store_io.cc store_key_md5.cc store_log.cc \
-	store_rebuild.cc store_swapin.cc store_swapmeta.cc \
-	store_swapout.cc StoreFileSystem.cc StoreIOState.cc \
-	StoreMeta.cc StoreMetaMD5.cc StoreMetaSTD.cc \
-	StoreMetaSTDLFS.cc StoreMetaUnpacker.cc StoreMetaURL.cc \
-	StoreMetaVary.cc StoreSwapLogData.cc tools.cc tunnel.cc \
-	SwapDir.cc urn.cc useragent.cc wccp2.cc whois.cc win32.cc \
-	wordlist.cc
+	peer_digest.cc peer_select.cc peer_sourcehash.cc \
+	peer_userhash.cc redirect.cc referer.cc refresh.cc Server.cc \
+	snmp_core.cc snmp_agent.cc ACLCertificateData.cc \
+	ACLCertificateData.h ACLCertificate.cc ACLCertificate.h \
+	ssl_support.cc ssl_support.h stat.cc StatHist.cc stmem.cc \
+	store.cc store_client.cc store_digest.cc store_dir.cc \
+	store_io.cc store_key_md5.cc store_log.cc store_rebuild.cc \
+	store_swapin.cc store_swapmeta.cc store_swapout.cc \
+	StoreFileSystem.cc StoreIOState.cc StoreMeta.cc \
+	StoreMetaMD5.cc StoreMetaSTD.cc StoreMetaSTDLFS.cc \
+	StoreMetaUnpacker.cc StoreMetaURL.cc StoreMetaVary.cc \
+	StoreSwapLogData.cc tools.cc tunnel.cc SwapDir.cc urn.cc \
+	useragent.cc wccp2.cc whois.cc win32.cc wordlist.cc
 am_tests_testURL_OBJECTS = debug.$(OBJEXT) url.$(OBJEXT) \
 	URLScheme.$(OBJEXT) globals.$(OBJEXT) HttpRequest.$(OBJEXT) \
 	HttpRequestMethod.$(OBJEXT) mem.$(OBJEXT) \
@@ -1169,7 +1179,8 @@
 	MemBuf.$(OBJEXT) MemObject.$(OBJEXT) mime.$(OBJEXT) \
 	neighbors.$(OBJEXT) net_db.$(OBJEXT) Packer.$(OBJEXT) \
 	Parsing.$(OBJEXT) pconn.$(OBJEXT) peer_digest.$(OBJEXT) \
-	peer_select.$(OBJEXT) redirect.$(OBJEXT) referer.$(OBJEXT) \
+	peer_select.$(OBJEXT) peer_sourcehash.$(OBJEXT) \
+	peer_userhash.$(OBJEXT) redirect.$(OBJEXT) referer.$(OBJEXT) \
 	refresh.$(OBJEXT) Server.$(OBJEXT) $(am__objects_21) \
 	$(am__objects_23) stat.$(OBJEXT) StatHist.$(OBJEXT) \
 	stmem.$(OBJEXT) store.$(OBJEXT) store_client.$(OBJEXT) \
@@ -1261,20 +1272,21 @@
 	icp_v3.cc ACLIdent.cc ACLIdent.h ident.cc int.cc internal.cc \
 	ipc.cc ipc_win32.cc ipcache.cc list.cc logfile.cc mem.cc \
 	mem_node.cc MemObject.cc mime.cc multicast.cc neighbors.cc \
-	net_db.cc Parsing.cc peer_digest.cc peer_select.cc pconn.cc \
-	redirect.cc referer.cc refresh.cc RemovalPolicy.cc Server.cc \
-	snmp_core.cc snmp_agent.cc ACLCertificateData.cc \
-	ACLCertificateData.h ACLCertificate.cc ACLCertificate.h \
-	ssl_support.cc ssl_support.h stat.cc StatHist.cc stmem.cc \
-	store.cc store_client.cc store_digest.cc store_dir.cc \
-	store_key_md5.cc store_io.cc store_log.cc store_rebuild.cc \
-	store_swapin.cc store_swapmeta.cc store_swapout.cc \
-	StoreFileSystem.cc StoreIOState.cc StoreMeta.cc \
-	StoreMetaMD5.cc StoreMetaSTD.cc StoreMetaSTDLFS.cc \
-	StoreMetaUnpacker.cc StoreMetaURL.cc StoreMetaVary.cc \
-	StoreSwapLogData.cc String.cc SwapDir.cc time.cc tools.cc \
-	tunnel.cc url.cc URLScheme.cc urn.cc useragent.cc wccp2.cc \
-	whois.cc win32.cc wordlist.cc Packer.cc MemBuf.cc
+	net_db.cc Parsing.cc peer_digest.cc peer_select.cc \
+	peer_sourcehash.cc peer_userhash.cc pconn.cc redirect.cc \
+	referer.cc refresh.cc RemovalPolicy.cc Server.cc snmp_core.cc \
+	snmp_agent.cc ACLCertificateData.cc ACLCertificateData.h \
+	ACLCertificate.cc ACLCertificate.h ssl_support.cc \
+	ssl_support.h stat.cc StatHist.cc stmem.cc store.cc \
+	store_client.cc store_digest.cc store_dir.cc store_key_md5.cc \
+	store_io.cc store_log.cc store_rebuild.cc store_swapin.cc \
+	store_swapmeta.cc store_swapout.cc StoreFileSystem.cc \
+	StoreIOState.cc StoreMeta.cc StoreMetaMD5.cc StoreMetaSTD.cc \
+	StoreMetaSTDLFS.cc StoreMetaUnpacker.cc StoreMetaURL.cc \
+	StoreMetaVary.cc StoreSwapLogData.cc String.cc SwapDir.cc \
+	time.cc tools.cc tunnel.cc url.cc URLScheme.cc urn.cc \
+	useragent.cc wccp2.cc whois.cc win32.cc wordlist.cc Packer.cc \
+	MemBuf.cc
 am_tests_test_http_range_OBJECTS = tests/test_http_range.$(OBJEXT) \
 	access_log.$(OBJEXT) acl.$(OBJEXT) acl_noncore.$(OBJEXT) \
 	ACLChecklist.$(OBJEXT) ACLProxyAuth.$(OBJEXT) \
@@ -1304,22 +1316,23 @@
 	logfile.$(OBJEXT) mem.$(OBJEXT) mem_node.$(OBJEXT) \
 	MemObject.$(OBJEXT) mime.$(OBJEXT) multicast.$(OBJEXT) \
 	neighbors.$(OBJEXT) net_db.$(OBJEXT) Parsing.$(OBJEXT) \
-	peer_digest.$(OBJEXT) peer_select.$(OBJEXT) pconn.$(OBJEXT) \
-	redirect.$(OBJEXT) referer.$(OBJEXT) refresh.$(OBJEXT) \
-	RemovalPolicy.$(OBJEXT) Server.$(OBJEXT) $(am__objects_21) \
-	$(am__objects_23) stat.$(OBJEXT) StatHist.$(OBJEXT) \
-	stmem.$(OBJEXT) store.$(OBJEXT) store_client.$(OBJEXT) \
-	store_digest.$(OBJEXT) store_dir.$(OBJEXT) \
-	store_key_md5.$(OBJEXT) store_io.$(OBJEXT) store_log.$(OBJEXT) \
-	store_rebuild.$(OBJEXT) store_swapin.$(OBJEXT) \
-	store_swapmeta.$(OBJEXT) store_swapout.$(OBJEXT) \
-	StoreFileSystem.$(OBJEXT) StoreIOState.$(OBJEXT) \
-	StoreMeta.$(OBJEXT) StoreMetaMD5.$(OBJEXT) \
-	StoreMetaSTD.$(OBJEXT) StoreMetaSTDLFS.$(OBJEXT) \
-	StoreMetaUnpacker.$(OBJEXT) StoreMetaURL.$(OBJEXT) \
-	StoreMetaVary.$(OBJEXT) StoreSwapLogData.$(OBJEXT) \
-	String.$(OBJEXT) SwapDir.$(OBJEXT) time.$(OBJEXT) \
-	tools.$(OBJEXT) tunnel.$(OBJEXT) url.$(OBJEXT) \
+	peer_digest.$(OBJEXT) peer_select.$(OBJEXT) \
+	peer_sourcehash.$(OBJEXT) peer_userhash.$(OBJEXT) \
+	pconn.$(OBJEXT) redirect.$(OBJEXT) referer.$(OBJEXT) \
+	refresh.$(OBJEXT) RemovalPolicy.$(OBJEXT) Server.$(OBJEXT) \
+	$(am__objects_21) $(am__objects_23) stat.$(OBJEXT) \
+	StatHist.$(OBJEXT) stmem.$(OBJEXT) store.$(OBJEXT) \
+	store_client.$(OBJEXT) store_digest.$(OBJEXT) \
+	store_dir.$(OBJEXT) store_key_md5.$(OBJEXT) store_io.$(OBJEXT) \
+	store_log.$(OBJEXT) store_rebuild.$(OBJEXT) \
+	store_swapin.$(OBJEXT) store_swapmeta.$(OBJEXT) \
+	store_swapout.$(OBJEXT) StoreFileSystem.$(OBJEXT) \
+	StoreIOState.$(OBJEXT) StoreMeta.$(OBJEXT) \
+	StoreMetaMD5.$(OBJEXT) StoreMetaSTD.$(OBJEXT) \
+	StoreMetaSTDLFS.$(OBJEXT) StoreMetaUnpacker.$(OBJEXT) \
+	StoreMetaURL.$(OBJEXT) StoreMetaVary.$(OBJEXT) \
+	StoreSwapLogData.$(OBJEXT) String.$(OBJEXT) SwapDir.$(OBJEXT) \
+	time.$(OBJEXT) tools.$(OBJEXT) tunnel.$(OBJEXT) url.$(OBJEXT) \
 	URLScheme.$(OBJEXT) urn.$(OBJEXT) useragent.$(OBJEXT) \
 	wccp2.$(OBJEXT) whois.$(OBJEXT) $(am__objects_25) \
 	wordlist.$(OBJEXT) Packer.$(OBJEXT) MemBuf.$(OBJEXT)
@@ -1368,12 +1381,13 @@
 	list.cc logfile.cc mem_node.cc mem_node.h Mem.h MemBuf.cc \
 	MemObject.cc MemObject.h mime.cc multicast.cc neighbors.cc \
 	net_db.cc Packer.cc Parsing.cc ProfStats.cc pconn.cc \
-	peer_digest.cc peer_select.cc protos.h redirect.cc referer.cc \
-	refresh.cc RemovalPolicy.cc send-announce.cc snmp_core.cc \
-	snmp_agent.cc squid.h ACLCertificateData.cc \
-	ACLCertificateData.h ACLCertificate.cc ACLCertificate.h \
-	ssl_support.cc ssl_support.h tunnel.cc Server.cc SquidNew.cc \
-	stat.cc StatHist.cc stmem.cc store_io.cc StoreIOBuffer.h \
+	peer_digest.cc peer_select.cc peer_sourcehash.cc \
+	peer_userhash.cc protos.h redirect.cc referer.cc refresh.cc \
+	RemovalPolicy.cc send-announce.cc snmp_core.cc snmp_agent.cc \
+	squid.h ACLCertificateData.cc ACLCertificateData.h \
+	ACLCertificate.cc ACLCertificate.h ssl_support.cc \
+	ssl_support.h tunnel.cc Server.cc SquidNew.cc stat.cc \
+	StatHist.cc stmem.cc store_io.cc StoreIOBuffer.h \
 	StoreIOState.cc store_client.cc StoreClient.h store_digest.cc \
 	store_dir.cc store_log.cc store_rebuild.cc store_swapin.cc \
 	store_swapmeta.cc store_swapout.cc structs.h SwapDir.cc \
@@ -1416,14 +1430,15 @@
 	MemObject.$(OBJEXT) mime.$(OBJEXT) multicast.$(OBJEXT) \
 	neighbors.$(OBJEXT) net_db.$(OBJEXT) Packer.$(OBJEXT) \
 	Parsing.$(OBJEXT) $(am__objects_19) pconn.$(OBJEXT) \
-	peer_digest.$(OBJEXT) peer_select.$(OBJEXT) redirect.$(OBJEXT) \
-	referer.$(OBJEXT) refresh.$(OBJEXT) RemovalPolicy.$(OBJEXT) \
-	send-announce.$(OBJEXT) $(am__objects_21) $(am__objects_23) \
-	tunnel.$(OBJEXT) Server.$(OBJEXT) SquidNew.$(OBJEXT) \
-	stat.$(OBJEXT) StatHist.$(OBJEXT) stmem.$(OBJEXT) \
-	store_io.$(OBJEXT) StoreIOState.$(OBJEXT) \
-	store_client.$(OBJEXT) store_digest.$(OBJEXT) \
-	store_dir.$(OBJEXT) store_log.$(OBJEXT) \
+	peer_digest.$(OBJEXT) peer_select.$(OBJEXT) \
+	peer_sourcehash.$(OBJEXT) peer_userhash.$(OBJEXT) \
+	redirect.$(OBJEXT) referer.$(OBJEXT) refresh.$(OBJEXT) \
+	RemovalPolicy.$(OBJEXT) send-announce.$(OBJEXT) \
+	$(am__objects_21) $(am__objects_23) tunnel.$(OBJEXT) \
+	Server.$(OBJEXT) SquidNew.$(OBJEXT) stat.$(OBJEXT) \
+	StatHist.$(OBJEXT) stmem.$(OBJEXT) store_io.$(OBJEXT) \
+	StoreIOState.$(OBJEXT) store_client.$(OBJEXT) \
+	store_digest.$(OBJEXT) store_dir.$(OBJEXT) store_log.$(OBJEXT) \
 	store_rebuild.$(OBJEXT) store_swapin.$(OBJEXT) \
 	store_swapmeta.$(OBJEXT) store_swapout.$(OBJEXT) \
 	SwapDir.$(OBJEXT) tools.$(OBJEXT) $(am__objects_24) \
@@ -2183,6 +2198,8 @@
 	PeerDigest.h \
 	peer_digest.cc \
 	peer_select.cc \
+	peer_sourcehash.cc \
+	peer_userhash.cc \
 	PeerSelectState.h \
 	PingData.h \
 	protos.h \
@@ -2465,6 +2482,8 @@
 	pconn.cc \
 	peer_digest.cc \
 	peer_select.cc \
+	peer_sourcehash.cc \
+	peer_userhash.cc \
 	protos.h \
 	redirect.cc \
 	referer.cc \
@@ -2848,6 +2867,8 @@
 	pconn.cc \
 	peer_digest.cc \
 	peer_select.cc \
+	peer_sourcehash.cc \
+	peer_userhash.cc \
 	redirect.cc \
 	referer.cc \
 	refresh.cc \
@@ -3018,6 +3039,8 @@
 	pconn.cc \
 	peer_digest.cc \
 	peer_select.cc \
+	peer_sourcehash.cc \
+	peer_userhash.cc \
 	redirect.cc \
 	referer.cc \
 	refresh.cc \
@@ -3172,6 +3195,8 @@
 	pconn.cc \
 	peer_digest.cc \
 	peer_select.cc \
+	peer_sourcehash.cc \
+	peer_userhash.cc \
 	redirect.cc \
 	referer.cc \
 	refresh.cc \
@@ -3349,6 +3374,8 @@
 	Parsing.cc \
 	peer_digest.cc \
 	peer_select.cc \
+	peer_sourcehash.cc \
+	peer_userhash.cc \
 	pconn.cc \
 	redirect.cc \
 	referer.cc \
@@ -3507,6 +3534,8 @@
 	pconn.cc \
 	peer_digest.cc \
 	peer_select.cc \
+	peer_sourcehash.cc \
+	peer_userhash.cc \
 	redirect.cc \
 	referer.cc \
 	refresh.cc \
@@ -3855,6 +3884,8 @@
 	pconn.cc \
 	peer_digest.cc \
 	peer_select.cc \
+	peer_sourcehash.cc \
+	peer_userhash.cc \
 	redirect.cc \
 	referer.cc \
 	refresh.cc \
@@ -4784,6 +4815,8 @@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pconn.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/peer_digest.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/peer_select.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/peer_sourcehash.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/peer_userhash.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pinger.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/recv-announce.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/redirect.Po@am__quote@
diff -u -r -N squid-3.0.STABLE7/src/neighbors.cc squid-3.0.STABLE8/src/neighbors.cc
--- squid-3.0.STABLE7/src/neighbors.cc	2008-06-22 15:35:53.000000000 +1200
+++ squid-3.0.STABLE8/src/neighbors.cc	2008-07-18 22:02:54.000000000 +1200
@@ -387,19 +387,67 @@
     return q;
 }
 
-/* This gets called every 5 minutes to clear the round-robin counter. */
+/**
+ * This gets called every 5 minutes to clear the round-robin counter.
+ * The exact timing is an arbitrary default, set on estimate timing of a
+ * large number of requests in a high-performance environment during the
+ * period. The larger the number of requests between cycled resets the
+ * more balanced the operations.
+ *
+ \param data	unused.
+ \todo Make the reset timing a selectable parameter in squid.conf
+ */
+static void 
+peerClearRRLoop(void *data)
+{
+    peerClearRR();
+    eventAdd("peerClearRR", peerClearRRLoop, data, 5 * 60.0, 0);
+}
+
+/**
+ * This gets called on startup and restart to kick off the peer round-robin
+ * maintenance event. It ensures that no matter how many times its called
+ * no more than one event is scheduled.
+ */
 void
-peerClearRR(void *data)
+peerClearRRStart(void)
 {
-    peer *p = (peer *)data;
-    p->rr_count -= p->rr_lastcount;
+    static int event_added = 0;
+    if (!event_added) {
+        peerClearRRLoop(NULL);
+    }
+}
 
-    if (p->rr_count < 0)
+/**
+ * Called whenever the round-robin counters need to be reset to a sane state.
+ * So far those times are:
+ \item On startup and reconfigure - to set the counters to sane initial settings.
+ \item When a peer has revived from dead, to prevent the revived peer being
+ *     flooded with requests which it has 'missed' during the down period.
+ */
+void
+peerClearRR()
+{
+    peer *p = NULL;
+    for (p = Config.peers; p; p = p->next) {
         p->rr_count = 0;
+    }
+}
 
-    p->rr_lastcount = p->rr_count;
+/**
+ * Perform all actions when a peer is detected revived.
+ */
+void
+peerAlive(peer *p)
+{
+    if (p->stats.logged_state == PEER_DEAD && p->tcp_up) {
+        debugs(15, 1, "Detected REVIVED " << neighborTypeStr(p) << ": " << p->name);
+        p->stats.logged_state = PEER_ALIVE;
+        peerClearRR();
+    }
 
-    eventAdd("peerClearRR", peerClearRR, p, 5 * 60.0, 0);
+    p->stats.last_reply = squid_curtime;
+    p->stats.probe_start = 0;
 }
 
 peer *
@@ -899,13 +947,7 @@
 static void
 neighborAlive(peer * p, const MemObject * mem, const icp_common_t * header)
 {
-    if (p->stats.logged_state == PEER_DEAD && p->tcp_up) {
-        debugs(15, 1, "Detected REVIVED " << neighborTypeStr(p) << ": " << p->name);
-        p->stats.logged_state = PEER_ALIVE;
-    }
-
-    p->stats.last_reply = squid_curtime;
-    p->stats.probe_start = 0;
+    peerAlive(p);
     p->stats.pings_acked++;
 
     if ((icp_opcode) header->opcode <= ICP_END)
@@ -943,14 +985,7 @@
 static void
 neighborAliveHtcp(peer * p, const MemObject * mem, const htcpReplyData * htcp)
 {
-    if (p->stats.logged_state == PEER_DEAD && p->tcp_up) {
-        debugs(15, 1, "Detected REVIVED " << neighborTypeStr(p) << ": " << p->name);
-        p->stats.logged_state = PEER_ALIVE;
-    }
-
-    p->stats.last_reply = squid_curtime;
-    p->stats.probe_start = 0;
-    p->stats.pings_acked++;
+    peerAlive(p);
     p->htcp.counts[htcp->hit ? 1 : 0]++;
     p->htcp.version = htcp->version;
 }
@@ -1361,13 +1396,13 @@
 {
     if (!p->tcp_up) {
         debugs(15, 2, "TCP connection to " << p->host << "/" << p->http_port << " succeded");
-        debugs(15, 1, "Detected REVIVED " << neighborTypeStr(p) << ": " << p->name);
-        p->stats.logged_state = PEER_ALIVE;
+        p->tcp_up = PEER_TCP_MAGIC_COUNT; // NP: so peerAlive(p) works properly.
+        peerAlive(p);
 	if (!p->n_addresses)
 	    ipcache_nbgethostbyname(p->host, peerDNSConfigure, p);
     }
-
-    p->tcp_up = PEER_TCP_MAGIC_COUNT;
+    else
+        p->tcp_up = PEER_TCP_MAGIC_COUNT;
 }
 
 static void
@@ -1574,6 +1609,15 @@
     if (p->options.roundrobin)
         storeAppendPrintf(sentry, " round-robin");
 
+    if (p->options.carp)
+        storeAppendPrintf(sentry, " carp");
+
+    if (p->options.userhash)
+        storeAppendPrintf(sentry, " userhash");
+
+    if (p->options.userhash)
+        storeAppendPrintf(sentry, " sourcehash");
+
     if (p->options.weighted_roundrobin)
         storeAppendPrintf(sentry, " weighted-round-robin");
 
diff -u -r -N squid-3.0.STABLE7/src/peer_select.cc squid-3.0.STABLE8/src/peer_select.cc
--- squid-3.0.STABLE7/src/peer_select.cc	2008-06-22 15:35:53.000000000 +1200
+++ squid-3.0.STABLE8/src/peer_select.cc	2008-07-18 22:02:54.000000000 +1200
@@ -67,6 +67,8 @@
         "CARP",
 #endif
         "ANY_PARENT",
+	"USERHASH",
+	"SOURCEHASH",
         "INVALID CODE"
     };
 
@@ -513,8 +515,11 @@
 
     if ((p = getDefaultParent(request))) {
         code = DEFAULT_PARENT;
+    } else if ((p = peerUserHashSelectParent(request))) {
+        code = USERHASH_PARENT;
+    } else if ((p = peerSourceHashSelectParent(request))) {
+        code = SOURCEHASH_PARENT;
 #if USE_CARP
-
     } else if ((p = carpSelectParent(request))) {
         code = CARP;
 #endif
diff -u -r -N squid-3.0.STABLE7/src/peer_sourcehash.cc squid-3.0.STABLE8/src/peer_sourcehash.cc
--- squid-3.0.STABLE7/src/peer_sourcehash.cc	1970-01-01 12:00:00.000000000 +1200
+++ squid-3.0.STABLE8/src/peer_sourcehash.cc	2008-07-18 22:02:54.000000000 +1200
@@ -0,0 +1,228 @@
+
+/*
+ * $Id: carp.cc,v 1.27 2008/01/14 12:13:49 hno Exp $
+ *
+ * DEBUG: section 39    Peer source hash based selection
+ * AUTHOR: Henrik Nordstrom
+ * BASED ON: carp.cc
+ *
+ * SQUID Web Proxy Cache          http://www.squid-cache.org/
+ * ----------------------------------------------------------
+ *
+ *  Squid is the result of efforts by numerous individuals from
+ *  the Internet community; see the CONTRIBUTORS file for full
+ *  details.   Many organizations have provided support for Squid's
+ *  development; see the SPONSORS file for full details.  Squid is
+ *  Copyrighted (C) 2001 by the Regents of the University of
+ *  California; see the COPYRIGHT file for full details.  Squid
+ *  incorporates software developed and/or copyrighted by other
+ *  sources; see the CREDITS file for full details.
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *  
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *  
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111, USA.
+ *
+ */
+
+#include "squid.h"
+#include "CacheManager.h"
+#include "Store.h"
+#include "HttpRequest.h"
+
+#define ROTATE_LEFT(x, n) (((x) << (n)) | ((x) >> (32-(n))))
+
+static int n_sourcehash_peers = 0;
+static peer **sourcehash_peers = NULL;
+static OBJH peerSourceHashCachemgr;
+
+static int
+peerSortWeight(const void *a, const void *b)
+{
+    const peer *const *p1 = (const peer *const *)a;
+    const peer *const *p2 = (const peer *const *)b;
+    return (*p1)->weight - (*p2)->weight;
+}
+
+void
+peerSourceHashInit(void)
+{
+    int W = 0;
+    int K;
+    int k;
+    double P_last, X_last, Xn;
+    peer *p;
+    peer **P;
+    char *t;
+    /* Clean up */
+
+    for (k = 0; k < n_sourcehash_peers; k++) {
+        cbdataReferenceDone(sourcehash_peers[k]);
+    }
+
+    safe_free(sourcehash_peers);
+    n_sourcehash_peers = 0;
+    /* find out which peers we have */
+
+    for (p = Config.peers; p; p = p->next) {
+        if (!p->options.sourcehash)
+            continue;
+
+        assert(p->type == PEER_PARENT);
+
+        if (p->weight == 0)
+            continue;
+
+        n_sourcehash_peers++;
+
+        W += p->weight;
+    }
+
+    if (n_sourcehash_peers == 0)
+        return;
+
+    sourcehash_peers = (peer **)xcalloc(n_sourcehash_peers, sizeof(*sourcehash_peers));
+
+    /* Build a list of the found peers and calculate hashes and load factors */
+    for (P = sourcehash_peers, p = Config.peers; p; p = p->next) {
+        if (!p->options.sourcehash)
+            continue;
+
+        if (p->weight == 0)
+            continue;
+
+        /* calculate this peers hash */
+        p->sourcehash.hash = 0;
+
+        for (t = p->name; *t != 0; t++)
+            p->sourcehash.hash += ROTATE_LEFT(p->sourcehash.hash, 19) + (unsigned int) *t;
+
+        p->sourcehash.hash += p->sourcehash.hash * 0x62531965;
+
+        p->sourcehash.hash = ROTATE_LEFT(p->sourcehash.hash, 21);
+
+        /* and load factor */
+        p->sourcehash.load_factor = ((double) p->weight) / (double) W;
+
+        if (floor(p->sourcehash.load_factor * 1000.0) == 0.0)
+            p->sourcehash.load_factor = 0.0;
+
+        /* add it to our list of peers */
+        *P++ = cbdataReference(p);
+    }
+
+    /* Sort our list on weight */
+    qsort(sourcehash_peers, n_sourcehash_peers, sizeof(*sourcehash_peers), peerSortWeight);
+
+    /* Calculate the load factor multipliers X_k
+     *
+     * X_1 = pow ((K*p_1), (1/K))
+     * X_k = ([K-k+1] * [P_k - P_{k-1}])/(X_1 * X_2 * ... * X_{k-1})
+     * X_k += pow ((X_{k-1}, {K-k+1})
+     * X_k = pow (X_k, {1/(K-k+1)})
+     * simplified to have X_1 part of the loop
+     */
+    K = n_sourcehash_peers;
+
+    P_last = 0.0;		/* Empty P_0 */
+
+    Xn = 1.0;			/* Empty starting point of X_1 * X_2 * ... * X_{x-1} */
+
+    X_last = 0.0;		/* Empty X_0, nullifies the first pow statement */
+
+    for (k = 1; k <= K; k++) {
+        double Kk1 = (double) (K - k + 1);
+        p = sourcehash_peers[k - 1];
+        p->sourcehash.load_multiplier = (Kk1 * (p->sourcehash.load_factor - P_last)) / Xn;
+        p->sourcehash.load_multiplier += pow(X_last, Kk1);
+        p->sourcehash.load_multiplier = pow(p->sourcehash.load_multiplier, 1.0 / Kk1);
+        Xn *= p->sourcehash.load_multiplier;
+        X_last = p->sourcehash.load_multiplier;
+        P_last = p->sourcehash.load_factor;
+    }
+}
+
+void
+peerSourceHashRegisterWithCacheManager(CacheManager & manager)
+{
+    manager.registerAction("sourcehash", "peer sourcehash information", peerSourceHashCachemgr, 0, 1);
+}
+
+peer *
+peerSourceHashSelectParent(HttpRequest * request)
+{
+    int k;
+    const char *c;
+    peer *p = NULL;
+    peer *tp;
+    unsigned int user_hash = 0;
+    unsigned int combined_hash;
+    double score;
+    double high_score = 0;
+    const char *key = NULL;
+
+    if (n_sourcehash_peers == 0)
+        return NULL;
+
+    key = inet_ntoa(request->client_addr);
+
+    /* calculate hash key */
+    debugs(39, 2, "peerSourceHashSelectParent: Calculating hash for " << key);
+
+    for (c = key; *c != 0; c++)
+        user_hash += ROTATE_LEFT(user_hash, 19) + *c;
+
+    /* select peer */
+    for (k = 0; k < n_sourcehash_peers; k++) {
+        tp = sourcehash_peers[k];
+        combined_hash = (user_hash ^ tp->sourcehash.hash);
+        combined_hash += combined_hash * 0x62531965;
+        combined_hash = ROTATE_LEFT(combined_hash, 21);
+        score = combined_hash * tp->sourcehash.load_multiplier;
+        debugs(39, 3, "peerSourceHashSelectParent: " << tp->name << " combined_hash " << combined_hash  << 
+               " score " << std::setprecision(0) << score);
+
+        if ((score > high_score) && peerHTTPOkay(tp, request)) {
+            p = tp;
+            high_score = score;
+        }
+    }
+
+    if (p)
+        debugs(39, 2, "peerSourceHashSelectParent: selected " << p->name);
+
+    return p;
+}
+
+static void
+peerSourceHashCachemgr(StoreEntry * sentry)
+{
+    peer *p;
+    int sumfetches = 0;
+    storeAppendPrintf(sentry, "%24s %10s %10s %10s %10s\n",
+                      "Hostname",
+                      "Hash",
+                      "Multiplier",
+                      "Factor",
+                      "Actual");
+
+    for (p = Config.peers; p; p = p->next)
+        sumfetches += p->stats.fetches;
+
+    for (p = Config.peers; p; p = p->next) {
+        storeAppendPrintf(sentry, "%24s %10x %10f %10f %10f\n",
+                          p->name, p->sourcehash.hash,
+                          p->sourcehash.load_multiplier,
+                          p->sourcehash.load_factor,
+                          sumfetches ? (double) p->stats.fetches / sumfetches : -1.0);
+    }
+}
diff -u -r -N squid-3.0.STABLE7/src/peer_userhash.cc squid-3.0.STABLE8/src/peer_userhash.cc
--- squid-3.0.STABLE7/src/peer_userhash.cc	1970-01-01 12:00:00.000000000 +1200
+++ squid-3.0.STABLE8/src/peer_userhash.cc	2008-07-18 22:02:54.000000000 +1200
@@ -0,0 +1,233 @@
+
+/*
+ * $Id: carp.cc,v 1.27 2008/01/14 12:13:49 hno Exp $
+ *
+ * DEBUG: section 39    Peer user hash based selection
+ * AUTHOR: Henrik Nordstrom
+ * BASED ON: carp.cc
+ *
+ * SQUID Web Proxy Cache          http://www.squid-cache.org/
+ * ----------------------------------------------------------
+ *
+ *  Squid is the result of efforts by numerous individuals from
+ *  the Internet community; see the CONTRIBUTORS file for full
+ *  details.   Many organizations have provided support for Squid's
+ *  development; see the SPONSORS file for full details.  Squid is
+ *  Copyrighted (C) 2001 by the Regents of the University of
+ *  California; see the COPYRIGHT file for full details.  Squid
+ *  incorporates software developed and/or copyrighted by other
+ *  sources; see the CREDITS file for full details.
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *  
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *  
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111, USA.
+ *
+ */
+
+#include "squid.h"
+#include "CacheManager.h"
+#include "Store.h"
+#include "HttpRequest.h"
+#include "AuthUserRequest.h"
+
+#define ROTATE_LEFT(x, n) (((x) << (n)) | ((x) >> (32-(n))))
+
+static int n_userhash_peers = 0;
+static peer **userhash_peers = NULL;
+static OBJH peerUserHashCachemgr;
+
+static int
+peerSortWeight(const void *a, const void *b)
+{
+    const peer *const *p1 = (const peer *const *)a;
+    const peer *const *p2 = (const peer *const *)b;
+    return (*p1)->weight - (*p2)->weight;
+}
+
+void
+peerUserHashInit(void)
+{
+    int W = 0;
+    int K;
+    int k;
+    double P_last, X_last, Xn;
+    peer *p;
+    peer **P;
+    char *t;
+    /* Clean up */
+
+    for (k = 0; k < n_userhash_peers; k++) {
+        cbdataReferenceDone(userhash_peers[k]);
+    }
+
+    safe_free(userhash_peers);
+    n_userhash_peers = 0;
+    /* find out which peers we have */
+
+    for (p = Config.peers; p; p = p->next) {
+        if (!p->options.userhash)
+            continue;
+
+        assert(p->type == PEER_PARENT);
+
+        if (p->weight == 0)
+            continue;
+
+        n_userhash_peers++;
+
+        W += p->weight;
+    }
+
+    if (n_userhash_peers == 0)
+        return;
+
+    userhash_peers = (peer **)xcalloc(n_userhash_peers, sizeof(*userhash_peers));
+
+    /* Build a list of the found peers and calculate hashes and load factors */
+    for (P = userhash_peers, p = Config.peers; p; p = p->next) {
+        if (!p->options.userhash)
+            continue;
+
+        if (p->weight == 0)
+            continue;
+
+        /* calculate this peers hash */
+        p->userhash.hash = 0;
+
+        for (t = p->name; *t != 0; t++)
+            p->userhash.hash += ROTATE_LEFT(p->userhash.hash, 19) + (unsigned int) *t;
+
+        p->userhash.hash += p->userhash.hash * 0x62531965;
+
+        p->userhash.hash = ROTATE_LEFT(p->userhash.hash, 21);
+
+        /* and load factor */
+        p->userhash.load_factor = ((double) p->weight) / (double) W;
+
+        if (floor(p->userhash.load_factor * 1000.0) == 0.0)
+            p->userhash.load_factor = 0.0;
+
+        /* add it to our list of peers */
+        *P++ = cbdataReference(p);
+    }
+
+    /* Sort our list on weight */
+    qsort(userhash_peers, n_userhash_peers, sizeof(*userhash_peers), peerSortWeight);
+
+    /* Calculate the load factor multipliers X_k
+     *
+     * X_1 = pow ((K*p_1), (1/K))
+     * X_k = ([K-k+1] * [P_k - P_{k-1}])/(X_1 * X_2 * ... * X_{k-1})
+     * X_k += pow ((X_{k-1}, {K-k+1})
+     * X_k = pow (X_k, {1/(K-k+1)})
+     * simplified to have X_1 part of the loop
+     */
+    K = n_userhash_peers;
+
+    P_last = 0.0;		/* Empty P_0 */
+
+    Xn = 1.0;			/* Empty starting point of X_1 * X_2 * ... * X_{x-1} */
+
+    X_last = 0.0;		/* Empty X_0, nullifies the first pow statement */
+
+    for (k = 1; k <= K; k++) {
+        double Kk1 = (double) (K - k + 1);
+        p = userhash_peers[k - 1];
+        p->userhash.load_multiplier = (Kk1 * (p->userhash.load_factor - P_last)) / Xn;
+        p->userhash.load_multiplier += pow(X_last, Kk1);
+        p->userhash.load_multiplier = pow(p->userhash.load_multiplier, 1.0 / Kk1);
+        Xn *= p->userhash.load_multiplier;
+        X_last = p->userhash.load_multiplier;
+        P_last = p->userhash.load_factor;
+    }
+}
+
+void
+peerUserHashRegisterWithCacheManager(CacheManager & manager)
+{
+    manager.registerAction("userhash", "peer userhash information", peerUserHashCachemgr, 0, 1);
+}
+
+peer *
+peerUserHashSelectParent(HttpRequest * request)
+{
+    int k;
+    const char *c;
+    peer *p = NULL;
+    peer *tp;
+    unsigned int user_hash = 0;
+    unsigned int combined_hash;
+    double score;
+    double high_score = 0;
+    const char *key = NULL;
+
+    if (n_userhash_peers == 0)
+        return NULL;
+
+    if (request->auth_user_request)
+	key = request->auth_user_request->username();
+
+    if (!key)
+	return NULL;
+
+    /* calculate hash key */
+    debugs(39, 2, "peerUserHashSelectParent: Calculating hash for " << key);
+
+    for (c = key; *c != 0; c++)
+        user_hash += ROTATE_LEFT(user_hash, 19) + *c;
+
+    /* select peer */
+    for (k = 0; k < n_userhash_peers; k++) {
+        tp = userhash_peers[k];
+        combined_hash = (user_hash ^ tp->userhash.hash);
+        combined_hash += combined_hash * 0x62531965;
+        combined_hash = ROTATE_LEFT(combined_hash, 21);
+        score = combined_hash * tp->userhash.load_multiplier;
+        debugs(39, 3, "peerUserHashSelectParent: " << tp->name << " combined_hash " << combined_hash  << 
+               " score " << std::setprecision(0) << score);
+
+        if ((score > high_score) && peerHTTPOkay(tp, request)) {
+            p = tp;
+            high_score = score;
+        }
+    }
+
+    if (p)
+        debugs(39, 2, "peerUserHashSelectParent: selected " << p->name);
+
+    return p;
+}
+
+static void
+peerUserHashCachemgr(StoreEntry * sentry)
+{
+    peer *p;
+    int sumfetches = 0;
+    storeAppendPrintf(sentry, "%24s %10s %10s %10s %10s\n",
+                      "Hostname",
+                      "Hash",
+                      "Multiplier",
+                      "Factor",
+                      "Actual");
+
+    for (p = Config.peers; p; p = p->next)
+        sumfetches += p->stats.fetches;
+
+    for (p = Config.peers; p; p = p->next) {
+        storeAppendPrintf(sentry, "%24s %10x %10f %10f %10f\n",
+                          p->name, p->userhash.hash,
+                          p->userhash.load_multiplier,
+                          p->userhash.load_factor,
+                          sumfetches ? (double) p->stats.fetches / sumfetches : -1.0);
+    }
+}
diff -u -r -N squid-3.0.STABLE7/src/pinger.cc squid-3.0.STABLE8/src/pinger.cc
--- squid-3.0.STABLE7/src/pinger.cc	2008-06-22 15:35:53.000000000 +1200
+++ squid-3.0.STABLE8/src/pinger.cc	2008-07-18 22:02:54.000000000 +1200
@@ -63,7 +63,9 @@
 
 #ifdef _SQUID_MSWIN_
 
+#if HAVE_WINSOCK2_H
 #include <winsock2.h>
+#endif
 #include <process.h>
 
 #define PINGER_TIMEOUT 5
@@ -222,6 +224,12 @@
                            );
 }
 
+void
+Win32SockCleanup(void)
+{
+    WSACleanup();
+    return;
+}
 #endif
 
 void
@@ -239,6 +247,7 @@
     struct sockaddr_in PS;
 
     WSAStartup(2, &wsaData);
+    atexit(Win32SockCleanup);
 
     getCurrentTime();
     _db_init(NULL, "ALL,1");
diff -u -r -N squid-3.0.STABLE7/src/protos.h squid-3.0.STABLE8/src/protos.h
--- squid-3.0.STABLE7/src/protos.h	2008-06-22 15:35:54.000000000 +1200
+++ squid-3.0.STABLE8/src/protos.h	2008-07-18 22:02:54.000000000 +1200
@@ -373,7 +373,8 @@
 SQUIDCEXTERN peer *getDefaultParent(HttpRequest * request);
 SQUIDCEXTERN peer *getRoundRobinParent(HttpRequest * request);
 SQUIDCEXTERN peer *getWeightedRoundRobinParent(HttpRequest * request);
-SQUIDCEXTERN void peerClearRR(void *);
+SQUIDCEXTERN void peerClearRRStart(void);
+SQUIDCEXTERN void peerClearRR(void);
 SQUIDCEXTERN peer *getAnyParent(HttpRequest * request);
 SQUIDCEXTERN lookup_t peerDigestLookup(peer * p, HttpRequest * request);
 SQUIDCEXTERN peer *neighborsDigestSelect(HttpRequest * request);
@@ -706,10 +707,17 @@
 
 #if USE_CARP
 SQUIDCEXTERN void carpInit(void);
-extern void carpRegisterWithCacheManager(CacheManager & manager);
+SQUIDCEXTERN void carpRegisterWithCacheManager(CacheManager & manager);
 SQUIDCEXTERN peer *carpSelectParent(HttpRequest *);
 #endif
 
+SQUIDCEXTERN void peerUserHashInit(void);
+SQUIDCEXTERN void peerUserHashRegisterWithCacheManager(CacheManager & manager);
+SQUIDCEXTERN peer * peerUserHashSelectParent(HttpRequest * request);
+
+SQUIDCEXTERN void peerSourceHashInit(void);
+SQUIDCEXTERN void peerSourceHashRegisterWithCacheManager(CacheManager & manager);
+SQUIDCEXTERN peer * peerSourceHashSelectParent(HttpRequest * request);
 
 #if USE_LEAKFINDER
 SQUIDCEXTERN void leakInit(void);
diff -u -r -N squid-3.0.STABLE7/src/StoreIOBuffer.h squid-3.0.STABLE8/src/StoreIOBuffer.h
--- squid-3.0.STABLE7/src/StoreIOBuffer.h	2008-06-22 15:35:52.000000000 +1200
+++ squid-3.0.STABLE8/src/StoreIOBuffer.h	2008-07-18 22:02:53.000000000 +1200
@@ -68,8 +68,8 @@
 
     void dump() const
     {
-        fwrite(data, length, 1, stderr);
-        fwrite("\n", 1, 1, stderr);
+        if(fwrite(data, length, 1, stderr)) {}
+        if(fwrite("\n", 1, 1, stderr)) {}
     }
 
     struct
diff -u -r -N squid-3.0.STABLE7/src/structs.h squid-3.0.STABLE8/src/structs.h
--- squid-3.0.STABLE7/src/structs.h	2008-06-22 15:35:54.000000000 +1200
+++ squid-3.0.STABLE8/src/structs.h	2008-07-18 22:02:54.000000000 +1200
@@ -554,6 +554,7 @@
         int httpd_suppress_version_string;
         int global_internal_static;
         int debug_override_X;
+        int WIN32_IpAddrChangeMonitor;
     }
 
     onoff;
@@ -1063,20 +1064,15 @@
 unsigned int no_delay:
         1;
 #endif
-
-unsigned int allow_miss:
-        1;
+        unsigned int allow_miss:1;
 #if USE_CARP
-
-unsigned int carp:
-        1;
+        unsigned int carp:1;
 #endif
+        unsigned int userhash:1;
+        unsigned int sourcehash:1;
+        unsigned int originserver:1;
+    } options;
 
-unsigned int originserver:
-        1;
-    }
-
-    options;
     int weight;
     int basetime;
 
@@ -1113,7 +1109,6 @@
     struct IN_ADDR addresses[10];
     int n_addresses;
     int rr_count;
-    int rr_lastcount;
     peer *next;
     int test_fd;
 #if USE_CARP
@@ -1128,6 +1123,20 @@
     carp;
 #endif
 
+    struct
+    {
+        unsigned int hash;
+        double load_multiplier;
+        double load_factor;	/* normalized weight value */
+    } userhash;
+
+    struct
+    {
+        unsigned int hash;
+        double load_multiplier;
+        double load_factor;	/* normalized weight value */
+    } sourcehash;
+
     char *login;		/* Proxy authorization */
     time_t connect_timeout;
     int max_conn;
diff -u -r -N squid-3.0.STABLE7/src/tools.cc squid-3.0.STABLE8/src/tools.cc
--- squid-3.0.STABLE7/src/tools.cc	2008-06-22 15:35:54.000000000 +1200
+++ squid-3.0.STABLE8/src/tools.cc	2008-07-18 22:02:55.000000000 +1200
@@ -152,7 +152,7 @@
 
     snprintf(command, 256, "%s %s < %s", Config.EmailProgram, Config.adminEmail, filename);
 
-    system(command);		/* XXX should avoid system(3) */
+    if(system(command)) {}		/* XXX should avoid system(3) */
 
     unlink(filename);
 }
diff -u -r -N squid-3.0.STABLE7/src/WinSvc.cc squid-3.0.STABLE8/src/WinSvc.cc
--- squid-3.0.STABLE7/src/WinSvc.cc	2008-06-22 15:35:52.000000000 +1200
+++ squid-3.0.STABLE8/src/WinSvc.cc	2008-07-18 22:02:53.000000000 +1200
@@ -390,16 +390,18 @@
     WIN32_Exit();
 }
 
+#ifdef _SQUID_MSWIN_
 void
 WIN32_IpAddrChangeMonitorExit()
 {
     DWORD status = ERROR_SUCCESS;
 
-    if (NotifyAddrChange_thread == INVALID_HANDLE_VALUE) {
+    if (NotifyAddrChange_thread != INVALID_HANDLE_VALUE) {
 	TerminateThread(NotifyAddrChange_thread, status);
 	CloseHandle(NotifyAddrChange_thread);
     }
 }
+#endif
 
 void
 WIN32_Exit()
@@ -459,7 +461,7 @@
     DWORD status = ERROR_SUCCESS;
     DWORD threadID = 0, ThrdParam = 0;
 
-    if (WIN32_run_mode == _WIN_SQUID_RUN_MODE_SERVICE) {
+    if ((WIN32_run_mode == _WIN_SQUID_RUN_MODE_SERVICE) && (Config.onoff.WIN32_IpAddrChangeMonitor)) {
 	NotifyAddrChange_thread = CreateThread(NULL, 0, WIN32_IpAddrChangeMonitor,
 	    &ThrdParam, 0, &threadID);
 	if (NotifyAddrChange_thread == NULL) {
diff -u -r -N squid-3.0.STABLE7/tools/cachemgr.cc squid-3.0.STABLE8/tools/cachemgr.cc
--- squid-3.0.STABLE7/tools/cachemgr.cc	2008-06-22 15:35:54.000000000 +1200
+++ squid-3.0.STABLE8/tools/cachemgr.cc	2008-07-18 22:02:55.000000000 +1200
@@ -420,7 +420,7 @@
     printf("<HTML><HEAD><TITLE>Cache Manager Error</TITLE>\n");
     printf("<STYLE type=\"text/css\"><!--BODY{background-color:#ffffff;font-family:verdana,sans-serif}--></STYLE></HEAD>\n");
     printf("<BODY><H1>Cache Manager Error</H1>\n");
-    printf("<P>\n%s</P>\n", msg);
+    printf("<P>\n%s</P>\n", html_quote(msg));
     print_trailer();
 }
 
@@ -536,7 +536,7 @@
     if (!strchr(buf, '\t') || *buf == '\t') {
         /* nope, just text */
         snprintf(html, sizeof(html), "%s%s",
-                 table_line_num ? "</table>\n<pre>" : "", buf);
+                 table_line_num ? "</table>\n<pre>" : "", html_quote(buf));
         table_line_num = 0;
         return html;
     }
@@ -573,7 +573,7 @@
         l += snprintf(html + l, sizeof(html) - l, "<%s colspan=\"%d\" align=\"%s\">%s</%s>",
                       ttag, column_span,
                       is_header ? "center" : is_number(cell) ? "right" : "left",
-                      cell, ttag);
+                      html_quote(cell), ttag);
     }
 
     xfree(buf_copy);
@@ -584,6 +584,27 @@
     return html;
 }
 
+static const char *
+munge_action_line(const char *_buf, cachemgr_request * req)
+{
+    static char html[2 * 1024];
+    char *buf = xstrdup(_buf);
+    char *x = buf;
+    const char *action, *description;
+    char *p;
+
+    if ((p = strchr(x, '\n')))
+       *p = '\0';
+    action = xstrtok(&x, '\t');
+    description = xstrtok(&x, '\t');
+    if (!description)
+       description = action;
+    if (!action)
+       return "";
+    snprintf(html, sizeof(html), " <a href=\"%s\">%s</a>", menu_url(req, action), description);
+    return html;
+}
+
 static int
 read_reply(int s, cachemgr_request * req)
 {
@@ -599,7 +620,7 @@
 #endif
     /* interpretation states */
     enum {
-        isStatusLine, isHeaders, isBodyStart, isBody, isForward, isEof, isForwardEof, isSuccess, isError
+        isStatusLine, isHeaders, isActions, isBodyStart, isBody, isForward, isEof, isForwardEof, isSuccess, isError
     } istate = isStatusLine;
     int parse_menu = 0;
     const char *action = req->action;
@@ -694,6 +715,22 @@
                 printf("<PRE>\n");
             }
 
+            istate = isActions;
+            /* yes, fall through, we do not want to loose the first line */
+
+        case isActions:
+            if (strncmp(buf, "action:", 7) == 0) {
+                fputs(" ", stdout);
+                fputs(munge_action_line(buf + 7, req), stdout);
+                break;
+            }
+            if (parse_menu) {
+                printf("<UL>\n");
+            } else {
+                printf("<HR noshade size=\"1px\">\n");
+                printf("<PRE>\n");
+            }
+
             istate = isBody;
             /* yes, fall through, we do not want to loose the first line */
 
@@ -714,9 +751,7 @@
              * 401 to .cgi because web server filters out all auth info. Thus we
              * disable authentication headers for now.
              */
-            if (!strncasecmp(buf, "WWW-Authenticate:", 17) || !strncasecmp(buf, "Proxy-Authenticate:", 19))
-
-                ;	/* skip */
+            if (!strncasecmp(buf, "WWW-Authenticate:", 17) || !strncasecmp(buf, "Proxy-Authenticate:", 19));	/* skip */
             else
                 fputs(buf, stdout);
 
diff -u -r -N squid-3.0.STABLE7/tools/squidclient.cc squid-3.0.STABLE8/tools/squidclient.cc
--- squid-3.0.STABLE7/tools/squidclient.cc	2008-06-22 15:35:54.000000000 +1200
+++ squid-3.0.STABLE8/tools/squidclient.cc	2008-07-18 22:02:55.000000000 +1200
@@ -86,7 +86,13 @@
 #include "util.h"
 
 #ifndef BUFSIZ
-#define BUFSIZ 8192
+#define BUFSIZ		8192
+#endif
+#ifndef MESSAGELEN
+#define MESSAGELEN	65536
+#endif
+#ifndef HEADERLEN
+#define HEADERLEN	65536
 #endif
 
 typedef void SIGHDLR(int sig);
@@ -110,6 +116,15 @@
 int total_bytes = 0;
 int io_timeout = 120;
 
+#ifdef _SQUID_MSWIN_
+void
+Win32SockCleanup(void)
+{
+    WSACleanup();
+    return;
+}
+#endif /* ifdef _SQUID_MSWIN_ */
+
 static void
 usage(const char *progname)
 {
@@ -151,8 +166,8 @@
     int opt_noaccept = 0;
     int opt_verbose = 0;
     const char *hostname, *localhost;
-    char url[BUFSIZ], msg[49152], buf[BUFSIZ];
-    char extra_hdrs[32768];
+    char url[BUFSIZ], msg[MESSAGELEN], buf[BUFSIZ];
+    char extra_hdrs[HEADERLEN];
     const char *method = "GET";
     extern char *optarg;
     time_t ims = 0;
@@ -313,6 +328,7 @@
     {
 	WSADATA wsaData;
 	WSAStartup(2, &wsaData);
+	atexit(Win32SockCleanup);
     }
 #endif
     /* Build the HTTP request */
