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