3 * $Id: icp_v3.cc,v 1.26 1998/09/21 06:52:16 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 switch (header
.opcode
) {
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);
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);
74 checklist
.src_addr
= from
.sin_addr
;
75 checklist
.request
= icp_request
;
76 allow
= aclCheckFast(Config
.accessList
.icp
, &checklist
);
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
)) {
82 * count this DENIED query in the clientdb, even though
83 * we're not sending an ICP reply...
85 clientdbUpdate(from
.sin_addr
, LOG_UDP_DENIED
, PROTO_ICP
, 0);
87 reply
= icpCreateMessage(ICP_DENIED
, 0, url
, header
.reqnum
, 0);
88 icpUdpSend(fd
, &from
, reply
, LOG_UDP_DENIED
, 0);
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);
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);
109 reply
= icpCreateMessage(ICP_MISS
, 0, url
, header
.reqnum
, 0);
110 icpUdpSend(fd
, &from
, reply
, LOG_UDP_MISS
, 0);
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;
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
),
131 key
= icpGetCacheKey(url
, (int) header
.reqnum
);
132 /* call neighborsUdpAck even if ping_status != PING_WAITING */
133 neighborsUdpAck(key
, &header
, &from
);
141 debug(12, 0) ("icpHandleIcpV3: UNKNOWN OPCODE: %d from %s\n",
142 header
.opcode
, inet_ntoa(from
.sin_addr
));
146 requestDestroy(icp_request
);