3 * $Id: icp_v3.cc,v 1.30 1999/06/14 03:02:07 wessels Exp $
5 * DEBUG: section 12 Internet Cache Protocol
6 * AUTHOR: Duane Wessels
8 * SQUID Internet Object Cache http://squid.nlanr.net/Squid/
9 * ----------------------------------------------------------
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.
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.
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.
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.
38 /* Currently Harvest cached-2.x uses ICP_VERSION_3 */
40 icpHandleIcpV3(int fd
, struct sockaddr_in from
, char *buf
, int len
)
44 StoreEntry
*entry
= NULL
;
47 request_t
*icp_request
= NULL
;
50 xmemcpy(&header
, buf
, sizeof(icp_common_t
));
52 * Only these fields need to be converted
54 header
.length
= ntohs(header
.length
);
55 header
.reqnum
= ntohl(header
.reqnum
);
56 header
.flags
= ntohl(header
.flags
);
57 header
.pad
= ntohl(header
.pad
);
59 * Length field should match the number of bytes read
61 if (len
!= header
.length
) {
62 debug(12, 3) ("icpHandleIcpV3: ICP message is too small\n");
65 switch (header
.opcode
) {
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);
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);
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
);
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
)) {
89 * count this DENIED query in the clientdb, even though
90 * we're not sending an ICP reply...
92 clientdbUpdate(from
.sin_addr
, LOG_UDP_DENIED
, PROTO_ICP
, 0);
94 reply
= icpCreateMessage(ICP_DENIED
, 0, url
, header
.reqnum
, 0);
95 icpUdpSend(fd
, &from
, reply
, LOG_UDP_DENIED
, 0);
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);
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);
116 reply
= icpCreateMessage(ICP_MISS
, 0, url
, header
.reqnum
, 0);
117 icpUdpSend(fd
, &from
, reply
, LOG_UDP_MISS
, 0);
122 #if ALLOW_SOURCE_PING
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;
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
),
140 key
= icpGetCacheKey(url
, (int) header
.reqnum
);
141 /* call neighborsUdpAck even if ping_status != PING_WAITING */
142 neighborsUdpAck(key
, &header
, &from
);
150 debug(12, 0) ("icpHandleIcpV3: UNKNOWN OPCODE: %d from %s\n",
151 header
.opcode
, inet_ntoa(from
.sin_addr
));
155 requestDestroy(icp_request
);