]> git.ipfire.org Git - thirdparty/squid.git/blob - src/icp_v3.cc
bdaf1a63297e8973c7c52d026de00ffe860a3dfa
[thirdparty/squid.git] / src / icp_v3.cc
1 /*
2 * Copyright (C) 1996-2016 The Squid Software Foundation and contributors
3 *
4 * Squid software is distributed under GPLv2+ license and includes
5 * contributions from numerous individuals and organizations.
6 * Please see the COPYING and CONTRIBUTORS files for details.
7 */
8
9 /* DEBUG: section 12 Internet Cache Protocol (ICP) */
10
11 /**
12 \defgroup ServerProtocolICPInternal3 ICPv3 Internals
13 \ingroup ServerProtocolICPAPI
14 */
15
16 #include "squid.h"
17 #include "HttpRequest.h"
18 #include "ICP.h"
19 #include "Store.h"
20
21 /// \ingroup ServerProtocolICPInternal3
22 class ICP3State : public ICPState, public StoreClient
23 {
24
25 public:
26 ICP3State(icp_common_t &aHeader, HttpRequest *aRequest) :
27 ICPState(aHeader, aRequest) {}
28
29 ~ICP3State();
30 void created (StoreEntry *newEntry);
31 };
32
33 /// \ingroup ServerProtocolICPInternal3
34 static void
35 doV3Query(int fd, Ip::Address &from, char *buf, icp_common_t header)
36 {
37 /* We have a valid packet */
38 char *url = buf + sizeof(icp_common_t) + sizeof(uint32_t);
39 HttpRequest *icp_request = icpGetRequest(url, header.reqnum, fd, from);
40
41 if (!icp_request)
42 return;
43
44 if (!icpAccessAllowed(from, icp_request)) {
45 icpDenyAccess (from, url, header.reqnum, fd);
46 delete icp_request;
47 return;
48 }
49
50 /* The peer is allowed to use this cache */
51 ICP3State *state = new ICP3State (header, icp_request);
52 state->fd = fd;
53 state->from = from;
54 state->url = xstrdup(url);
55
56 StoreEntry::getPublic (state, url, Http::METHOD_GET);
57 }
58
59 ICP3State::~ICP3State()
60 {}
61
62 void
63 ICP3State::created(StoreEntry *newEntry)
64 {
65 StoreEntry *entry = newEntry->isNull () ? NULL : newEntry;
66 debugs(12, 5, "icpHandleIcpV3: OPCODE " << icp_opcode_str[header.opcode]);
67 icp_opcode codeToSend;
68
69 if (icpCheckUdpHit(entry, request)) {
70 codeToSend = ICP_HIT;
71 } else if (icpGetCommonOpcode() == ICP_ERR)
72 codeToSend = ICP_MISS;
73 else
74 codeToSend = icpGetCommonOpcode();
75
76 icpCreateAndSend (codeToSend, 0, url, header.reqnum, 0, fd, from);
77
78 delete this;
79 }
80
81 /// \ingroup ServerProtocolICPInternal3
82 /* Currently Harvest cached-2.x uses ICP_VERSION_3 */
83 void
84 icpHandleIcpV3(int fd, Ip::Address &from, char *buf, int len)
85 {
86 if (len <= 0) {
87 debugs(12, 3, "icpHandleIcpV3: ICP message is too small");
88 return;
89 }
90
91 icp_common_t header (buf, len);
92 /*
93 * Length field should match the number of bytes read
94 */
95
96 if (len != header.length) {
97 debugs(12, 3, "icpHandleIcpV3: ICP message is too small");
98 return;
99 }
100
101 switch (header.opcode) {
102
103 case ICP_QUERY:
104 doV3Query(fd, from, buf, header);
105 break;
106
107 case ICP_HIT:
108
109 case ICP_DECHO:
110
111 case ICP_MISS:
112
113 case ICP_DENIED:
114
115 case ICP_MISS_NOFETCH:
116 header.handleReply(buf, from);
117 break;
118
119 case ICP_INVALID:
120
121 case ICP_ERR:
122 break;
123
124 default:
125 debugs(12, DBG_CRITICAL, "icpHandleIcpV3: UNKNOWN OPCODE: " << header.opcode << " from " << from);
126 break;
127 }
128 }
129