]> git.ipfire.org Git - thirdparty/squid.git/blob - src/icp_v3.cc
Ignore an ICP message if the ICP length is not equal to the number
[thirdparty/squid.git] / src / icp_v3.cc
1
2 /*
3 * $Id: icp_v3.cc,v 1.30 1999/06/14 03:02:07 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 * 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 }
65 switch (header.opcode) {
66 case ICP_QUERY:
67 /* We have a valid packet */
68 url = buf + sizeof(icp_common_t) + sizeof(u_num32);
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 }
75 if ((icp_request = urlParse(METHOD_GET, url)) == NULL) {
76 reply = icpCreateMessage(ICP_ERR, 0, url, header.reqnum, 0);
77 icpUdpSend(fd, &from, reply, LOG_UDP_INVALID, 0);
78 break;
79 }
80 checklist.src_addr = from.sin_addr;
81 checklist.my_addr = no_addr;
82 checklist.request = icp_request;
83 allow = aclCheckFast(Config.accessList.icp, &checklist);
84 if (!allow) {
85 debug(12, 2) ("icpHandleIcpV3: Access Denied for %s by %s.\n",
86 inet_ntoa(from.sin_addr), AclMatchedName);
87 if (clientdbCutoffDenied(from.sin_addr)) {
88 /*
89 * count this DENIED query in the clientdb, even though
90 * we're not sending an ICP reply...
91 */
92 clientdbUpdate(from.sin_addr, LOG_UDP_DENIED, PROTO_ICP, 0);
93 } else {
94 reply = icpCreateMessage(ICP_DENIED, 0, url, header.reqnum, 0);
95 icpUdpSend(fd, &from, reply, LOG_UDP_DENIED, 0);
96 }
97 break;
98 }
99 /* The peer is allowed to use this cache */
100 entry = storeGetPublic(url, METHOD_GET);
101 debug(12, 5) ("icpHandleIcpV3: OPCODE %s\n",
102 icp_opcode_str[header.opcode]);
103 if (icpCheckUdpHit(entry, icp_request)) {
104 reply = icpCreateMessage(ICP_HIT, 0, url, header.reqnum, 0);
105 icpUdpSend(fd, &from, reply, LOG_UDP_HIT, 0);
106 break;
107 }
108 /* if store is rebuilding, return a UDP_HIT, but not a MISS */
109 if (opt_reload_hit_only && store_dirs_rebuilding) {
110 reply = icpCreateMessage(ICP_MISS_NOFETCH, 0, url, header.reqnum, 0);
111 icpUdpSend(fd, &from, reply, LOG_UDP_MISS_NOFETCH, 0);
112 } else if (hit_only_mode_until > squid_curtime) {
113 reply = icpCreateMessage(ICP_MISS_NOFETCH, 0, url, header.reqnum, 0);
114 icpUdpSend(fd, &from, reply, LOG_UDP_MISS_NOFETCH, 0);
115 } else {
116 reply = icpCreateMessage(ICP_MISS, 0, url, header.reqnum, 0);
117 icpUdpSend(fd, &from, reply, LOG_UDP_MISS, 0);
118 }
119 break;
120
121 case ICP_HIT:
122 #if ALLOW_SOURCE_PING
123 case ICP_SECHO:
124 #endif
125 case ICP_DECHO:
126 case ICP_MISS:
127 case ICP_DENIED:
128 case ICP_MISS_NOFETCH:
129 if (neighbors_do_private_keys && header.reqnum == 0) {
130 debug(12, 0) ("icpHandleIcpV3: Neighbor %s returned reqnum = 0\n",
131 inet_ntoa(from.sin_addr));
132 debug(12, 0) ("icpHandleIcpV3: Disabling use of private keys\n");
133 neighbors_do_private_keys = 0;
134 }
135 url = buf + sizeof(icp_common_t);
136 debug(12, 3) ("icpHandleIcpV3: %s from %s for '%s'\n",
137 icp_opcode_str[header.opcode],
138 inet_ntoa(from.sin_addr),
139 url);
140 key = icpGetCacheKey(url, (int) header.reqnum);
141 /* call neighborsUdpAck even if ping_status != PING_WAITING */
142 neighborsUdpAck(key, &header, &from);
143 break;
144
145 case ICP_INVALID:
146 case ICP_ERR:
147 break;
148
149 default:
150 debug(12, 0) ("icpHandleIcpV3: UNKNOWN OPCODE: %d from %s\n",
151 header.opcode, inet_ntoa(from.sin_addr));
152 break;
153 }
154 if (icp_request)
155 requestDestroy(icp_request);
156 }