]> git.ipfire.org Git - thirdparty/squid.git/blob - src/icp_v3.cc
Casting and alignment fixes
[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 xmemcpy(&header, buf, sizeof(icp_common_t));
16 /*
17 * Only these fields need to be converted
18 */
19 header.length = ntohs(header.length);
20 header.reqnum = ntohl(header.reqnum);
21 header.flags = ntohl(header.flags);
22 header.pad = ntohl(header.pad);
23
24 switch (header.opcode) {
25 case ICP_QUERY:
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);
31 break;
32 }
33 checklist.src_addr = from.sin_addr;
34 checklist.request = icp_request;
35 allow = aclCheckFast(Config.accessList.icp, &checklist);
36 if (!allow) {
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);
42 } else {
43 /*
44 * count this DENIED query in the clientdb, even though
45 * we're not sending an ICP reply...
46 */
47 clientdbUpdate(from.sin_addr,
48 LOG_UDP_DENIED,
49 Config.Port.icp);
50 }
51 break;
52 }
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);
61 break;
62 }
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);
70 } else {
71 reply = icpCreateMessage(ICP_MISS, 0, url, header.reqnum, 0);
72 icpUdpSend(fd, &from, reply, LOG_UDP_MISS, icp_request->protocol);
73 }
74 break;
75
76 case ICP_HIT:
77 case ICP_SECHO:
78 case ICP_DECHO:
79 case ICP_MISS:
80 case ICP_DENIED:
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;
87 }
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),
92 url);
93 if (neighbors_do_private_keys && header.reqnum)
94 key = storeKeyPrivate(url, METHOD_GET, header.reqnum);
95 else
96 key = storeKeyPublic(url, METHOD_GET);
97 debug(12, 3) ("icpHandleIcpV3: Looking for key '%s'\n",
98 storeKeyText(key));
99 if ((entry = storeGet(key)) == NULL) {
100 debug(12, 3) ("icpHandleIcpV3: Ignoring %s for NULL Entry.\n",
101 icp_opcode_str[header.opcode]);
102 } else {
103 /* call neighborsUdpAck even if ping_status != PING_WAITING */
104 neighborsUdpAck(url, &header, &from, entry);
105 }
106 break;
107
108 case ICP_INVALID:
109 case ICP_ERR:
110 break;
111
112 default:
113 debug(12, 0) ("icpHandleIcpV3: UNKNOWN OPCODE: %d from %s\n",
114 header.opcode, inet_ntoa(from.sin_addr));
115 break;
116 }
117 if (icp_request)
118 memFree(MEM_REQUEST_T, icp_request);
119 }