diff -Nur squid-3.0.STABLE4/src/cf.data.pre squid-3.0.STABLE4-zph/src/cf.data.pre
--- squid-3.0.STABLE4/src/cf.data.pre	2008-04-01 14:54:37.000000000 +0300
+++ squid-3.0.STABLE4-zph/src/cf.data.pre	2008-04-23 15:55:39.000000000 +0300
@@ -1103,6 +1103,60 @@
 	making the request.
 DOC_END
 
+NAME: zph_tos_local
+TYPE: int
+DEFAULT: 0
+LOC: Config.zph_tos_local
+DOC_START
+       Allows you to select a TOS/Diffserv value to mark local hits. Read above
+       (tcp_outgoing_tos) for details/requirements about TOS.
+       Default: 0 (disabled).
+DOC_END
+
+NAME: zph_tos_peer
+TYPE: int
+DEFAULT: 0
+LOC: Config.zph_tos_peer
+DOC_START
+       Allows you to select a TOS/Diffserv value to mark peer hits. Read above
+       (tcp_outgoing_tos) for details/requirements about TOS.
+       Default: 0 (disabled).
+DOC_END
+
+NAME: zph_tos_parent
+COMMENT: on|off
+TYPE: onoff
+LOC: Config.onoff.zph_tos_parent
+DEFAULT: on
+DOC_START
+       Set this to off if you want only sibling hits to be marked.
+       If set to on (default), parent hits are being marked too.
+DOC_END
+
+NAME: zph_preserve_miss_tos
+COMMENT: on|off
+TYPE: onoff
+LOC: Config.onoff.zph_preserve_miss_tos
+DEFAULT: on
+DOC_START
+       If set to on (default), any HTTP response towards clients will
+       have the TOS value of the response comming from the remote
+       server masked with the value of zph_preserve_miss_tos_mask.
+       For this to work correctly, you will need to patch your linux
+       kernel with the TOS preserving ZPH patch.
+DOC_END
+
+NAME: zph_preserve_miss_tos_mask
+TYPE: int
+DEFAULT: 255
+LOC: Config.zph_preserve_miss_tos_mask
+DOC_START
+       Allows you to mask certain bits in the TOS received from the
+       remote server, before copying the value to the TOS send towards
+       clients.
+       Default: 255 (TOS from server is not changed).
+DOC_END
+
 NAME: tcp_outgoing_address
 TYPE: acl_address
 DEFAULT: none
diff -Nur squid-3.0.STABLE4/src/client_side_reply.cc squid-3.0.STABLE4-zph/src/client_side_reply.cc
--- squid-3.0.STABLE4/src/client_side_reply.cc	2008-04-01 14:54:37.000000000 +0300
+++ squid-3.0.STABLE4-zph/src/client_side_reply.cc	2008-04-23 15:56:33.000000000 +0300
@@ -48,6 +48,7 @@
 #include "ESI.h"
 #endif
 #include "MemObject.h"
+#include "fde.h"
 #include "ACLChecklist.h"
 #include "ACL.h"
 #if DELAY_POOLS
@@ -1614,6 +1615,58 @@
         /* guarantee nothing has been sent yet! */
         assert(http->out.size == 0);
         assert(http->out.offset == 0);
+
+        if (Config.zph_tos_local ||
+        	Config.zph_tos_peer ||
+	        Config.onoff.zph_preserve_miss_tos && Config.zph_preserve_miss_tos_mask)
+		{
+		   int need_change = 0;
+		   int hit = 0;
+		   int tos = 0;
+		   int tos_old = 0;
+		   int tos_len = sizeof(tos_old);
+		   int res;
+		               
+		   if (Config.zph_tos_local)
+		   {
+			   /* local hit */
+		       hit = 1;
+		       tos = Config.zph_tos_local;
+		   }
+		   else if (Config.zph_tos_peer && 
+			    	(http->request->hier.code==SIBLING_HIT ||
+			    	Config.onoff.zph_tos_parent&&http->request->hier.code==PARENT_HIT))
+		   {
+			  /* sibling or parent hit */
+		       hit = 1;
+		       tos = Config.zph_tos_peer;
+		   }
+		   
+		   if (http->request->flags.proxy_keepalive)
+		   {
+			   res = getsockopt(http->getConn()->fd, IPPROTO_IP, IP_TOS, &tos_old, (socklen_t*)&tos_len);
+		       if (res < 0)
+		       {
+		           debugs(33, 1, "ZPH: error in getsockopt(IP_TOS) on keepalived FD "<< http->getConn()->fd << " " << xstrerror());
+		       }
+		       else if (hit && tos_old != tos)
+		       {
+		    	   /* HIT: 1-st request, or previous was MISS,
+		    	    * or local/parent hit change.
+		    	    */
+		           need_change = 1;                    
+		       }
+		   }
+		   else if (hit)
+		   {
+			   /* no keepalive */
+		       need_change = 1;
+		   }
+		   if (need_change) {
+			   comm_set_tos(http->getConn()->fd,tos);
+		   }
+		}        
+        
         tempBuffer.offset = reqofs;
         tempBuffer.length = getNextNode()->readBuffer.length;
         tempBuffer.data = getNextNode()->readBuffer.data;
@@ -1922,6 +1975,14 @@
      */
     assert(reqofs == 0 || flags.storelogiccomplete);
 
+    if (reqofs==0 && !logTypeIsATcpHit(http->logType) &&
+    	Config.onoff.zph_preserve_miss_tos &&
+    	Config.zph_preserve_miss_tos_mask)
+    {
+		int tos = fd_table[fd].upstreamTOS & Config.zph_preserve_miss_tos_mask;
+		comm_set_tos(fd,tos);
+    }
+
     if (flags.headersSent && buf != result.data) {
         /* we've got to copy some data */
         assert(result.length <= next()->readBuffer.length);
diff -Nur squid-3.0.STABLE4/src/fde.h squid-3.0.STABLE4-zph/src/fde.h
--- squid-3.0.STABLE4/src/fde.h	2008-04-01 14:54:38.000000000 +0300
+++ squid-3.0.STABLE4-zph/src/fde.h	2008-04-23 15:57:11.000000000 +0300
@@ -106,7 +106,7 @@
         long handle;
     } win32;
 #endif
-
+    unsigned char upstreamTOS;			/* see FwdState::dispatch()  */
 };
 
 #endif /* SQUID_FDE_H */
diff -Nur squid-3.0.STABLE4/src/forward.cc squid-3.0.STABLE4-zph/src/forward.cc
--- squid-3.0.STABLE4/src/forward.cc	2008-04-01 14:54:38.000000000 +0300
+++ squid-3.0.STABLE4-zph/src/forward.cc	2008-04-23 15:57:59.000000000 +0300
@@ -968,6 +968,52 @@
 
     netdbPingSite(request->host);
 
+    /* Retrieves remote server TOS value, and stores it as part of the
+     * original client request FD object. It is later used to forward
+     * remote server's TOS in the response to the client in case of a MISS.
+     */
+	fde * clientFde = &fd_table[client_fd];
+	if (clientFde)
+	{
+		int tos = 1;
+		int tos_len = sizeof(tos);
+		clientFde->upstreamTOS = 0;
+	    if (setsockopt(server_fd,SOL_IP,IP_RECVTOS,&tos,tos_len)==0)
+	    {
+	       unsigned char buf[512];
+	       int len = 512;
+	       if (getsockopt(server_fd,SOL_IP,IP_PKTOPTIONS,buf,(socklen_t*)&len) == 0)
+	       {
+	           /* Parse the PKTOPTIONS structure to locate the TOS data message
+	            * prepared in the kernel by the ZPH incoming TCP TOS preserving
+	            * patch.
+	            */
+	    	   unsigned char * p = buf;
+	           while (p-buf < len)
+	           {
+	              struct cmsghdr *o = (struct cmsghdr*)p;
+	              if (o->cmsg_len<=0)
+	                 break;
+	
+	              if (o->cmsg_level == SOL_IP && o->cmsg_type == IP_TOS)
+	              {
+	            	  clientFde->upstreamTOS = (unsigned char)(*(int*)CMSG_DATA(o));
+	            	  break;
+	              }
+	              p += CMSG_LEN(o->cmsg_len);
+	           }
+	       }
+	       else
+	       {
+	           debugs(33, 1, "ZPH: error in getsockopt(IP_PKTOPTIONS) on FD "<<server_fd<<" "<<xstrerror());
+	       }
+	    }
+	    else
+	    {
+	    	debugs(33, 1, "ZPH: error in setsockopt(IP_RECVTOS) on FD "<<server_fd<<" "<<xstrerror());
+	    }
+	}    
+
     if (servers && (p = servers->_peer)) {
         p->stats.fetches++;
         request->peer_login = p->login;
diff -Nur squid-3.0.STABLE4/src/Parsing.cc squid-3.0.STABLE4-zph/src/Parsing.cc
--- squid-3.0.STABLE4/src/Parsing.cc	2008-04-01 14:54:37.000000000 +0300
+++ squid-3.0.STABLE4-zph/src/Parsing.cc	2008-04-23 17:10:51.000000000 +0300
@@ -89,9 +89,14 @@
     if (token == NULL)
         self_destruct();
 
-    if (sscanf(token, "%d", &i) != 1)
-        self_destruct();
-
+    if (token[0]=='0'&&token[1]=='x') {
+    	char junk;
+    	if (sscanf(token, "0x%x%c", &i, &junk) != 1)
+            self_destruct();
+    } else {
+	    if (sscanf(token, "%d", &i) != 1)
+	        self_destruct();
+    }
     return i;
 }
 
diff -Nur squid-3.0.STABLE4/src/structs.h squid-3.0.STABLE4-zph/src/structs.h
--- squid-3.0.STABLE4/src/structs.h	2008-04-01 14:54:39.000000000 +0300
+++ squid-3.0.STABLE4-zph/src/structs.h	2008-04-23 15:58:18.000000000 +0300
@@ -553,6 +553,8 @@
         int emailErrData;
         int httpd_suppress_version_string;
         int global_internal_static;
+        int zph_tos_parent;
+        int zph_preserve_miss_tos;
         int debug_override_X;
     }
 
@@ -720,6 +722,9 @@
     int sleep_after_fork;	/* microseconds */
     time_t minimum_expiry_time;	/* seconds */
     external_acl *externalAclHelperList;
+    int zph_tos_local;
+    int zph_tos_peer;
+    int zph_preserve_miss_tos_mask;
 #if USE_SSL
 
     struct
