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