]> git.ipfire.org Git - thirdparty/squid.git/commitdiff
Bug #1554: HTCP RFC compliance
authorhno <>
Tue, 30 May 2006 23:31:23 +0000 (23:31 +0000)
committerhno <>
Tue, 30 May 2006 23:31:23 +0000 (23:31 +0000)
Fix field order to comply with the RFC. Bump minor version to 1 to
make migration easier. New cache-peer option to support old Squid HTCP
implementaitons.

src/cache_cf.cc
src/cf.data.pre
src/htcp.cc
src/structs.h

index 3f0d8c0c511f2b07c0eab41c25923f96ea15ce4f..818003142f7d3c02ba677839e05f2173ca6ecb5c 100644 (file)
@@ -1,6 +1,6 @@
 
 /*
- * $Id: cache_cf.cc,v 1.497 2006/05/29 00:15:01 robertc Exp $
+ * $Id: cache_cf.cc,v 1.498 2006/05/30 17:31:23 hno Exp $
  *
  * DEBUG: section 3     Configuration File Parsing
  * AUTHOR: Harvest Derived
@@ -1546,6 +1546,9 @@ parse_peer(peer ** head)
 
         } else if (!strcasecmp(token, "htcp")) {
             p->options.htcp = 1;
+        } else if (!strcasecmp(token, "htcp-oldsquid")) {
+            p->options.htcp = 1;
+            p->options.htcp_oldsquid = 1;
 #endif
 
         } else if (!strcasecmp(token, "no-netdb-exchange")) {
index b1e8f8f2b5a60bd6caa1c4827263c5cd455644e7..e7560bea5189057ecf55b61832ce93927aba54c7 100644 (file)
@@ -1,6 +1,6 @@
 
 #
-# $Id: cf.data.pre,v 1.414 2006/05/26 22:33:24 hno Exp $
+# $Id: cf.data.pre,v 1.415 2006/05/30 17:31:23 hno Exp $
 #
 #
 # SQUID Web Proxy Cache                http://www.squid-cache.org/
@@ -475,6 +475,7 @@ DOC_START
                     allow-miss
                     max-conn
                     htcp
+                    htcp-oldsquid
                     originserver
                     name=xxx
                     forceddomain=name
@@ -602,6 +603,8 @@ DOC_START
                     to the neighbor.  You probably also want to
                     set the "icp port" to 4827 instead of 3130.
 
+                    use 'htcp-oldsquid' to send HTCP to old Squid versions
+
                     'originserver' causes this parent peer to be contacted as
                     a origin server. Meant to be used in accelerator setups.
 
index 3a09dd1cb2fccb86068ee65d2b59780187fb8cef..b5ae84d59069090ca7457dfba26239b0a1b58044 100644 (file)
@@ -1,6 +1,6 @@
 
 /*
- * $Id: htcp.cc,v 1.67 2006/05/12 19:27:11 serassio Exp $
+ * $Id: htcp.cc,v 1.68 2006/05/30 17:31:23 hno Exp $
  *
  * DEBUG: section 31    Hypertext Caching Protocol
  * AUTHOR: Duane Wesssels
@@ -49,6 +49,8 @@ typedef struct _htcpHeader htcpHeader;
 
 typedef struct _htcpDataHeader htcpDataHeader;
 
+typedef struct _htcpDataHeaderSquid htcpDataHeaderSquid;
+
 typedef struct _htcpAuthHeader htcpAuthHeader;
 
 typedef struct _htcpStuff htcpStuff;
@@ -69,6 +71,49 @@ struct _htcpHeader
 };
 
 struct _htcpDataHeader
+{
+    u_int16_t length;
+#if WORDS_BIGENDIAN
+
+u_int8_t opcode:
+    4;
+
+u_int8_t response:
+    4;
+#else
+
+u_int8_t response:
+    4;
+
+u_int8_t opcode:
+    4;
+#endif
+#if WORDS_BIGENDIAN
+
+u_int8_t reserved:
+    6;
+
+u_int8_t F1:
+    1;
+
+u_int8_t RR:
+    1;
+#else
+
+u_int8_t RR:
+    1;
+
+u_int8_t F1:
+    1;
+
+u_int8_t reserved:
+    6;
+#endif
+
+    u_int32_t msg_id;
+};
+
+struct _htcpDataHeaderSquid
 {
     u_int16_t length;
 #if !WORDS_BIGENDIAN
@@ -215,6 +260,8 @@ static int htcpOutSocket = -1;
 static cache_key queried_keys[N_QUERIED_KEYS][MD5_DIGEST_CHARS];
 static MemAllocator *htcpDetailPool = NULL;
 
+static int old_squid_format = 0;
+
 
 static char *htcpBuildPacket(htcpStuff * stuff, ssize_t * len);
 static htcpSpecifier *htcpUnpackSpecifier(char *buf, int sz);
@@ -481,7 +528,18 @@ htcpBuildData(char *buf, size_t buflen, htcpStuff * stuff)
 
     hdr.msg_id = htonl(hdr.msg_id);
 
-    xmemcpy(buf, &hdr, hdr_sz);
+    if (!old_squid_format) {
+        xmemcpy(buf, &hdr, hdr_sz);
+    } else {
+        htcpDataHeaderSquid hdrSquid;
+        memset(&hdrSquid, 0, sizeof(hdrSquid));
+        hdrSquid.length = hdr.length;
+        hdrSquid.opcode = hdr.opcode;
+        hdrSquid.response = hdr.response;
+        hdrSquid.F1 = hdr.F1;
+        hdrSquid.RR = hdr.RR;
+        xmemcpy(buf, &hdrSquid, hdr_sz);
+    }
 
     debug(31, 3) ("htcpBuildData: size %d\n", (int) off);
 
@@ -523,10 +581,18 @@ htcpBuildPacket(htcpStuff * stuff, ssize_t * len)
     off += s;
     hdr.length = htons((u_int16_t) off);
     hdr.major = 0;
-    hdr.minor = 0;
+
+    if (old_squid_format)
+        hdr.minor = 0;
+    else
+        hdr.minor = 1;
+
     xmemcpy(buf, &hdr, hdr_sz);
+
     *len = off;
+
     debug(31, 3) ("htcpBuildPacket: size %d\n", (int) off);
+
     return buf;
 }
 
@@ -1002,7 +1068,21 @@ htcpHandleData(char *buf, int sz, struct sockaddr_in *from)
         return;
     }
 
-    xmemcpy(&hdr, buf, sizeof(htcpDataHeader));
+    if (!old_squid_format)
+    {
+        xmemcpy(&hdr, buf, sizeof(htcpDataHeader));
+    } else
+    {
+        htcpDataHeaderSquid hdrSquid;
+        xmemcpy(&hdrSquid, buf, sizeof(hdrSquid));
+        hdr.opcode = hdrSquid.opcode;
+        hdr.response = hdrSquid.response;
+        hdr.F1 = hdrSquid.F1;
+        hdr.RR = hdrSquid.RR;
+        hdr.reserved = 0;
+        hdr.msg_id = hdrSquid.msg_id;
+    }
+
     hdr.length = ntohs(hdr.length);
     hdr.msg_id = ntohl(hdr.msg_id);
     debug(31, 3) ("htcpHandleData: sz = %d\n", sz);
@@ -1025,7 +1105,13 @@ htcpHandleData(char *buf, int sz, struct sockaddr_in *from)
 
     if (sz < hdr.length)
     {
-        debug(31, 0) ("htcpHandle: sz < hdr.length\n");
+        debug(31, 1) ("htcpHandle: sz < hdr.length\n");
+        return;
+    }
+
+    if (hdr.length + sizeof(htcpDataHeader) > (size_t)sz)
+    {
+        debug(31, 1) ("htcpHandleData: Invalid HTCP packet from %s\n", inet_ntoa(from->sin_addr));
         return;
     }
 
@@ -1089,8 +1175,16 @@ htcpHandle(char *buf, int sz, struct sockaddr_in *from)
     htcpHexdump("htcpHandle", buf, sz);
     xmemcpy(&htcpHdr, buf, sizeof(htcpHeader));
     htcpHdr.length = ntohs(htcpHdr.length);
+
+    if (htcpHdr.minor == 0)
+        old_squid_format = 1;
+    else
+        old_squid_format = 0;
+
     debug(31, 3) ("htcpHandle: htcpHdr.length = %d\n", (int) htcpHdr.length);
+
     debug(31, 3) ("htcpHandle: htcpHdr.major = %d\n", (int) htcpHdr.major);
+
     debug(31, 3) ("htcpHandle: htcpHdr.minor = %d\n", (int) htcpHdr.minor);
 
     if (sz != htcpHdr.length)
@@ -1101,6 +1195,14 @@ htcpHandle(char *buf, int sz, struct sockaddr_in *from)
         return;
     }
 
+    if (htcpHdr.major != 0)
+    {
+        debug(31, 1) ("htcpHandle: Unknown major version %d from %s:%d\n",
+                      htcpHdr.major,
+                      inet_ntoa(from->sin_addr), (int) ntohs(from->sin_port));
+        return;
+    }
+
     buf += sizeof(htcpHeader);
     sz -= sizeof(htcpHeader);
     htcpHandleData(buf, sz, from);
@@ -1204,6 +1306,8 @@ htcpQuery(StoreEntry * e, HttpRequest * req, peer * p)
     if (htcpInSocket < 0)
         return;
 
+    old_squid_format = p->options.htcp_oldsquid;
+
     memset(&flags, '\0', sizeof(flags));
 
     snprintf(vbuf, sizeof(vbuf), "%d/%d",
index 68a767f5e17f89e7de8cc1b9f211c45e9509de46..c059aa14cd8caed38f4afb98735c107f53e1885c 100644 (file)
@@ -1,6 +1,6 @@
 
 /*
- * $Id: structs.h,v 1.542 2006/05/08 23:38:33 robertc Exp $
+ * $Id: structs.h,v 1.543 2006/05/30 17:31:23 hno Exp $
  *
  *
  * SQUID Web Proxy Cache          http://www.squid-cache.org/
@@ -1157,6 +1157,9 @@ unsigned int closest_only:
 
 unsigned int htcp:
         1;
+
+unsigned int htcp_oldsquid:
+        1;
 #endif
 
 unsigned int no_netdb_exchange: