]> git.ipfire.org Git - thirdparty/squid.git/blob - src/DelayId.cc
SourceFormat Enforcement
[thirdparty/squid.git] / src / DelayId.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 77 Delay Pools */
10
11 #include "squid.h"
12
13 /* MS Visual Studio Projects are monolithic, so we need the following
14 * #if to exclude the delay pools code from compile process when not needed.
15 */
16 #if USE_DELAY_POOLS
17 #include "acl/FilledChecklist.h"
18 #include "client_side_request.h"
19 #include "CommRead.h"
20 #include "DelayId.h"
21 #include "DelayPool.h"
22 #include "DelayPools.h"
23 #include "HttpRequest.h"
24 #include "SquidConfig.h"
25
26 DelayId::DelayId () : pool_ (0), compositeId(NULL), markedAsNoDelay(false)
27 {}
28
29 DelayId::DelayId (unsigned short aPool) :
30 pool_ (aPool), compositeId (NULL), markedAsNoDelay (false)
31 {
32 debugs(77, 3, "DelayId::DelayId: Pool " << aPool << "u");
33 }
34
35 DelayId::~DelayId ()
36 {}
37
38 void
39 DelayId::compositePosition(DelayIdComposite::Pointer newPosition)
40 {
41 compositeId = newPosition;
42 }
43
44 unsigned short
45 DelayId::pool() const
46 {
47 return pool_;
48 }
49
50 bool
51 DelayId::operator == (DelayId const &rhs) const
52 {
53 /* Doesn't compare composites properly....
54 * only use to test against default ID's
55 */
56 return pool_ == rhs.pool_ && compositeId == rhs.compositeId;
57 }
58
59 DelayId::operator bool() const
60 {
61 return pool_ || compositeId.getRaw();
62 }
63
64 /* create a delay Id for a given request */
65 DelayId
66 DelayId::DelayClient(ClientHttpRequest * http, HttpReply *reply)
67 {
68 HttpRequest *r;
69 unsigned short pool;
70 assert(http);
71 r = http->request;
72
73 if (r->client_addr.isNoAddr()) {
74 debugs(77, 2, "delayClient: WARNING: Called with 'NO_ADDR' address, ignoring");
75 return DelayId();
76 }
77
78 for (pool = 0; pool < DelayPools::pools(); ++pool) {
79
80 /* pools require explicit 'allow' to assign a client into them */
81 if (!DelayPools::delay_data[pool].access) {
82 debugs(77, DBG_IMPORTANT, "delay_pool " << pool <<
83 " has no delay_access configured. This means that no clients will ever use it.");
84 continue;
85 }
86
87 ACLFilledChecklist ch(DelayPools::delay_data[pool].access, r, NULL);
88 if (reply) {
89 ch.reply = reply;
90 HTTPMSGLOCK(reply);
91 }
92 #if FOLLOW_X_FORWARDED_FOR
93 if (Config.onoff.delay_pool_uses_indirect_client)
94 ch.src_addr = r->indirect_client_addr;
95 else
96 #endif /* FOLLOW_X_FORWARDED_FOR */
97 ch.src_addr = r->client_addr;
98 ch.my_addr = r->my_addr;
99
100 if (http->getConn() != NULL)
101 ch.conn(http->getConn());
102
103 if (DelayPools::delay_data[pool].theComposite().getRaw() && ch.fastCheck() == ACCESS_ALLOWED) {
104
105 DelayId result (pool + 1);
106 CompositePoolNode::CompositeSelectionDetails details;
107 details.src_addr = ch.src_addr;
108 #if USE_AUTH
109 details.user = r->auth_user_request;
110 #endif
111 details.tag = r->tag;
112 result.compositePosition(DelayPools::delay_data[pool].theComposite()->id(details));
113 return result;
114 }
115 }
116
117 return DelayId();
118 }
119
120 void
121 DelayId::setNoDelay(bool const newValue)
122 {
123 markedAsNoDelay = newValue;
124 }
125
126 /*
127 * this returns the number of bytes the client is permitted. it does not take
128 * into account bytes already buffered - that is up to the caller.
129 */
130 int
131 DelayId::bytesWanted(int minimum, int maximum) const
132 {
133 /* unlimited */
134
135 if (! (*this) || markedAsNoDelay)
136 return max(minimum, maximum);
137
138 /* limited */
139 int nbytes = max(minimum, maximum);
140
141 if (compositeId != NULL)
142 nbytes = compositeId->bytesWanted(minimum, nbytes);
143
144 return nbytes;
145 }
146
147 /*
148 * this records actual bytes received. always recorded, even if the
149 * class is disabled - it's more efficient to just do it than to do all
150 * the checks.
151 */
152 void
153 DelayId::bytesIn(int qty)
154 {
155 if (! (*this))
156 return;
157
158 if (markedAsNoDelay)
159 return;
160
161 assert ((unsigned short)(pool() - 1) != 0xFFFF);
162
163 if (compositeId != NULL)
164 compositeId->bytesIn(qty);
165 }
166
167 void
168 DelayId::delayRead(DeferredRead const &aRead)
169 {
170 assert (compositeId != NULL);
171 compositeId->delayRead(aRead);
172
173 }
174
175 #endif /* USE_DELAY_POOLS */
176