3 /* Currently Harvest cached-2.x uses ICP_VERSION_3 */
5 icpHandleIcpV3(int fd
, struct sockaddr_in from
, char *buf
, int len
)
9 StoreEntry
*entry
= NULL
;
12 request_t
*icp_request
= NULL
;
16 xmemcpy(&header
, buf
, sizeof(icp_common_t
));
18 * Only these fields need to be converted
20 header
.length
= ntohs(header
.length
);
21 header
.reqnum
= ntohl(header
.reqnum
);
22 header
.flags
= ntohl(header
.flags
);
23 header
.pad
= ntohl(header
.pad
);
25 method
= header
.reqnum
>> 24;
26 /* Squid-1.1 doesn't use the "method bits" for METHOD_GET */
27 if (METHOD_NONE
== method
|| METHOD_ENUM_END
<= method
)
29 switch (header
.opcode
) {
31 /* We have a valid packet */
32 url
= buf
+ sizeof(icp_common_t
) + sizeof(u_num32
);
33 if ((icp_request
= urlParse(method
, url
)) == NULL
) {
34 reply
= icpCreateMessage(ICP_ERR
, 0, url
, header
.reqnum
, 0);
35 icpUdpSend(fd
, &from
, reply
, LOG_UDP_INVALID
, PROTO_NONE
);
38 checklist
.src_addr
= from
.sin_addr
;
39 checklist
.request
= icp_request
;
40 allow
= aclCheckFast(Config
.accessList
.icp
, &checklist
);
42 debug(12, 2) ("icpHandleIcpV3: Access Denied for %s by %s.\n",
43 inet_ntoa(from
.sin_addr
), AclMatchedName
);
44 if (clientdbCutoffDenied(from
.sin_addr
)) {
46 * count this DENIED query in the clientdb, even though
47 * we're not sending an ICP reply...
49 clientdbUpdate(from
.sin_addr
, LOG_UDP_DENIED
, Config
.Port
.icp
, 0);
51 reply
= icpCreateMessage(ICP_DENIED
, 0, url
, header
.reqnum
, 0);
52 icpUdpSend(fd
, &from
, reply
, LOG_UDP_DENIED
, icp_request
->protocol
);
56 /* The peer is allowed to use this cache */
57 key
= storeKeyPublic(url
, method
);
58 entry
= storeGet(key
);
59 debug(12, 5) ("icpHandleIcpV3: OPCODE %s\n",
60 icp_opcode_str
[header
.opcode
]);
61 if (icpCheckUdpHit(entry
, icp_request
)) {
62 reply
= icpCreateMessage(ICP_HIT
, 0, url
, header
.reqnum
, 0);
63 icpUdpSend(fd
, &from
, reply
, LOG_UDP_HIT
, icp_request
->protocol
);
66 /* if store is rebuilding, return a UDP_HIT, but not a MISS */
67 if (opt_reload_hit_only
&& store_rebuilding
) {
68 reply
= icpCreateMessage(ICP_MISS_NOFETCH
, 0, url
, header
.reqnum
, 0);
69 icpUdpSend(fd
, &from
, reply
, LOG_UDP_MISS_NOFETCH
, icp_request
->protocol
);
70 } else if (hit_only_mode_until
> squid_curtime
) {
71 reply
= icpCreateMessage(ICP_MISS_NOFETCH
, 0, url
, header
.reqnum
, 0);
72 icpUdpSend(fd
, &from
, reply
, LOG_UDP_MISS_NOFETCH
, icp_request
->protocol
);
74 reply
= icpCreateMessage(ICP_MISS
, 0, url
, header
.reqnum
, 0);
75 icpUdpSend(fd
, &from
, reply
, LOG_UDP_MISS
, icp_request
->protocol
);
84 case ICP_MISS_NOFETCH
:
85 if (neighbors_do_private_keys
&& header
.reqnum
== 0) {
86 debug(12, 0) ("icpHandleIcpV3: Neighbor %s returned reqnum = 0\n",
87 inet_ntoa(from
.sin_addr
));
88 debug(12, 0) ("icpHandleIcpV3: Disabling use of private keys\n");
89 neighbors_do_private_keys
= 0;
91 url
= buf
+ sizeof(icp_common_t
);
92 debug(12, 3) ("icpHandleIcpV3: %s from %s for '%s'\n",
93 icp_opcode_str
[header
.opcode
],
94 inet_ntoa(from
.sin_addr
),
96 if (neighbors_do_private_keys
&& header
.reqnum
)
97 key
= storeKeyPrivate(url
, method
, header
.reqnum
);
99 key
= storeKeyPublic(url
, method
);
100 /* call neighborsUdpAck even if ping_status != PING_WAITING */
101 neighborsUdpAck(key
, &header
, &from
);
109 debug(12, 0) ("icpHandleIcpV3: UNKNOWN OPCODE: %d from %s\n",
110 header
.opcode
, inet_ntoa(from
.sin_addr
));
114 stringClean(&icp_request
->urlpath
);
115 memFree(MEM_REQUEST_T
, icp_request
);