]>
Commit | Line | Data |
---|---|---|
1 | /* | |
2 | * Copyright (C) 1996-2025 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 | #include "squid.h" | |
10 | #include "acl/Acl.h" | |
11 | #include "acl/Gadgets.h" | |
12 | #include "ClientDelayConfig.h" | |
13 | #include "ConfigParser.h" | |
14 | #include "Parsing.h" | |
15 | #include "Store.h" | |
16 | ||
17 | ClientDelayPool::~ClientDelayPool() | |
18 | { | |
19 | if (access) | |
20 | aclDestroyAccessList(&access); | |
21 | } | |
22 | ||
23 | void ClientDelayPool::dump(StoreEntry * entry, unsigned int poolNumberMinusOne) const | |
24 | { | |
25 | LOCAL_ARRAY(char, nom, 32); | |
26 | snprintf(nom, 32, "client_delay_access %d", poolNumberMinusOne + 1); | |
27 | dump_acl_access(entry, nom, access); | |
28 | storeAppendPrintf(entry, "client_delay_parameters %d %d %" PRId64 "\n", poolNumberMinusOne + 1, rate,highwatermark); | |
29 | storeAppendPrintf(entry, "\n"); | |
30 | } | |
31 | ||
32 | ClientDelayPools * | |
33 | ClientDelayPools::Instance() | |
34 | { | |
35 | static ClientDelayPools pools; | |
36 | return &pools; | |
37 | } | |
38 | ||
39 | ClientDelayPools::~ClientDelayPools() | |
40 | { | |
41 | pools.clear(); | |
42 | } | |
43 | ||
44 | void | |
45 | ClientDelayConfig::finalize() | |
46 | { | |
47 | for (unsigned int i = 0; i < pools().size(); ++i) { | |
48 | /* pools require explicit 'allow' to assign a client into them */ | |
49 | if (!pool(i).access) { | |
50 | debugs(77, DBG_IMPORTANT, "WARNING: client_delay_pool #" << (i+1) << | |
51 | " has no client_delay_access configured. " << | |
52 | "No client will ever use it."); | |
53 | } | |
54 | } | |
55 | } | |
56 | ||
57 | void ClientDelayConfig::dumpPoolCount(StoreEntry * entry, const char *name) const | |
58 | { | |
59 | const auto &pools_ = ClientDelayPools::Instance()->pools; | |
60 | if (pools_.size()) { | |
61 | storeAppendPrintf(entry, "%s %d\n", name, static_cast<int>(pools_.size())); | |
62 | for (unsigned int i = 0; i < pools_.size(); ++i) | |
63 | pools_[i]->dump(entry, i); | |
64 | } | |
65 | } | |
66 | ||
67 | void | |
68 | ClientDelayConfig::freePools() | |
69 | { | |
70 | pools().clear(); | |
71 | } | |
72 | ||
73 | void ClientDelayConfig::parsePoolCount() | |
74 | { | |
75 | if (pools().size()) { | |
76 | debugs(3, DBG_CRITICAL, "parse_client_delay_pool_count: multiple client_delay_pools lines, " << | |
77 | "aborting all previous client_delay_pools config"); | |
78 | freePools(); | |
79 | } | |
80 | unsigned short pools_; | |
81 | ConfigParser::ParseUShort(&pools_); | |
82 | for (int i = 0; i < pools_; ++i) | |
83 | pools().push_back(new ClientDelayPool()); | |
84 | } | |
85 | ||
86 | void ClientDelayConfig::parsePoolRates() | |
87 | { | |
88 | if (unsigned short poolId = parsePoolId()) { | |
89 | --poolId; | |
90 | pool(poolId).rate = GetInteger(); | |
91 | pool(poolId).highwatermark = GetInteger64(); | |
92 | } | |
93 | } | |
94 | ||
95 | void ClientDelayConfig::parsePoolAccess(ConfigParser &parser) | |
96 | { | |
97 | if (const unsigned short poolId = parsePoolId()) | |
98 | aclParseAccessLine("client_delay_access", parser, &(pool(poolId-1).access)); | |
99 | } | |
100 | ||
101 | unsigned short | |
102 | ClientDelayConfig::parsePoolId() | |
103 | { | |
104 | unsigned short poolId = 0; | |
105 | ConfigParser::ParseUShort(&poolId); | |
106 | if (poolId < 1 || poolId > pools().size()) { | |
107 | debugs(3, DBG_CRITICAL, "parse_client_delay_pool_rates: Ignoring pool " << | |
108 | poolId << " not in 1 .. " << pools().size()); | |
109 | return 0; | |
110 | } | |
111 | return poolId; | |
112 | } | |
113 |