]>
git.ipfire.org Git - thirdparty/squid.git/blob - src/delay_pools.cc
3 * $Id: delay_pools.cc,v 1.2 1998/08/14 09:22:34 wessels Exp $
5 * DEBUG: section 77 Delay Pools
6 * AUTHOR: David Luyer <luyer@ucs.uwa.edu.au>
8 * SQUID Internet Object Cache http://squid.nlanr.net/Squid/
9 * ----------------------------------------------------------
11 * Squid is the result of efforts by numerous individuals from the
12 * Internet community. Development is led by Duane Wessels of the
13 * National Laboratory for Applied Network Research and funded by the
14 * National Science Foundation. Squid is Copyrighted (C) 1998 by
15 * Duane Wessels and the University of California San Diego. Please
16 * see the COPYRIGHT file for full details. Squid incorporates
17 * software developed and/or copyrighted by other sources. Please see
18 * the CREDITS file for full details.
20 * This program is free software; you can redistribute it and/or modify
21 * it under the terms of the GNU General Public License as published by
22 * the Free Software Foundation; either version 2 of the License, or
23 * (at your option) any later version.
25 * This program is distributed in the hope that it will be useful,
26 * but WITHOUT ANY WARRANTY; without even the implied warranty of
27 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
28 * GNU General Public License for more details.
30 * You should have received a copy of the GNU General Public License
31 * along with this program; if not, write to the Free Software
32 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111, USA.
45 /* 254 entries + 1 terminator byte */
46 unsigned char class2_individual_map
[255];
48 int class2_individual
[254];
50 /* 255 entries + 1 terminator byte */
51 unsigned char class3_network_map
[256];
53 int class3_network
[255];
54 /* 255 sets of (254 entries + 1 terminator byte) */
55 unsigned char class3_individual_map
[255][255];
56 /* largest entry = (254<<8)+253 = 65277 */
57 int class3_individual
[65278];
60 static struct _delayData delay_data
;
61 static OBJH delayPoolStats
;
62 static delay_id
delayId(unsigned char class, int position
);
65 delayId(unsigned char class, int position
)
68 return (class << 16) | (position
& 0xFFFF);
72 delayClient(clientHttpRequest
* http
)
78 unsigned char class = 0;
80 request_t
*r
= http
->request
;
82 memset(&ch
, '\0', sizeof(ch
));
83 ch
.src_addr
= http
->conn
->peer
.sin_addr
;
85 if (aclCheckFast(Config
.Delay
.class1
.access
, &ch
)) {
87 r
->delay_id
= delayId(class, position
);
90 if (aclCheckFast(Config
.Delay
.class2
.access
, &ch
)) {
92 host
= ntohl(ch
.src_addr
.s_addr
) & 0xff;
93 if (host
== 255 || !host
) {
94 debug(77, 0) ("ARGH: Delay requested for host %s\n", inet_ntoa(ch
.src_addr
));
96 r
->delay_id
= delayId(class, position
);
100 if (delay_data
.class2_individual_map
[i
] == host
)
102 if (delay_data
.class2_individual_map
[i
] == 255) {
103 delay_data
.class2_individual_map
[i
] = host
;
104 delay_data
.class2_individual_map
[i
+ 1] = 255;
105 delay_data
.class2_individual
[i
] = Config
.Delay
.class2
.individual
.restore_bps
;
110 r
->delay_id
= delayId(class, position
);
113 if (aclCheckFast(Config
.Delay
.class3
.access
, &ch
)) {
115 host
= ntohl(ch
.src_addr
.s_addr
) & 0xffff;
118 if (host
== 255 || !host
|| net
== 255) {
119 debug(77, 0) ("ARGH: Delay requested for host %s\n", inet_ntoa(ch
.src_addr
));
121 r
->delay_id
= delayId(class, position
);
125 if (delay_data
.class3_network_map
[i
] == net
)
127 if (delay_data
.class3_network_map
[i
] == 255) {
128 delay_data
.class3_network_map
[i
] = net
;
129 delay_data
.class3_individual_map
[i
][0] = 255;
130 delay_data
.class3_network_map
[i
+ 1] = 255;
131 delay_data
.class3_network
[i
] = Config
.Delay
.class3
.network
.restore_bps
;
137 if (delay_data
.class3_individual_map
[i
][j
] == host
) {
141 if (delay_data
.class3_individual_map
[i
][j
] == 255) {
142 delay_data
.class3_individual_map
[i
][j
] = host
;
143 delay_data
.class3_individual_map
[i
][j
+ 1] = 255;
144 delay_data
.class3_individual
[position
|= j
] =
145 Config
.Delay
.class3
.individual
.restore_bps
;
149 r
->delay_id
= delayId(class, position
);
153 r
->delay_id
= delayId(class, position
);
159 delayPoolsUpdate(int incr
)
164 int individual_restore_bytes
;
165 int network_restore_bytes
;
166 /* Increment 3 aggregate pools */
167 if (Config
.Delay
.class1
.aggregate
.restore_bps
!= -1 &&
168 (delay_data
.class1_aggregate
+=
169 Config
.Delay
.class1
.aggregate
.restore_bps
* incr
) >
170 Config
.Delay
.class1
.aggregate
.max_bytes
)
171 delay_data
.class1_aggregate
= Config
.Delay
.class1
.aggregate
.max_bytes
;
172 if (Config
.Delay
.class2
.aggregate
.restore_bps
!= -1 &&
173 (delay_data
.class2_aggregate
+=
174 Config
.Delay
.class2
.aggregate
.restore_bps
* incr
) >
175 Config
.Delay
.class2
.aggregate
.max_bytes
)
176 delay_data
.class2_aggregate
= Config
.Delay
.class2
.aggregate
.max_bytes
;
177 if (Config
.Delay
.class3
.aggregate
.restore_bps
!= -1 &&
178 (delay_data
.class3_aggregate
+=
179 Config
.Delay
.class3
.aggregate
.restore_bps
* incr
) >
180 Config
.Delay
.class3
.aggregate
.max_bytes
)
181 delay_data
.class3_aggregate
= Config
.Delay
.class3
.aggregate
.max_bytes
;
182 /* Increment class 2 individual pools */
183 if ((individual_restore_bytes
= Config
.Delay
.class2
.individual
.restore_bps
) != -1) {
184 individual_restore_bytes
*= incr
;
186 if (delay_data
.class2_individual_map
[i
] == 255)
188 if (delay_data
.class2_individual
[i
] == Config
.Delay
.class2
.individual
.max_bytes
)
190 if ((delay_data
.class2_individual
[i
] += individual_restore_bytes
) >
191 Config
.Delay
.class2
.individual
.max_bytes
)
192 delay_data
.class2_individual
[i
] = Config
.Delay
.class2
.individual
.max_bytes
;
195 /* Increment class 3 individual and network pools */
196 if ((network_restore_bytes
= Config
.Delay
.class3
.network
.restore_bps
) != -1 ||
197 (individual_restore_bytes
= Config
.Delay
.class3
.individual
.restore_bps
) != -1) {
198 individual_restore_bytes
*= incr
;
199 network_restore_bytes
*= incr
;
201 if (delay_data
.class3_network_map
[i
] == 255)
203 if (individual_restore_bytes
!= -incr
) {
204 for (j
= 0, mpos
= (i
<< 8);; j
++, mpos
++) {
205 if (delay_data
.class3_individual_map
[i
][j
] == 255)
207 if (delay_data
.class3_individual
[mpos
] == Config
.Delay
.class3
.individual
.max_bytes
)
209 if ((delay_data
.class3_individual
[mpos
] += individual_restore_bytes
) >
210 Config
.Delay
.class3
.individual
.max_bytes
)
211 delay_data
.class3_individual
[mpos
] = Config
.Delay
.class3
.individual
.max_bytes
;
214 if (network_restore_bytes
== -incr
||
215 delay_data
.class3_network
[i
] == Config
.Delay
.class3
.network
.max_bytes
)
217 if ((delay_data
.class3_network
[i
] += network_restore_bytes
) >
218 Config
.Delay
.class3
.network
.max_bytes
)
219 delay_data
.class3_network
[i
] = Config
.Delay
.class3
.network
.max_bytes
;
226 delayPoolStats(StoreEntry
* sentry
)
230 storeAppendPrintf(sentry
, "Class 1 Delay Pool Statistics:\n");
231 if (Config
.Delay
.class1
.aggregate
.restore_bps
!= -1) {
232 storeAppendPrintf(sentry
, "\n\tAggregate:\n");
233 storeAppendPrintf(sentry
, "\t\tMax: %d\n",
234 Config
.Delay
.class1
.aggregate
.max_bytes
);
235 storeAppendPrintf(sentry
, "\t\tRate: %d\n",
236 Config
.Delay
.class1
.aggregate
.restore_bps
);
237 storeAppendPrintf(sentry
, "\t\tCurrent: %d\n",
238 delay_data
.class1_aggregate
);
240 storeAppendPrintf(sentry
, "\n\tAggregate:\n\tDisabled.\n");
242 storeAppendPrintf(sentry
, "\nClass 2 Delay Pool Statistics:\n");
243 if (Config
.Delay
.class2
.aggregate
.restore_bps
!= -1) {
244 storeAppendPrintf(sentry
, "\n\tAggregate:\n");
245 storeAppendPrintf(sentry
, "\t\tMax: %d\n",
246 Config
.Delay
.class2
.aggregate
.max_bytes
);
247 storeAppendPrintf(sentry
, "\t\tRate: %d\n",
248 Config
.Delay
.class2
.aggregate
.restore_bps
);
249 storeAppendPrintf(sentry
, "\t\tCurrent: %d\n",
250 delay_data
.class2_aggregate
);
252 storeAppendPrintf(sentry
, "\n\tAggregate:\n\tDisabled.\n");
254 if (Config
.Delay
.class2
.individual
.restore_bps
!= -1) {
255 storeAppendPrintf(sentry
, "\n\tIndividual:\n");
256 storeAppendPrintf(sentry
, "\t\tMax: %d\n",
257 Config
.Delay
.class2
.individual
.max_bytes
);
258 storeAppendPrintf(sentry
, "\t\tRate: %d\n",
259 Config
.Delay
.class2
.individual
.restore_bps
);
260 storeAppendPrintf(sentry
, "\t\tCurrent: ");
262 if (delay_data
.class2_individual_map
[i
] == 255)
264 storeAppendPrintf(sentry
, "%d:%d ",
265 delay_data
.class2_individual_map
[i
],
266 delay_data
.class2_individual
[i
]);
269 storeAppendPrintf(sentry
, "\n\tIndividual:\n\tDisabled.");
271 storeAppendPrintf(sentry
, "\n\nClass 3 Delay Pool Statistics:\n");
272 if (Config
.Delay
.class3
.aggregate
.restore_bps
!= -1) {
273 storeAppendPrintf(sentry
, "\n\tAggregate:\n");
274 storeAppendPrintf(sentry
, "\t\tMax: %d\n",
275 Config
.Delay
.class3
.aggregate
.max_bytes
);
276 storeAppendPrintf(sentry
, "\t\tRate: %d\n",
277 Config
.Delay
.class3
.aggregate
.restore_bps
);
278 storeAppendPrintf(sentry
, "\t\tCurrent: %d\n",
279 delay_data
.class3_aggregate
);
281 storeAppendPrintf(sentry
, "\n\tAggregate:\n\tDisabled.\n");
283 if (Config
.Delay
.class3
.network
.restore_bps
!= -1) {
284 storeAppendPrintf(sentry
, "\n\tNetwork:\n");
285 storeAppendPrintf(sentry
, "\t\tMax: %d\n",
286 Config
.Delay
.class3
.network
.max_bytes
);
287 storeAppendPrintf(sentry
, "\t\tRate: %d\n",
288 Config
.Delay
.class3
.network
.restore_bps
);
289 storeAppendPrintf(sentry
, "\t\tCurrent: ");
291 if (delay_data
.class3_network_map
[i
] == 255)
293 storeAppendPrintf(sentry
, "%d:%d ",
294 delay_data
.class3_network_map
[i
],
295 delay_data
.class3_network
[i
]);
298 storeAppendPrintf(sentry
, "\n\tNetwork:\n\tDisabled.");
300 if (Config
.Delay
.class3
.individual
.restore_bps
!= -1) {
301 storeAppendPrintf(sentry
, "\n\n\tIndividual:\n");
302 storeAppendPrintf(sentry
, "\t\tMax: %d\n",
303 Config
.Delay
.class3
.individual
.max_bytes
);
304 storeAppendPrintf(sentry
, "\t\tRate: %d\n",
305 Config
.Delay
.class3
.individual
.restore_bps
);
307 if (delay_data
.class3_network_map
[i
] == 255)
309 storeAppendPrintf(sentry
, "\t\tCurrent [Network %d]: ",
310 delay_data
.class3_network_map
[i
]);
312 if (delay_data
.class3_individual_map
[i
][j
] == 255)
314 storeAppendPrintf(sentry
, "%d:%d ",
315 delay_data
.class3_individual_map
[i
][j
],
316 delay_data
.class3_individual
[(i
<< 8) + j
]);
318 storeAppendPrintf(sentry
, "\n");
321 storeAppendPrintf(sentry
, "\n\n\tIndividual:\n\tDisabled.\n");
323 storeAppendPrintf(sentry
, "\n");
329 delay_pools_last_update
= getCurrentTime();
330 delay_data
.class1_aggregate
= Config
.Delay
.class1
.aggregate
.restore_bps
;
331 delay_data
.class2_aggregate
= Config
.Delay
.class2
.aggregate
.restore_bps
;
332 delay_data
.class2_individual_map
[0] = 255;
333 delay_data
.class3_aggregate
= Config
.Delay
.class3
.aggregate
.restore_bps
;
334 delay_data
.class3_network_map
[0] = 255;
335 cachemgrRegister("delay", "Delay Pool Levels", delayPoolStats
, 0, 1);
339 * this returns the number of bytes the client is permitted. it does not take
340 * into account bytes already buffered - that is up to the caller.
343 delayBytesWanted(delay_id d
, int max
)
345 int position
= d
& 0xFFFF;
346 unsigned char class = (d
& 0xFF0000) >> 16;
353 if (Config
.Delay
.class1
.aggregate
.restore_bps
!= -1)
354 nbytes
= XMIN(nbytes
, delay_data
.class1_aggregate
);
358 if (Config
.Delay
.class2
.aggregate
.restore_bps
!= -1)
359 nbytes
= XMIN(nbytes
, delay_data
.class2_aggregate
);
360 if (Config
.Delay
.class2
.individual
.restore_bps
!= -1)
361 nbytes
= XMIN(nbytes
, delay_data
.class2_individual
[position
]);
365 if (Config
.Delay
.class3
.aggregate
.restore_bps
!= -1)
366 nbytes
= XMIN(nbytes
, delay_data
.class3_aggregate
);
367 if (Config
.Delay
.class3
.individual
.restore_bps
!= -1)
368 nbytes
= XMIN(nbytes
, delay_data
.class3_individual
[position
]);
369 if (Config
.Delay
.class3
.network
.restore_bps
!= -1)
370 nbytes
= XMIN(nbytes
, delay_data
.class3_network
[position
>> 8]);
374 fatalf("delayBytesWanted: Invalid class %d\n", class);
378 assert(nbytes
<= max
);
383 * this records actual bytes recieved. always recorded, even if the
384 * class is disabled - see above for all the cases which would be needed
385 * to efficiently not record it, so it's just ignored if not wanted.
388 delayBytesIn(delay_id d
, int qty
)
390 int position
= d
& 0xFFFF;
391 unsigned char class = (d
& 0xFF0000) >> 16;
395 delay_data
.class1_aggregate
-= qty
;
399 delay_data
.class2_aggregate
-= qty
;
400 delay_data
.class3_individual
[position
] -= qty
;
404 delay_data
.class3_aggregate
-= qty
;
405 delay_data
.class3_network
[position
>> 8] -= qty
;
406 delay_data
.class3_individual
[position
] -= qty
;
413 delayMostBytesWanted(const MemObject
* mem
, int max
)
417 for (sc
= mem
->clients
; sc
; sc
= sc
->next
) {
418 if (sc
->callback_data
== NULL
) /* open slot */
420 if (sc
->type
!= STORE_MEM_CLIENT
)
422 i
= XMAX(delayBytesWanted(sc
->delay_id
, max
), i
);
428 delayMostBytesAllowed(const MemObject
* mem
)
434 for (sc
= mem
->clients
; sc
; sc
= sc
->next
) {
435 if (sc
->callback_data
== NULL
) /* open slot */
437 if (sc
->type
!= STORE_MEM_CLIENT
)
439 j
= delayBytesWanted(sc
->delay_id
, SQUID_TCP_SO_RCVBUF
);
449 delaySetStoreClient(StoreEntry
* e
, void *data
, delay_id delay_id
)
451 store_client
*sc
= storeClientListSearch(e
->mem_obj
, data
);
453 sc
->delay_id
= delay_id
;