]> git.ipfire.org Git - thirdparty/squid.git/blob - src/icp_v3.cc
New averaging counter stuff
[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 icp_common_t *headerp = (icp_common_t *) (void *) buf;
10 StoreEntry *entry = NULL;
11 char *url = NULL;
12 const cache_key *key;
13 request_t *icp_request = NULL;
14 int allow = 0;
15 char *data = NULL;
16 u_short data_sz = 0;
17 u_short u;
18 aclCheck_t checklist;
19
20 header.opcode = headerp->opcode;
21 header.version = headerp->version;
22 header.length = ntohs(headerp->length);
23 header.reqnum = ntohl(headerp->reqnum);
24 header.flags = ntohl(headerp->flags);
25 header.shostid = ntohl(headerp->shostid);
26
27 switch (header.opcode) {
28 case ICP_OP_QUERY:
29 /* We have a valid packet */
30 url = buf + sizeof(header) + sizeof(u_num32);
31 if ((icp_request = urlParse(METHOD_GET, url)) == NULL) {
32 reply = icpCreateMessage(ICP_OP_ERR, 0, url, header.reqnum, 0);
33 icpUdpSend(fd, &from, reply, LOG_UDP_INVALID, PROTO_NONE);
34 break;
35 }
36 checklist.src_addr = from.sin_addr;
37 checklist.request = icp_request;
38 allow = aclCheckFast(Config.accessList.icp, &checklist);
39 if (!allow) {
40 debug(12, 2) ("icpHandleIcpV3: Access Denied for %s by %s.\n",
41 inet_ntoa(from.sin_addr), AclMatchedName);
42 if (clientdbDeniedPercent(from.sin_addr) < 95) {
43 reply = icpCreateMessage(ICP_OP_DENIED, 0, url, header.reqnum, 0);
44 icpUdpSend(fd, &from, reply, LOG_UDP_DENIED, icp_request->protocol);
45 }
46 break;
47 }
48 /* The peer is allowed to use this cache */
49 key = storeKeyPublic(url, METHOD_GET);
50 entry = storeGet(key);
51 debug(12, 5) ("icpHandleIcpV3: OPCODE %s\n",
52 IcpOpcodeStr[header.opcode]);
53 if (icpCheckUdpHit(entry, icp_request)) {
54 reply = icpCreateMessage(ICP_OP_HIT, 0, url, header.reqnum, 0);
55 icpUdpSend(fd, &from, reply, LOG_UDP_HIT, icp_request->protocol);
56 break;
57 }
58 /* if store is rebuilding, return a UDP_HIT, but not a MISS */
59 if (opt_reload_hit_only && store_rebuilding) {
60 reply = icpCreateMessage(ICP_OP_MISS_NOFETCH, 0, url, header.reqnum, 0);
61 icpUdpSend(fd, &from, reply, LOG_UDP_MISS_NOFETCH, icp_request->protocol);
62 } else if (hit_only_mode_until > squid_curtime) {
63 reply = icpCreateMessage(ICP_OP_MISS_NOFETCH, 0, url, header.reqnum, 0);
64 icpUdpSend(fd, &from, reply, LOG_UDP_MISS_NOFETCH, icp_request->protocol);
65 } else {
66 reply = icpCreateMessage(ICP_OP_MISS, 0, url, header.reqnum, 0);
67 icpUdpSend(fd, &from, reply, LOG_UDP_MISS, icp_request->protocol);
68 }
69 break;
70
71 case ICP_OP_HIT_OBJ:
72 case ICP_OP_HIT:
73 case ICP_OP_SECHO:
74 case ICP_OP_DECHO:
75 case ICP_OP_MISS:
76 case ICP_OP_DENIED:
77 case ICP_OP_MISS_NOFETCH:
78 if (neighbors_do_private_keys && header.reqnum == 0) {
79 debug(12, 0) ("icpHandleIcpV3: Neighbor %s returned reqnum = 0\n",
80 inet_ntoa(from.sin_addr));
81 debug(12, 0) ("icpHandleIcpV3: Disabling use of private keys\n");
82 neighbors_do_private_keys = 0;
83 }
84 url = buf + sizeof(header);
85 if (header.opcode == ICP_OP_HIT_OBJ) {
86 data = url + strlen(url) + 1;
87 xmemcpy((char *) &u, data, sizeof(u_short));
88 data += sizeof(u_short);
89 data_sz = ntohs(u);
90 if ((int) data_sz > (len - (data - buf))) {
91 debug(12, 0) ("icpHandleIcpV3: ICP_OP_HIT_OBJ object too small\n");
92 break;
93 }
94 }
95 debug(12, 3) ("icpHandleIcpV3: %s from %s for '%s'\n",
96 IcpOpcodeStr[header.opcode],
97 inet_ntoa(from.sin_addr),
98 url);
99 if (neighbors_do_private_keys && header.reqnum)
100 key = storeKeyPrivate(url, METHOD_GET, header.reqnum);
101 else
102 key = storeKeyPublic(url, METHOD_GET);
103 debug(12, 3) ("icpHandleIcpV3: Looking for key '%s'\n",
104 storeKeyText(key));
105 if ((entry = storeGet(key)) == NULL) {
106 debug(12, 3) ("icpHandleIcpV3: Ignoring %s for NULL Entry.\n",
107 IcpOpcodeStr[header.opcode]);
108 } else {
109 /* call neighborsUdpAck even if ping_status != PING_WAITING */
110 neighborsUdpAck(url, &header, &from, entry);
111 }
112 break;
113
114 case ICP_OP_INVALID:
115 case ICP_OP_ERR:
116 break;
117
118 default:
119 debug(12, 0) ("icpHandleIcpV3: UNKNOWN OPCODE: %d from %s\n",
120 header.opcode, inet_ntoa(from.sin_addr));
121 break;
122 }
123 if (icp_request)
124 put_free_request_t(icp_request);
125 }