]> git.ipfire.org Git - thirdparty/squid.git/blob - src/icp_v3.cc
Added storeGetPublic() mostly so that we can check both old and new
[thirdparty/squid.git] / src / icp_v3.cc
1
2 /*
3 * $Id: icp_v3.cc,v 1.26 1998/09/21 06:52:16 wessels Exp $
4 *
5 * DEBUG: section 12 Internet Cache Protocol
6 * AUTHOR: Duane Wessels
7 *
8 * SQUID Internet Object Cache http://squid.nlanr.net/Squid/
9 * ----------------------------------------------------------
10 *
11 * Squid is the result of efforts by numerous individuals from the
12 * Internet community. Development is led by Duane Wessels of the
13 * National Laboratory for Applied Network Research and funded by the
14 * National Science Foundation. Squid is Copyrighted (C) 1998 by
15 * Duane Wessels and the University of California San Diego. Please
16 * see the COPYRIGHT file for full details. Squid incorporates
17 * software developed and/or copyrighted by other sources. Please see
18 * the CREDITS file for full details.
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
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;
44 StoreEntry *entry = NULL;
45 char *url = NULL;
46 const cache_key *key;
47 request_t *icp_request = NULL;
48 int allow = 0;
49 aclCheck_t checklist;
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);
58
59 switch (header.opcode) {
60 case ICP_QUERY:
61 /* We have a valid packet */
62 url = buf + sizeof(icp_common_t) + sizeof(u_num32);
63 if (strpbrk(url, w_space)) {
64 url = rfc1738_escape(url);
65 reply = icpCreateMessage(ICP_ERR, 0, url, header.reqnum, 0);
66 icpUdpSend(fd, &from, reply, LOG_UDP_INVALID, 0);
67 break;
68 }
69 if ((icp_request = urlParse(METHOD_GET, url)) == NULL) {
70 reply = icpCreateMessage(ICP_ERR, 0, url, header.reqnum, 0);
71 icpUdpSend(fd, &from, reply, LOG_UDP_INVALID, 0);
72 break;
73 }
74 checklist.src_addr = from.sin_addr;
75 checklist.request = icp_request;
76 allow = aclCheckFast(Config.accessList.icp, &checklist);
77 if (!allow) {
78 debug(12, 2) ("icpHandleIcpV3: Access Denied for %s by %s.\n",
79 inet_ntoa(from.sin_addr), AclMatchedName);
80 if (clientdbCutoffDenied(from.sin_addr)) {
81 /*
82 * count this DENIED query in the clientdb, even though
83 * we're not sending an ICP reply...
84 */
85 clientdbUpdate(from.sin_addr, LOG_UDP_DENIED, PROTO_ICP, 0);
86 } else {
87 reply = icpCreateMessage(ICP_DENIED, 0, url, header.reqnum, 0);
88 icpUdpSend(fd, &from, reply, LOG_UDP_DENIED, 0);
89 }
90 break;
91 }
92 /* The peer is allowed to use this cache */
93 entry = storeGetPublic(url, METHOD_GET);
94 debug(12, 5) ("icpHandleIcpV3: OPCODE %s\n",
95 icp_opcode_str[header.opcode]);
96 if (icpCheckUdpHit(entry, icp_request)) {
97 reply = icpCreateMessage(ICP_HIT, 0, url, header.reqnum, 0);
98 icpUdpSend(fd, &from, reply, LOG_UDP_HIT, 0);
99 break;
100 }
101 /* if store is rebuilding, return a UDP_HIT, but not a MISS */
102 if (opt_reload_hit_only && store_rebuilding) {
103 reply = icpCreateMessage(ICP_MISS_NOFETCH, 0, url, header.reqnum, 0);
104 icpUdpSend(fd, &from, reply, LOG_UDP_MISS_NOFETCH, 0);
105 } else if (hit_only_mode_until > squid_curtime) {
106 reply = icpCreateMessage(ICP_MISS_NOFETCH, 0, url, header.reqnum, 0);
107 icpUdpSend(fd, &from, reply, LOG_UDP_MISS_NOFETCH, 0);
108 } else {
109 reply = icpCreateMessage(ICP_MISS, 0, url, header.reqnum, 0);
110 icpUdpSend(fd, &from, reply, LOG_UDP_MISS, 0);
111 }
112 break;
113
114 case ICP_HIT:
115 case ICP_SECHO:
116 case ICP_DECHO:
117 case ICP_MISS:
118 case ICP_DENIED:
119 case ICP_MISS_NOFETCH:
120 if (neighbors_do_private_keys && header.reqnum == 0) {
121 debug(12, 0) ("icpHandleIcpV3: Neighbor %s returned reqnum = 0\n",
122 inet_ntoa(from.sin_addr));
123 debug(12, 0) ("icpHandleIcpV3: Disabling use of private keys\n");
124 neighbors_do_private_keys = 0;
125 }
126 url = buf + sizeof(icp_common_t);
127 debug(12, 3) ("icpHandleIcpV3: %s from %s for '%s'\n",
128 icp_opcode_str[header.opcode],
129 inet_ntoa(from.sin_addr),
130 url);
131 key = icpGetCacheKey(url, (int) header.reqnum);
132 /* call neighborsUdpAck even if ping_status != PING_WAITING */
133 neighborsUdpAck(key, &header, &from);
134 break;
135
136 case ICP_INVALID:
137 case ICP_ERR:
138 break;
139
140 default:
141 debug(12, 0) ("icpHandleIcpV3: UNKNOWN OPCODE: %d from %s\n",
142 header.opcode, inet_ntoa(from.sin_addr));
143 break;
144 }
145 if (icp_request)
146 requestDestroy(icp_request);
147 }