]> git.ipfire.org Git - thirdparty/squid.git/blob - src/icp_v3.cc
gindent
[thirdparty/squid.git] / src / icp_v3.cc
1 #include "squid.h"
2
3 /* Currently Harvest cached-2.x uses ICP_VERSION_3 */
4 void
5 icpHandleIcpV3(int fd, struct sockaddr_in from, char *buf, int len)
6 {
7 icp_common_t header;
8 icp_common_t *reply;
9 StoreEntry *entry = NULL;
10 char *url = NULL;
11 const cache_key *key;
12 request_t *icp_request = NULL;
13 int allow = 0;
14 aclCheck_t checklist;
15 method_t method;
16 xmemcpy(&header, buf, sizeof(icp_common_t));
17 /*
18 * Only these fields need to be converted
19 */
20 header.length = ntohs(header.length);
21 header.reqnum = ntohl(header.reqnum);
22 header.flags = ntohl(header.flags);
23 header.pad = ntohl(header.pad);
24
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)
28 method = METHOD_GET;
29 switch (header.opcode) {
30 case ICP_QUERY:
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);
36 break;
37 }
38 checklist.src_addr = from.sin_addr;
39 checklist.request = icp_request;
40 allow = aclCheckFast(Config.accessList.icp, &checklist);
41 if (!allow) {
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)) {
45 /*
46 * count this DENIED query in the clientdb, even though
47 * we're not sending an ICP reply...
48 */
49 clientdbUpdate(from.sin_addr, LOG_UDP_DENIED, Config.Port.icp, 0);
50 } else {
51 reply = icpCreateMessage(ICP_DENIED, 0, url, header.reqnum, 0);
52 icpUdpSend(fd, &from, reply, LOG_UDP_DENIED, icp_request->protocol);
53 }
54 break;
55 }
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);
64 break;
65 }
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);
73 } else {
74 reply = icpCreateMessage(ICP_MISS, 0, url, header.reqnum, 0);
75 icpUdpSend(fd, &from, reply, LOG_UDP_MISS, icp_request->protocol);
76 }
77 break;
78
79 case ICP_HIT:
80 case ICP_SECHO:
81 case ICP_DECHO:
82 case ICP_MISS:
83 case ICP_DENIED:
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;
90 }
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),
95 url);
96 if (neighbors_do_private_keys && header.reqnum)
97 key = storeKeyPrivate(url, method, header.reqnum);
98 else
99 key = storeKeyPublic(url, method);
100 /* call neighborsUdpAck even if ping_status != PING_WAITING */
101 neighborsUdpAck(key, &header, &from);
102 break;
103
104 case ICP_INVALID:
105 case ICP_ERR:
106 break;
107
108 default:
109 debug(12, 0) ("icpHandleIcpV3: UNKNOWN OPCODE: %d from %s\n",
110 header.opcode, inet_ntoa(from.sin_addr));
111 break;
112 }
113 if (icp_request) {
114 stringClean(&icp_request->urlpath);
115 memFree(MEM_REQUEST_T, icp_request);
116 }
117 }