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
;
15 xmemcpy(&header
, buf
, sizeof(icp_common_t
));
17 * Only these fields need to be converted
19 header
.length
= ntohs(header
.length
);
20 header
.reqnum
= ntohl(header
.reqnum
);
21 header
.flags
= ntohl(header
.flags
);
22 header
.pad
= ntohl(header
.pad
);
24 switch (header
.opcode
) {
26 /* We have a valid packet */
27 url
= buf
+ sizeof(icp_common_t
) + sizeof(u_num32
);
28 if ((icp_request
= urlParse(METHOD_GET
, url
)) == NULL
) {
29 reply
= icpCreateMessage(ICP_ERR
, 0, url
, header
.reqnum
, 0);
30 icpUdpSend(fd
, &from
, reply
, LOG_UDP_INVALID
, PROTO_NONE
);
33 checklist
.src_addr
= from
.sin_addr
;
34 checklist
.request
= icp_request
;
35 allow
= aclCheckFast(Config
.accessList
.icp
, &checklist
);
37 debug(12, 2) ("icpHandleIcpV3: Access Denied for %s by %s.\n",
38 inet_ntoa(from
.sin_addr
), AclMatchedName
);
39 if (clientdbDeniedPercent(from
.sin_addr
) < 95) {
40 reply
= icpCreateMessage(ICP_DENIED
, 0, url
, header
.reqnum
, 0);
41 icpUdpSend(fd
, &from
, reply
, LOG_UDP_DENIED
, icp_request
->protocol
);
44 * count this DENIED query in the clientdb, even though
45 * we're not sending an ICP reply...
47 clientdbUpdate(from
.sin_addr
,
53 /* The peer is allowed to use this cache */
54 key
= storeKeyPublic(url
, METHOD_GET
);
55 entry
= storeGet(key
);
56 debug(12, 5) ("icpHandleIcpV3: OPCODE %s\n",
57 icp_opcode_str
[header
.opcode
]);
58 if (icpCheckUdpHit(entry
, icp_request
)) {
59 reply
= icpCreateMessage(ICP_HIT
, 0, url
, header
.reqnum
, 0);
60 icpUdpSend(fd
, &from
, reply
, LOG_UDP_HIT
, icp_request
->protocol
);
63 /* if store is rebuilding, return a UDP_HIT, but not a MISS */
64 if (opt_reload_hit_only
&& store_rebuilding
) {
65 reply
= icpCreateMessage(ICP_MISS_NOFETCH
, 0, url
, header
.reqnum
, 0);
66 icpUdpSend(fd
, &from
, reply
, LOG_UDP_MISS_NOFETCH
, icp_request
->protocol
);
67 } else if (hit_only_mode_until
> squid_curtime
) {
68 reply
= icpCreateMessage(ICP_MISS_NOFETCH
, 0, url
, header
.reqnum
, 0);
69 icpUdpSend(fd
, &from
, reply
, LOG_UDP_MISS_NOFETCH
, icp_request
->protocol
);
71 reply
= icpCreateMessage(ICP_MISS
, 0, url
, header
.reqnum
, 0);
72 icpUdpSend(fd
, &from
, reply
, LOG_UDP_MISS
, icp_request
->protocol
);
81 case ICP_MISS_NOFETCH
:
82 if (neighbors_do_private_keys
&& header
.reqnum
== 0) {
83 debug(12, 0) ("icpHandleIcpV3: Neighbor %s returned reqnum = 0\n",
84 inet_ntoa(from
.sin_addr
));
85 debug(12, 0) ("icpHandleIcpV3: Disabling use of private keys\n");
86 neighbors_do_private_keys
= 0;
88 url
= buf
+ sizeof(icp_common_t
);
89 debug(12, 3) ("icpHandleIcpV3: %s from %s for '%s'\n",
90 icp_opcode_str
[header
.opcode
],
91 inet_ntoa(from
.sin_addr
),
93 if (neighbors_do_private_keys
&& header
.reqnum
)
94 key
= storeKeyPrivate(url
, METHOD_GET
, header
.reqnum
);
96 key
= storeKeyPublic(url
, METHOD_GET
);
97 debug(12, 3) ("icpHandleIcpV3: Looking for key '%s'\n",
99 if ((entry
= storeGet(key
)) == NULL
) {
100 debug(12, 3) ("icpHandleIcpV3: Ignoring %s for NULL Entry.\n",
101 icp_opcode_str
[header
.opcode
]);
103 /* call neighborsUdpAck even if ping_status != PING_WAITING */
104 neighborsUdpAck(url
, &header
, &from
, entry
);
113 debug(12, 0) ("icpHandleIcpV3: UNKNOWN OPCODE: %d from %s\n",
114 header
.opcode
, inet_ntoa(from
.sin_addr
));
118 memFree(MEM_REQUEST_T
, icp_request
);