]> git.ipfire.org Git - thirdparty/squid.git/blame - src/DelayUser.cc
SourceFormat Enforcement
[thirdparty/squid.git] / src / DelayUser.cc
CommitLineData
88a03fda 1/*
ef57eb7b 2 * Copyright (C) 1996-2016 The Squid Software Foundation and contributors
26ac0430 3 *
bbc27441
AJ
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.
88a03fda 7 */
8
bbc27441
AJ
9/* DEBUG: section 77 Delay Pools */
10
f7f3304a 11#include "squid.h"
88a03fda 12
79fc6915 13#if USE_DELAY_POOLS && USE_AUTH
2d2b0bb7 14#include "auth/User.h"
582c2af2 15#include "auth/UserRequest.h"
1b76e6c1 16#include "comm/Connection.h"
582c2af2 17#include "DelayUser.h"
88a03fda 18#include "NullDelayId.h"
19#include "Store.h"
20
21void *
22DelayUser::operator new(size_t size)
23{
24 DelayPools::MemoryUsed += sizeof (DelayUser);
25 return ::operator new (size);
26}
27
28void
29DelayUser::operator delete (void *address)
30{
31 DelayPools::MemoryUsed -= sizeof (DelayUser);
32 ::operator delete (address);
33}
34
88a03fda 35DelayUser::DelayUser()
36{
37 DelayPools::registerForUpdates (this);
38}
39
1a005c0e 40static Splay<DelayUserBucket::Pointer>::SPLAYFREE DelayUserFree;
29b17d63 41
88a03fda 42DelayUser::~DelayUser()
43{
44 DelayPools::deregisterForUpdates (this);
d6349cfb 45 buckets.destroy(DelayUserFree);
29b17d63 46}
47
1a005c0e 48static Splay<DelayUserBucket::Pointer>::SPLAYCMP DelayUserCmp;
29b17d63 49
50int
51DelayUserCmp(DelayUserBucket::Pointer const &left, DelayUserBucket::Pointer const &right)
52{
98e025e1
AJ
53 /* Verify for re-currance of Bug 2127. either of these missing will crash strcasecmp() */
54 assert(left->authUser->username() != NULL);
55 assert(right->authUser->username() != NULL);
56
29b17d63 57 /* for rate limiting, case insensitive */
58 return strcasecmp(left->authUser->username(), right->authUser->username());
59}
60
61void
62DelayUserFree(DelayUserBucket::Pointer &)
62e76326 63{}
29b17d63 64
65void
66DelayUserStatsWalkee(DelayUserBucket::Pointer const &current, void *state)
67{
68 current->stats ((StoreEntry *)state);
88a03fda 69}
70
d6349cfb
FC
71struct DelayUserStatsVisitor {
72 StoreEntry *se;
73 explicit DelayUserStatsVisitor(StoreEntry *s) : se(s) {}
74 void operator() (DelayUserBucket::Pointer const &current) {
75 current->stats(se);
76 }
77};
78
88a03fda 79void
80DelayUser::stats(StoreEntry * sentry)
81{
82 spec.stats (sentry, "Per User");
62e76326 83
88a03fda 84 if (spec.restore_bps == -1)
62e76326 85 return;
86
88a03fda 87 storeAppendPrintf(sentry, "\t\tCurrent: ");
62e76326 88
d6349cfb 89 if (buckets.empty()) {
62e76326 90 storeAppendPrintf (sentry, "Not used yet.\n\n");
91 return;
88a03fda 92 }
62e76326 93
d6349cfb
FC
94 DelayUserStatsVisitor visitor(sentry);
95 buckets.visit(visitor);
88a03fda 96 storeAppendPrintf(sentry, "\n\n");
97}
98
99void
100DelayUser::dump(StoreEntry *entry) const
101{
102 spec.dump(entry);
103}
104
26ac0430
AJ
105struct DelayUserUpdater {
106 DelayUserUpdater (DelaySpec &_spec, int _incr):spec(_spec),incr(_incr) {};
62e76326 107
29b17d63 108 DelaySpec spec;
109 int incr;
110};
62e76326 111
29b17d63 112void
113DelayUserUpdateWalkee(DelayUserBucket::Pointer const &current, void *state)
114{
115 DelayUserUpdater *t = (DelayUserUpdater *)state;
116 /* This doesn't change the value of the DelayUserBucket, so is safe */
117 const_cast<DelayUserBucket *>(current.getRaw())->theBucket.update(t->spec, t->incr);
118}
62e76326 119
d6349cfb
FC
120struct DelayUserUpdateVisitor {
121 DelayUserUpdater *t;
122 DelayUserUpdateVisitor(DelayUserUpdater *updater) : t(updater) {}
123 void operator() (DelayUserBucket::Pointer const &current) {
124 const_cast<DelayUserBucket *>(current.getRaw())->theBucket.update(t->spec, t->incr);
125 }
126};
127
88a03fda 128void
129DelayUser::update(int incr)
130{
29b17d63 131 DelayUserUpdater updater(spec, incr);
d6349cfb
FC
132 DelayUserUpdateVisitor visitor(&updater);
133 buckets.visit(visitor);
88a03fda 134}
135
136void
137DelayUser::parse()
138{
139 spec.parse();
140}
141
142DelayIdComposite::Pointer
1e5562e3 143DelayUser::id(CompositePoolNode::CompositeSelectionDetails &details)
88a03fda 144{
98e025e1 145 if (!details.user || !details.user->user() || !details.user->user()->username())
62e76326 146 return new NullDelayId;
147
98e025e1 148 debugs(77, 3, HERE << "Adding a slow-down for User '" << details.user->user()->username() << "'");
f5691f9c 149 return new Id(this, details.user->user());
88a03fda 150}
151
152void *
153DelayUser::Id::operator new(size_t size)
154{
155 DelayPools::MemoryUsed += sizeof (Id);
156 return ::operator new (size);
157}
158
159void
160DelayUser::Id::operator delete (void *address)
161{
162 DelayPools::MemoryUsed -= sizeof (Id);
163 ::operator delete (address);
164}
165
88a03fda 166void *
167DelayUserBucket::operator new(size_t size)
168{
169 DelayPools::MemoryUsed += sizeof (DelayUserBucket);
170 return ::operator new (size);
171}
172
173void
56a49fda 174DelayUserBucket::operator delete(void *address)
88a03fda 175{
56a49fda
AJ
176 DelayPools::MemoryUsed -= sizeof(DelayUserBucket);
177 ::operator delete(address);
88a03fda 178}
179
d87154ee 180DelayUserBucket::DelayUserBucket(Auth::User::Pointer aUser) : authUser(aUser)
88a03fda 181{
bf8fe701 182 debugs(77, 3, "DelayUserBucket::DelayUserBucket");
88a03fda 183}
184
185DelayUserBucket::~DelayUserBucket()
186{
56a49fda 187 authUser = NULL;
bf8fe701 188 debugs(77, 3, "DelayUserBucket::~DelayUserBucket");
88a03fda 189}
190
191void
192DelayUserBucket::stats (StoreEntry *entry) const
193{
194 storeAppendPrintf(entry, " %s:", authUser->username());
56a49fda 195 theBucket.stats(entry);
88a03fda 196}
197
d87154ee 198DelayUser::Id::Id(DelayUser::Pointer aDelayUser, Auth::User::Pointer aUser) : theUser(aDelayUser)
88a03fda 199{
88a03fda 200 theBucket = new DelayUserBucket(aUser);
29b17d63 201 DelayUserBucket::Pointer const *existing = theUser->buckets.find(theBucket, DelayUserCmp);
62e76326 202
29b17d63 203 if (existing) {
62e76326 204 theBucket = *existing;
205 return;
29b17d63 206 }
62e76326 207
88a03fda 208 theBucket->theBucket.init(theUser->spec);
d6349cfb 209 theUser->buckets.insert (theBucket, DelayUserCmp);
88a03fda 210}
211
212DelayUser::Id::~Id()
213{
bf8fe701 214 debugs(77, 3, "DelayUser::Id::~Id");
88a03fda 215}
216
217int
218DelayUser::Id::bytesWanted (int min, int max) const
219{
220 return theBucket->theBucket.bytesWanted(min,max);
221}
222
223void
224DelayUser::Id::bytesIn(int qty)
225{
226 theBucket->theBucket.bytesIn(qty);
227}
62e76326 228
79fc6915 229#endif /* USE_DELAY_POOLS && USE_AUTH */
f53969cc 230