]>
Commit | Line | Data |
---|---|---|
9cef6668 | 1 | |
2 | /* | |
2b6662ba | 3 | * $Id: icp_v3.cc,v 1.33 2001/01/12 00:37:18 wessels Exp $ |
9cef6668 | 4 | * |
5 | * DEBUG: section 12 Internet Cache Protocol | |
6 | * AUTHOR: Duane Wessels | |
7 | * | |
2b6662ba | 8 | * SQUID Web Proxy Cache http://www.squid-cache.org/ |
9cef6668 | 9 | * ---------------------------------------------------------- |
10 | * | |
2b6662ba | 11 | * Squid is the result of efforts by numerous individuals from |
12 | * the Internet community; see the CONTRIBUTORS file for full | |
13 | * details. Many organizations have provided support for Squid's | |
14 | * development; see the SPONSORS file for full details. Squid is | |
15 | * Copyrighted (C) 2001 by the Regents of the University of | |
16 | * California; see the COPYRIGHT file for full details. Squid | |
17 | * incorporates software developed and/or copyrighted by other | |
18 | * sources; see the CREDITS file for full details. | |
9cef6668 | 19 | * |
20 | * This program is free software; you can redistribute it and/or modify | |
21 | * it under the terms of the GNU General Public License as published by | |
22 | * the Free Software Foundation; either version 2 of the License, or | |
23 | * (at your option) any later version. | |
24 | * | |
25 | * This program is distributed in the hope that it will be useful, | |
26 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
27 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
28 | * GNU General Public License for more details. | |
29 | * | |
30 | * You should have received a copy of the GNU General Public License | |
31 | * along with this program; if not, write to the Free Software | |
32 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111, USA. | |
33 | * | |
34 | */ | |
35 | ||
7a2f978b | 36 | #include "squid.h" |
37 | ||
38 | /* Currently Harvest cached-2.x uses ICP_VERSION_3 */ | |
39 | void | |
40 | icpHandleIcpV3(int fd, struct sockaddr_in from, char *buf, int len) | |
41 | { | |
42 | icp_common_t header; | |
43 | icp_common_t *reply; | |
7a2f978b | 44 | StoreEntry *entry = NULL; |
45 | char *url = NULL; | |
46 | const cache_key *key; | |
47 | request_t *icp_request = NULL; | |
48 | int allow = 0; | |
7a2f978b | 49 | aclCheck_t checklist; |
c8f6c9c7 | 50 | xmemcpy(&header, buf, sizeof(icp_common_t)); |
51 | /* | |
52 | * Only these fields need to be converted | |
53 | */ | |
54 | header.length = ntohs(header.length); | |
55 | header.reqnum = ntohl(header.reqnum); | |
56 | header.flags = ntohl(header.flags); | |
57 | header.pad = ntohl(header.pad); | |
7b83b3d9 | 58 | /* |
59 | * Length field should match the number of bytes read | |
60 | */ | |
61 | if (len != header.length) { | |
62 | debug(12, 3) ("icpHandleIcpV3: ICP message is too small\n"); | |
63 | return; | |
64 | } | |
7a2f978b | 65 | switch (header.opcode) { |
27cd7235 | 66 | case ICP_QUERY: |
7a2f978b | 67 | /* We have a valid packet */ |
c8f6c9c7 | 68 | url = buf + sizeof(icp_common_t) + sizeof(u_num32); |
a02d20d9 | 69 | if (strpbrk(url, w_space)) { |
70 | url = rfc1738_escape(url); | |
71 | reply = icpCreateMessage(ICP_ERR, 0, url, header.reqnum, 0); | |
72 | icpUdpSend(fd, &from, reply, LOG_UDP_INVALID, 0); | |
73 | break; | |
74 | } | |
007b8be4 | 75 | if ((icp_request = urlParse(METHOD_GET, url)) == NULL) { |
27cd7235 | 76 | reply = icpCreateMessage(ICP_ERR, 0, url, header.reqnum, 0); |
17b6e784 | 77 | icpUdpSend(fd, &from, reply, LOG_UDP_INVALID, 0); |
7a2f978b | 78 | break; |
79 | } | |
d20b1cd0 | 80 | memset(&checklist, '\0', sizeof(checklist)); |
7a2f978b | 81 | checklist.src_addr = from.sin_addr; |
ae2c08a2 | 82 | checklist.my_addr = no_addr; |
7a2f978b | 83 | checklist.request = icp_request; |
84 | allow = aclCheckFast(Config.accessList.icp, &checklist); | |
85 | if (!allow) { | |
86 | debug(12, 2) ("icpHandleIcpV3: Access Denied for %s by %s.\n", | |
87 | inet_ntoa(from.sin_addr), AclMatchedName); | |
e711a2ff | 88 | if (clientdbCutoffDenied(from.sin_addr)) { |
1a47dc5a | 89 | /* |
90 | * count this DENIED query in the clientdb, even though | |
91 | * we're not sending an ICP reply... | |
92 | */ | |
728da2ee | 93 | clientdbUpdate(from.sin_addr, LOG_UDP_DENIED, PROTO_ICP, 0); |
e711a2ff | 94 | } else { |
95 | reply = icpCreateMessage(ICP_DENIED, 0, url, header.reqnum, 0); | |
17b6e784 | 96 | icpUdpSend(fd, &from, reply, LOG_UDP_DENIED, 0); |
7a2f978b | 97 | } |
98 | break; | |
99 | } | |
100 | /* The peer is allowed to use this cache */ | |
08e5d64f | 101 | entry = storeGetPublic(url, METHOD_GET); |
7a2f978b | 102 | debug(12, 5) ("icpHandleIcpV3: OPCODE %s\n", |
27cd7235 | 103 | icp_opcode_str[header.opcode]); |
7a2f978b | 104 | if (icpCheckUdpHit(entry, icp_request)) { |
27cd7235 | 105 | reply = icpCreateMessage(ICP_HIT, 0, url, header.reqnum, 0); |
17b6e784 | 106 | icpUdpSend(fd, &from, reply, LOG_UDP_HIT, 0); |
7a2f978b | 107 | break; |
108 | } | |
109 | /* if store is rebuilding, return a UDP_HIT, but not a MISS */ | |
b2c141d4 | 110 | if (opt_reload_hit_only && store_dirs_rebuilding) { |
27cd7235 | 111 | reply = icpCreateMessage(ICP_MISS_NOFETCH, 0, url, header.reqnum, 0); |
17b6e784 | 112 | icpUdpSend(fd, &from, reply, LOG_UDP_MISS_NOFETCH, 0); |
7a2f978b | 113 | } else if (hit_only_mode_until > squid_curtime) { |
27cd7235 | 114 | reply = icpCreateMessage(ICP_MISS_NOFETCH, 0, url, header.reqnum, 0); |
17b6e784 | 115 | icpUdpSend(fd, &from, reply, LOG_UDP_MISS_NOFETCH, 0); |
7a2f978b | 116 | } else { |
27cd7235 | 117 | reply = icpCreateMessage(ICP_MISS, 0, url, header.reqnum, 0); |
17b6e784 | 118 | icpUdpSend(fd, &from, reply, LOG_UDP_MISS, 0); |
7a2f978b | 119 | } |
120 | break; | |
121 | ||
27cd7235 | 122 | case ICP_HIT: |
db1cd23c | 123 | #if ALLOW_SOURCE_PING |
27cd7235 | 124 | case ICP_SECHO: |
db1cd23c | 125 | #endif |
27cd7235 | 126 | case ICP_DECHO: |
127 | case ICP_MISS: | |
128 | case ICP_DENIED: | |
129 | case ICP_MISS_NOFETCH: | |
7a2f978b | 130 | if (neighbors_do_private_keys && header.reqnum == 0) { |
131 | debug(12, 0) ("icpHandleIcpV3: Neighbor %s returned reqnum = 0\n", | |
132 | inet_ntoa(from.sin_addr)); | |
133 | debug(12, 0) ("icpHandleIcpV3: Disabling use of private keys\n"); | |
134 | neighbors_do_private_keys = 0; | |
135 | } | |
c8f6c9c7 | 136 | url = buf + sizeof(icp_common_t); |
7a2f978b | 137 | debug(12, 3) ("icpHandleIcpV3: %s from %s for '%s'\n", |
27cd7235 | 138 | icp_opcode_str[header.opcode], |
7a2f978b | 139 | inet_ntoa(from.sin_addr), |
140 | url); | |
007b8be4 | 141 | key = icpGetCacheKey(url, (int) header.reqnum); |
5ad33356 | 142 | /* call neighborsUdpAck even if ping_status != PING_WAITING */ |
143 | neighborsUdpAck(key, &header, &from); | |
7a2f978b | 144 | break; |
145 | ||
27cd7235 | 146 | case ICP_INVALID: |
147 | case ICP_ERR: | |
7a2f978b | 148 | break; |
149 | ||
150 | default: | |
151 | debug(12, 0) ("icpHandleIcpV3: UNKNOWN OPCODE: %d from %s\n", | |
152 | header.opcode, inet_ntoa(from.sin_addr)); | |
153 | break; | |
154 | } | |
98abae73 | 155 | if (icp_request) |
99edd1c3 | 156 | requestDestroy(icp_request); |
7a2f978b | 157 | } |