--------------------- PatchSet 8103 Date: 2006/05/31 10:19:59 Author: serassio Branch: nt Tag: (none) Log: Manually merge with HEAD after a Sourgeforce problem durin latest cvsmerge, grrrrrr ...... Members: CONTRIBUTORS:1.24.2.1->1.24.2.2 ChangeLog:1.44.2.11->1.44.2.12 doc/Makefile.am:1.5.8.1->1.5.8.2 doc/cachemgr.cgi.8.in:1.2->1.2.10.1 doc/squid.8.in:1.2.10.2->1.2.10.3 src/cf.data.pre:1.100.2.11->1.100.2.12 src/client_side.c:1.89.2.14->1.89.2.15 src/htcp.c:1.16->1.16.6.1 src/protos.h:1.74.2.14->1.74.2.15 src/structs.h:1.81.2.11->1.81.2.12 Index: squid/CONTRIBUTORS =================================================================== RCS file: /cvsroot/squid-sf//squid/CONTRIBUTORS,v retrieving revision 1.24.2.1 retrieving revision 1.24.2.2 diff -u -r1.24.2.1 -r1.24.2.2 --- squid/CONTRIBUTORS 18 May 2006 18:34:19 -0000 1.24.2.1 +++ squid/CONTRIBUTORS 31 May 2006 10:19:59 -0000 1.24.2.2 @@ -93,5 +93,8 @@ Flavio Pescuma Paul Armstrong Steven Wilton + Felix Meschberger + Mark Bergsma + Tim Starling Duane Wessels Index: squid/ChangeLog =================================================================== RCS file: /cvsroot/squid-sf//squid/ChangeLog,v retrieving revision 1.44.2.11 retrieving revision 1.44.2.12 diff -u -r1.44.2.11 -r1.44.2.12 --- squid/ChangeLog 30 May 2006 10:28:51 -0000 1.44.2.11 +++ squid/ChangeLog 31 May 2006 10:19:59 -0000 1.44.2.12 @@ -42,6 +42,8 @@ request details (browser, language etc). - umask now defaults to 027 to protect the content of cache and log files from local users + - HTCP support for access control and the CRL operation for + purgeing of cache content Changes to squid-2.5.STABLE14 (20 May 2006) - [Minor] icons not displayed when visible_hostname is a Index: squid/doc/Makefile.am =================================================================== RCS file: /cvsroot/squid-sf//squid/doc/Makefile.am,v retrieving revision 1.5.8.1 retrieving revision 1.5.8.2 diff -u -r1.5.8.1 -r1.5.8.2 --- squid/doc/Makefile.am 16 May 2006 21:05:57 -0000 1.5.8.1 +++ squid/doc/Makefile.am 31 May 2006 10:20:00 -0000 1.5.8.2 @@ -16,6 +16,7 @@ s%@DEFAULT_CACHEMGR_CONFIG@%$(DEFAULT_CACHEMGR_CONFIG)%g;\ s%@DEFAULT_ERROR_DIR@%$(DEFAULT_ERROR_DIR)%g;\ s%@DEFAULT_MIME_TABLE@%$(DEFAULT_MIME_TABLE)%g;\ + s%@""PACKAGE_STRING""@%$(PACKAGE_STRING)%g;\ " squid.8: $(srcdir)/squid.8.in Makefile Index: squid/doc/cachemgr.cgi.8.in =================================================================== RCS file: /cvsroot/squid-sf//squid/doc/cachemgr.cgi.8.in,v retrieving revision 1.2 retrieving revision 1.2.10.1 diff -u -r1.2 -r1.2.10.1 --- squid/doc/cachemgr.cgi.8.in 28 Apr 2006 11:10:45 -0000 1.2 +++ squid/doc/cachemgr.cgi.8.in 31 May 2006 10:20:00 -0000 1.2.10.1 @@ -1,4 +1,4 @@ -.TH cachemgr.cgi 8 2005-04-25 "squid 2.5.STABLE10" +.TH cachemgr.cgi 8 2005-04-25 "@PACKAGE_STRING@" .\" Copyright and licensing information .\" goes here. .SH NAME Index: squid/doc/squid.8.in =================================================================== RCS file: /cvsroot/squid-sf//squid/doc/squid.8.in,v retrieving revision 1.2.10.2 retrieving revision 1.2.10.3 diff -u -r1.2.10.2 -r1.2.10.3 --- squid/doc/squid.8.in 30 May 2006 21:03:31 -0000 1.2.10.2 +++ squid/doc/squid.8.in 31 May 2006 10:20:00 -0000 1.2.10.3 @@ -1,4 +1,4 @@ -.TH squid 8 2006-05-29 "squid 2.6.PRE1" +.TH squid 8 2006-05-29 "@PACKAGE_STRING@" .\" Copyright and licensing information .\" goes here. .SH NAME Index: squid/src/cf.data.pre =================================================================== RCS file: /cvsroot/squid-sf//squid/src/cf.data.pre,v retrieving revision 1.100.2.11 retrieving revision 1.100.2.12 diff -u -r1.100.2.11 -r1.100.2.12 --- squid/src/cf.data.pre 30 May 2006 19:05:59 -0000 1.100.2.11 +++ squid/src/cf.data.pre 31 May 2006 10:20:00 -0000 1.100.2.12 @@ -1,6 +1,6 @@ # -# $Id: cf.data.pre,v 1.100.2.11 2006/05/30 19:05:59 serassio Exp $ +# $Id: cf.data.pre,v 1.100.2.12 2006/05/31 10:20:00 serassio Exp $ # # # SQUID Web Proxy Cache http://www.squid-cache.org/ @@ -2846,6 +2846,44 @@ DOC_END +NAME: htcp_access +IFDEF: USE_HTCP +TYPE: acl_access +LOC: Config.accessList.htcp +DEFAULT: none +DEFAULT_IF_NONE: deny all +DOC_START + Allowing or Denying access to the HTCP port based on defined + access lists + + htcp_access allow|deny [!]aclname ... + + See http_access for details + +#Allow HTCP queries from everyone +htcp_access allow all +DOC_END + +NAME: htcp_clr_access +IFDEF: USE_HTCP +TYPE: acl_access +LOC: Config.accessList.htcp_clr +DEFAULT: none +DEFAULT_IF_NONE: deny all +DOC_START + Allowing or Denying access to purge content using HTCP based + on defined access lists + + htcp_clr_access allow|deny [!]aclname ... + + See http_access for details + +#Allow HTCP CLR requests from trusted peers +acl htcp_clr_peer src 172.16.1.2 +htcp_clr_access allow htcp_clr_peer +DOC_END + + NAME: miss_access TYPE: acl_access LOC: Config.accessList.miss Index: squid/src/client_side.c =================================================================== RCS file: /cvsroot/squid-sf//squid/src/client_side.c,v retrieving revision 1.89.2.14 retrieving revision 1.89.2.15 diff -u -r1.89.2.14 -r1.89.2.15 --- squid/src/client_side.c 30 May 2006 20:10:06 -0000 1.89.2.14 +++ squid/src/client_side.c 31 May 2006 10:20:01 -0000 1.89.2.15 @@ -1,6 +1,6 @@ /* - * $Id: client_side.c,v 1.89.2.14 2006/05/30 20:10:06 serassio Exp $ + * $Id: client_side.c,v 1.89.2.15 2006/05/31 10:20:01 serassio Exp $ * * DEBUG: section 33 Client-side Routines * AUTHOR: Duane Wessels @@ -148,14 +148,18 @@ static int clientRequestBodyTooLarge(squid_off_t clen); static void clientProcessBody(ConnStateData * conn); static void clientEatRequestBody(clientHttpRequest *); -static void clientAccessCheckDone2(int answer, void *data); +static void clientAccessCheck(void *data); +static void clientAccessCheckDone(int answer, void *data); static void clientAccessCheck2(void *data); +static void clientAccessCheckDone2(int answer, void *data); static BODY_HANDLER clientReadBody; static void clientAbortBody(request_t * req); #if USE_SSL static void httpsAcceptSSL(ConnStateData * connState, SSL_CTX * sslContext); #endif static int varyEvaluateMatch(StoreEntry * entry, request_t * request); +static int modifiedSince(StoreEntry *, request_t *); +static StoreEntry *clientCreateStoreEntry(clientHttpRequest *, method_t, request_flags); #if USE_IDENT static void @@ -187,7 +191,7 @@ return ch; } -void +static void clientAccessCheck(void *data) { clientHttpRequest *http = data; @@ -220,7 +224,7 @@ EBIT_TEST(r->cache_control->mask, CC_ONLY_IF_CACHED); } -StoreEntry * +static StoreEntry * clientCreateStoreEntry(clientHttpRequest * h, method_t m, request_flags flags) { StoreEntry *e; @@ -241,7 +245,7 @@ return e; } -void +static void clientAccessCheckDone(int answer, void *data) { clientHttpRequest *http = data; @@ -867,7 +871,7 @@ } } -int +static int modifiedSince(StoreEntry * entry, request_t * request) { squid_off_t object_length; @@ -901,7 +905,7 @@ } } -void +static void clientPurgeRequest(clientHttpRequest * http) { StoreEntry *entry; Index: squid/src/htcp.c =================================================================== RCS file: /cvsroot/squid-sf//squid/src/htcp.c,v retrieving revision 1.16 retrieving revision 1.16.6.1 diff -u -r1.16 -r1.16.6.1 --- squid/src/htcp.c 12 May 2006 22:51:56 -0000 1.16 +++ squid/src/htcp.c 31 May 2006 10:20:01 -0000 1.16.6.1 @@ -1,6 +1,6 @@ /* - * $Id: htcp.c,v 1.16 2006/05/12 22:51:56 squidadm Exp $ + * $Id: htcp.c,v 1.16.6.1 2006/05/31 10:20:01 serassio Exp $ * * DEBUG: section 31 Hypertext Caching Protocol * AUTHOR: Duane Wesssels @@ -93,6 +93,7 @@ char *uri; char *version; char *req_hdrs; + request_t *request; }; struct _htcpDetail { @@ -155,14 +156,13 @@ static int htcpOutSocket = -1; #define N_QUERIED_KEYS 256 static cache_key queried_keys[N_QUERIED_KEYS][MD5_DIGEST_CHARS]; +static struct sockaddr_in queried_addr[N_QUERIED_KEYS]; static MemPool *htcpSpecifierPool = NULL; static MemPool *htcpDetailPool = NULL; - -static char *htcpBuildPacket(htcpStuff * stuff, ssize_t * len); +static ssize_t htcpBuildPacket(char *buf, size_t buflen, htcpStuff * stuff); static htcpSpecifier *htcpUnpackSpecifier(char *buf, int sz); static htcpDetail *htcpUnpackDetail(char *buf, int sz); -static int htcpUnpackCountstr(char *buf, int sz, char **str); static ssize_t htcpBuildAuth(char *buf, size_t buflen); static ssize_t htcpBuildCountstr(char *buf, size_t buflen, const char *s); static ssize_t htcpBuildData(char *buf, size_t buflen, htcpStuff * stuff); @@ -322,6 +322,9 @@ case HTCP_TST: off = htcpBuildTstOpData(buf + off, buflen, stuff); break; + case HTCP_CLR: + // nothing to be done + break; default: assert(0); break; @@ -358,40 +361,38 @@ return off; } -static char * -htcpBuildPacket(htcpStuff * stuff, ssize_t * len) +/* + * Build an HTCP packet into buf, maximum length buflen. + * Returns the packet length, or zero on failure. + */ +static ssize_t +htcpBuildPacket(char *buf, size_t buflen, htcpStuff * stuff) { - size_t buflen = 8192; ssize_t s; ssize_t off = 0; size_t hdr_sz = sizeof(htcpHeader); htcpHeader hdr; - char *buf = xcalloc(buflen, 1); /* skip the header -- we don't know the overall length */ if (buflen < hdr_sz) { - xfree(buf); - return NULL; + return 0; } off += hdr_sz; s = htcpBuildData(buf + off, buflen - off, stuff); if (s < 0) { - xfree(buf); - return NULL; + return 0; } off += s; s = htcpBuildAuth(buf + off, buflen - off); if (s < 0) { - xfree(buf); - return NULL; + return 0; } off += s; hdr.length = htons((u_short) off); hdr.major = 0; hdr.minor = 0; xmemcpy(buf, &hdr, hdr_sz); - *len = off; debug(31, 3) ("htcpBuildPacket: size %d\n", (int) off); - return buf; + return off; } static void @@ -417,130 +418,185 @@ static void htcpFreeSpecifier(htcpSpecifier * s) { - safe_free(s->method); - safe_free(s->uri); - safe_free(s->version); - safe_free(s->req_hdrs); + if (s->request) + requestDestroy(s->request); memPoolFree(htcpSpecifierPool, s); } static void htcpFreeDetail(htcpDetail * d) { - safe_free(d->resp_hdrs); - safe_free(d->entity_hdrs); - safe_free(d->cache_hdrs); memPoolFree(htcpDetailPool, d); } -static int -htcpUnpackCountstr(char *buf, int sz, char **str) -{ - u_short l; - debug(31, 3) ("htcpUnpackCountstr: sz = %d\n", sz); - if (sz < 2) { - debug(31, 3) ("htcpUnpackCountstr: sz < 2\n"); - return -1; - } - htcpHexdump("htcpUnpackCountstr", buf, sz); - xmemcpy(&l, buf, 2); - l = ntohs(l); - buf += 2; - sz -= 2; - debug(31, 3) ("htcpUnpackCountstr: LENGTH = %d\n", (int) l); - if (sz < l) { - debug(31, 3) ("htcpUnpackCountstr: sz(%d) < l(%d)\n", sz, l); - return -1; - } - if (str) { - *str = xmalloc(l + 1); - xstrncpy(*str, buf, l + 1); - debug(31, 3) ("htcpUnpackCountstr: TEXT = {%s}\n", *str); - } - return (int) l + 2; -} - +/* + * Unpack an HTCP SPECIFIER in place + * This will overwrite any following AUTH block + */ static htcpSpecifier * htcpUnpackSpecifier(char *buf, int sz) { htcpSpecifier *s = memPoolAlloc(htcpSpecifierPool); - int o; - debug(31, 3) ("htcpUnpackSpecifier: %d bytes\n", (int) sz); - o = htcpUnpackCountstr(buf, sz, &s->method); - if (o < 0) { + method_t method; + + /* Find length of METHOD */ + u_short l = ntohs(*(u_short *) buf); + sz -= 2; + buf += 2; + if (l > sz) { debug(31, 1) ("htcpUnpackSpecifier: failed to unpack METHOD\n"); htcpFreeSpecifier(s); return NULL; } - buf += o; - sz -= o; - o = htcpUnpackCountstr(buf, sz, &s->uri); - if (o < 0) { + /* Set METHOD */ + s->method = buf; + buf += l; + sz -= l; + + /* Find length of URI */ + l = ntohs(*(u_short *) buf); + sz -= 2; + if (l > sz) { debug(31, 1) ("htcpUnpackSpecifier: failed to unpack URI\n"); htcpFreeSpecifier(s); return NULL; } - buf += o; - sz -= o; - o = htcpUnpackCountstr(buf, sz, &s->version); - if (o < 0) { + /* Add terminating null to METHOD */ + *buf = '\0'; + /* Set URI */ + buf += 2; + s->uri = buf; + buf += l; + sz -= l; + + /* Find length of VERSION */ + l = ntohs(*(u_short *) buf); + sz -= 2; + if (l > sz) { debug(31, 1) ("htcpUnpackSpecifier: failed to unpack VERSION\n"); htcpFreeSpecifier(s); return NULL; } - buf += o; - sz -= o; - o = htcpUnpackCountstr(buf, sz, &s->req_hdrs); - if (o < 0) { + /* Add terminating null to URI */ + *buf = '\0'; + /* Set VERSION */ + buf += 2; + s->version = buf; + buf += l; + sz -= l; + + /* Find length of REQ-HDRS */ + l = ntohs(*(u_short *) buf); + sz -= 2; + if (l > sz) { debug(31, 1) ("htcpUnpackSpecifier: failed to unpack REQ-HDRS\n"); htcpFreeSpecifier(s); return NULL; } - buf += o; - sz -= o; + /* Add terminating null to URI */ + *buf = '\0'; + /* Set REQ-HDRS */ + buf += 2; + s->req_hdrs = buf; + buf += l; + sz -= l; + debug(31, 3) ("htcpUnpackSpecifier: %d bytes left\n", sz); + /* + * Add terminating null to REQ-HDRS. This is possible because we allocated + * an extra byte when we received the packet. This will overwrite any following + * AUTH block. + */ + *buf = '\0'; + /* + * Parse the request + */ + method = urlParseMethod(s->method); + s->request = urlParse(method == METHOD_NONE ? METHOD_GET : method, s->uri); return s; } +/* + * Unpack an HTCP DETAIL in place + * This will overwrite any following AUTH block + */ static htcpDetail * htcpUnpackDetail(char *buf, int sz) { htcpDetail *d = memPoolAlloc(htcpDetailPool); - int o; - debug(31, 3) ("htcpUnpackDetail: %d bytes\n", (int) sz); - o = htcpUnpackCountstr(buf, sz, &d->resp_hdrs); - if (o < 0) { - debug(31, 1) ("htcpUnpackDetail: failed to unpack RESP_HDRS\n"); + + /* Find length of RESP-HDRS */ + u_short l = ntohs(*(u_short *) buf); + sz -= 2; + buf += 2; + if (l > sz) { + debug(31, 1) ("htcpUnpackDetail: failed to unpack RESP-HDRS\n"); htcpFreeDetail(d); return NULL; } - buf += o; - sz -= o; - o = htcpUnpackCountstr(buf, sz, &d->entity_hdrs); - if (o < 0) { - debug(31, 1) ("htcpUnpackDetail: failed to unpack ENTITY_HDRS\n"); + /* Set RESP-HDRS */ + d->resp_hdrs = buf; + buf += l; + sz -= l; + + /* Find length of ENTITY-HDRS */ + l = ntohs(*(u_short *) buf); + sz -= 2; + if (l > sz) { + debug(31, 1) ("htcpUnpackDetail: failed to unpack ENTITY-HDRS\n"); htcpFreeDetail(d); return NULL; } - buf += o; - sz -= o; - o = htcpUnpackCountstr(buf, sz, &d->cache_hdrs); - if (o < 0) { - debug(31, 1) ("htcpUnpackDetail: failed to unpack CACHE_HDRS\n"); + /* Add terminating null to RESP-HDRS */ + *buf = '\0'; + /* Set ENTITY-HDRS */ + buf += 2; + d->entity_hdrs = buf; + buf += l; + sz -= l; + + /* Find length of CACHE-HDRS */ + l = ntohs(*(u_short *) buf); + sz -= 2; + if (l > sz) { + debug(31, 1) ("htcpUnpackDetail: failed to unpack CACHE-HDRS\n"); htcpFreeDetail(d); return NULL; } - buf += o; - sz -= o; + /* Add terminating null to ENTITY-HDRS */ + *buf = '\0'; + /* Set CACHE-HDRS */ + buf += 2; + d->cache_hdrs = buf; + buf += l; + sz -= l; + debug(31, 3) ("htcpUnpackDetail: %d bytes left\n", sz); + /* + * Add terminating null to CACHE-HDRS. This is possible because we allocated + * an extra byte when we received the packet. This will overwrite any following + * AUTH block. + */ + *buf = '\0'; return d; } +static int +htcpAccessCheck(acl_access * acl, htcpSpecifier * s, struct sockaddr_in *from) +{ + aclCheck_t checklist; + memset(&checklist, '\0', sizeof(checklist)); + checklist.src_addr = from->sin_addr; + checklist.my_addr = no_addr; + checklist.request = s->request; + return aclCheckFast(acl, &checklist); +} + static void htcpTstReply(htcpDataHeader * dhdr, StoreEntry * e, htcpSpecifier * spec, struct sockaddr_in *from) { htcpStuff stuff; - char *pkt; + static char pkt[8192]; HttpHeader hdr; MemBuf mb; Packer p; @@ -597,16 +653,41 @@ httpHeaderClean(&hdr); packerClean(&p); } - pkt = htcpBuildPacket(&stuff, &pktlen); + pktlen = htcpBuildPacket(pkt, sizeof(pkt), &stuff); safe_free(stuff.D.resp_hdrs); safe_free(stuff.D.entity_hdrs); safe_free(stuff.D.cache_hdrs); - if (pkt == NULL) { + if (!pktlen) { debug(31, 0) ("htcpTstReply: htcpBuildPacket() failed\n"); return; } htcpSend(pkt, (int) pktlen, from); - xfree(pkt); +} + +static void +htcpClrReply(htcpDataHeader * dhdr, int purgeSucceeded, struct sockaddr_in *from) +{ + htcpStuff stuff; + static char pkt[8192]; + ssize_t pktlen; + + /* If dhdr->F1 == 0, no response desired */ + if (dhdr->F1 == 0) + return; + + memset(&stuff, '\0', sizeof(stuff)); + stuff.op = HTCP_CLR; + stuff.rr = RR_RESPONSE; + stuff.f1 = 0; + stuff.response = purgeSucceeded ? 0 : 2; + debug(31, 3) ("htcpClrReply: response = %d\n", stuff.response); + stuff.msg_id = dhdr->msg_id; + pktlen = htcpBuildPacket(pkt, sizeof(pkt), &stuff); + if (pktlen == 0) { + debug(31, 0) ("htcpClrReply: htcpBuildPacket() failed\n"); + return; + } + htcpSend(pkt, (int) pktlen, from); } static void @@ -618,11 +699,9 @@ static StoreEntry * htcpCheckHit(const htcpSpecifier * s) { - request_t *request; - method_t m = urlParseMethod(s->method); + request_t *request = s->request; StoreEntry *e = NULL, *hit = NULL; char *blk_end; - request = urlParse(m, s->uri); if (NULL == request) { debug(31, 3) ("htcpCheckHit: NO; failed to parse URL\n"); return NULL; @@ -648,11 +727,52 @@ debug(31, 3) ("htcpCheckHit: YES!?\n"); hit = e; miss: - requestDestroy(request); return hit; } static void +htcpClrStoreEntry(StoreEntry * e) +{ + debug(31, 4) ("htcpClrStoreEntry: Clearing store for entry: %s\n", storeUrl(e)); + storeRelease(e); +} + +static int +htcpClrStore(const htcpSpecifier * s) +{ + request_t *request = s->request; + char *blk_end; + StoreEntry *e = NULL; + int released; + + if (request == NULL) { + debug(31, 3) ("htcpClrStore: failed to parse URL\n"); + return -1; + } + /* Parse request headers */ + blk_end = s->req_hdrs + strlen(s->req_hdrs); + if (!httpHeaderParse(&request->header, s->req_hdrs, blk_end)) { + debug(31, 2) ("htcpClrStore: failed to parse request headers\n"); + return -1; + } + /* Lookup matching entries. This matches both GET and HEAD */ + while ((e = storeGetPublicByRequest(request)) != NULL) { + if (e != NULL) { + htcpClrStoreEntry(e); + released++; + } + } + + if (released) { + debug(31, 4) ("htcpClrStore: Cleared %d matching entries\n", released); + return 1; + } else { + debug(31, 4) ("htcpClrStore: No matching entry found\n"); + return 0; + } +} + +static void htcpHandleTst(htcpDataHeader * hdr, char *buf, int sz, struct sockaddr_in *from) { debug(31, 3) ("htcpHandleTst: sz = %d\n", (int) sz); @@ -667,10 +787,22 @@ { htcpReplyData htcpReply; cache_key *key = NULL; + struct sockaddr_in *peer; htcpDetail *d = NULL; char *t; + + key = queried_keys[hdr->msg_id % N_QUERIED_KEYS]; + if (!key) { + debug(31, 2) ("htcpHandleTstResponse: No matching query id '%d' from '%s'\n", hdr->msg_id, inet_ntoa(from->sin_addr)); + return; + } + peer = &queried_addr[hdr->msg_id % N_QUERIED_KEYS]; + if (peer->sin_addr.s_addr != from->sin_addr.s_addr || peer->sin_port != from->sin_port) { + debug(31, 1) ("htcpHandleTstResponse: Unexpected response source %s\n", inet_ntoa(from->sin_addr)); + return; + } if (hdr->F1 == 1) { - debug(31, 1) ("htcpHandleTstResponse: error condition, F1/MO == 1\n"); + debug(31, 2) ("htcpHandleTstResponse: error condition, F1/MO == 1\n"); return; } memset(&htcpReply, '\0', sizeof(htcpReply)); @@ -716,7 +848,17 @@ return; s = htcpUnpackSpecifier(buf, sz); if (NULL == s) { - debug(31, 3) ("htcpHandleTstRequest: htcpUnpackSpecifier failed\n"); + debug(31, 2) ("htcpHandleTstRequest: htcpUnpackSpecifier failed\n"); + return; + } + if (!s->request) { + debug(31, 2) ("htcpHandleTstRequest: failed to parse request\n"); + htcpFreeSpecifier(s); + return; + } + if (!htcpAccessCheck(Config.accessList.htcp, s, from)) { + debug(31, 2) ("htcpHandleTstRequest: Access denied\n"); + htcpFreeSpecifier(s); return; } debug(31, 3) ("htcpHandleTstRequest: %s %s %s\n", @@ -744,6 +886,54 @@ } static void +htcpHandleClr(htcpDataHeader * hdr, char *buf, int sz, struct sockaddr_in *from) +{ + /* buf[0/1] is reserved and reason */ + int reason = buf[1] << 4; + debug(31, 3) ("htcpHandleClr: reason=%d\n", reason); + buf += 2; + sz -= 2; + + /* buf should be a SPECIFIER */ + htcpSpecifier *s; + if (sz == 0) { + debug(31, 4) ("htcpHandleClr: nothing to do\n"); + return; + } + s = htcpUnpackSpecifier(buf, sz); + if (NULL == s) { + debug(31, 3) ("htcpHandleClr: htcpUnpackSpecifier failed\n"); + return; + } + if (!htcpAccessCheck(Config.accessList.htcp_clr, s, from)) { + debug(31, 2) ("htcpHandleClr: Access denied\n"); + htcpFreeSpecifier(s); + return; + } + debug(31, 5) ("htcpHandleClr: %s %s %s\n", + s->method, + s->uri, + s->version); + debug(31, 5) ("htcpHandleClr: request headers: %s\n", s->req_hdrs); + + /* Release objects from cache + * analog to clientPurgeRequest in client_side.c + */ + switch (htcpClrStore(s)) { + case 1: + htcpClrReply(hdr, 1, from); /* hit */ + break; + case 0: + htcpClrReply(hdr, 0, from); /* miss */ + break; + default: + break; + } + + htcpFreeSpecifier(s); +} + +static void htcpHandleData(char *buf, int sz, struct sockaddr_in *from) { htcpDataHeader hdr; @@ -795,12 +985,10 @@ htcpHandleSet(&hdr, buf, sz, from); break; case HTCP_CLR: - debug(31, 1) ("htcpHandleData: client %s, CLR not supported\n", - inet_ntoa(from->sin_addr)); + htcpHandleClr(&hdr, buf, sz, from); break; default: - assert(0); - break; + return; } } @@ -838,7 +1026,8 @@ socklen_t flen = sizeof(struct sockaddr_in); memset(&from, '\0', flen); statCounter.syscalls.sock.recvfroms++; - len = recvfrom(fd, buf, 8192, 0, (struct sockaddr *) &from, &flen); + /* Receive up to 8191 bytes, leaving room for a null */ + len = recvfrom(fd, buf, sizeof(buf) - 1, 0, (struct sockaddr *) &from, &flen); debug(31, 3) ("htcpRecv: FD %d, %d bytes from %s:%d\n", fd, len, inet_ntoa(from.sin_addr), ntohs(from.sin_port)); htcpHandle(buf, len, &from); @@ -899,7 +1088,7 @@ htcpQuery(StoreEntry * e, request_t * req, peer * p) { cache_key *save_key; - char *pkt; + static char pkt[8192]; ssize_t pktlen; char vbuf[32]; htcpStuff stuff; @@ -929,17 +1118,17 @@ httpHeaderClean(&hdr); packerClean(&pa); stuff.S.req_hdrs = mb.buf; - pkt = htcpBuildPacket(&stuff, &pktlen); + pktlen = htcpBuildPacket(pkt, sizeof(pkt), &stuff); memBufClean(&mb); - if (pkt == NULL) { + if (!pktlen) { debug(31, 0) ("htcpQuery: htcpBuildPacket() failed\n"); return; } htcpSend(pkt, (int) pktlen, &p->in_addr); save_key = queried_keys[stuff.msg_id % N_QUERIED_KEYS]; storeKeyCopy(save_key, e->hash.key); + queried_addr[stuff.msg_id % N_QUERIED_KEYS] = p->in_addr; debug(31, 3) ("htcpQuery: key (%p) %s\n", save_key, storeKeyText(save_key)); - xfree(pkt); } /* Index: squid/src/protos.h =================================================================== RCS file: /cvsroot/squid-sf//squid/src/protos.h,v retrieving revision 1.74.2.14 retrieving revision 1.74.2.15 diff -u -r1.74.2.14 -r1.74.2.15 --- squid/src/protos.h 29 May 2006 18:41:17 -0000 1.74.2.14 +++ squid/src/protos.h 31 May 2006 10:20:01 -0000 1.74.2.15 @@ -1,6 +1,6 @@ /* - * $Id: protos.h,v 1.74.2.14 2006/05/29 18:41:17 serassio Exp $ + * $Id: protos.h,v 1.74.2.15 2006/05/31 10:20:01 serassio Exp $ * * * SQUID Web Proxy Cache http://www.squid-cache.org/ @@ -135,15 +135,10 @@ extern void clientdbFreeMemory(void); extern int clientdbEstablished(struct in_addr, int); -extern void clientAccessCheck(void *); -extern void clientAccessCheckDone(int, void *); -extern int modifiedSince(StoreEntry *, request_t *); extern char *clientConstructTraceEcho(clientHttpRequest *); -extern void clientPurgeRequest(clientHttpRequest *); extern int checkNegativeHit(StoreEntry *); extern void clientOpenListenSockets(void); extern void clientHttpConnectionsClose(void); -extern StoreEntry *clientCreateStoreEntry(clientHttpRequest *, method_t, request_flags); extern int isTcpHit(log_type); extern int commSetNonBlocking(int fd); Index: squid/src/structs.h =================================================================== RCS file: /cvsroot/squid-sf//squid/src/structs.h,v retrieving revision 1.81.2.11 retrieving revision 1.81.2.12 diff -u -r1.81.2.11 -r1.81.2.12 --- squid/src/structs.h 30 May 2006 19:05:59 -0000 1.81.2.11 +++ squid/src/structs.h 31 May 2006 10:20:02 -0000 1.81.2.12 @@ -1,6 +1,6 @@ /* - * $Id: structs.h,v 1.81.2.11 2006/05/30 19:05:59 serassio Exp $ + * $Id: structs.h,v 1.81.2.12 2006/05/31 10:20:02 serassio Exp $ * * * SQUID Web Proxy Cache http://www.squid-cache.org/ @@ -695,6 +695,10 @@ acl_access *reply; acl_address *outgoing_address; acl_tos *outgoing_tos; +#if USE_HTCP + acl_access *htcp; + acl_access *htcp_clr; +#endif } accessList; acl_deny_info_list *denyInfoList; struct _authConfig {