]> git.ipfire.org Git - thirdparty/squid.git/blame - src/DelayUser.cc
Boilerplate: update copyright blurbs on src/
[thirdparty/squid.git] / src / DelayUser.cc
CommitLineData
88a03fda 1/*
bbc27441 2 * Copyright (C) 1996-2014 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
29b17d63 40static SplayNode<DelayUserBucket::Pointer>::SPLAYFREE DelayUserFree;
41
88a03fda 42DelayUser::~DelayUser()
43{
44 DelayPools::deregisterForUpdates (this);
29b17d63 45 buckets.head->destroy (DelayUserFree);
46}
47
48static SplayNode<DelayUserBucket::Pointer>::SPLAYCMP DelayUserCmp;
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
71void
72DelayUser::stats(StoreEntry * sentry)
73{
74 spec.stats (sentry, "Per User");
62e76326 75
88a03fda 76 if (spec.restore_bps == -1)
62e76326 77 return;
78
88a03fda 79 storeAppendPrintf(sentry, "\t\tCurrent: ");
62e76326 80
29b17d63 81 if (!buckets.head) {
62e76326 82 storeAppendPrintf (sentry, "Not used yet.\n\n");
83 return;
88a03fda 84 }
62e76326 85
29b17d63 86 buckets.head->walk(DelayUserStatsWalkee, sentry);
88a03fda 87 storeAppendPrintf(sentry, "\n\n");
88}
89
90void
91DelayUser::dump(StoreEntry *entry) const
92{
93 spec.dump(entry);
94}
95
26ac0430
AJ
96struct DelayUserUpdater {
97 DelayUserUpdater (DelaySpec &_spec, int _incr):spec(_spec),incr(_incr) {};
62e76326 98
29b17d63 99 DelaySpec spec;
100 int incr;
101};
62e76326 102
29b17d63 103void
104DelayUserUpdateWalkee(DelayUserBucket::Pointer const &current, void *state)
105{
106 DelayUserUpdater *t = (DelayUserUpdater *)state;
107 /* This doesn't change the value of the DelayUserBucket, so is safe */
108 const_cast<DelayUserBucket *>(current.getRaw())->theBucket.update(t->spec, t->incr);
109}
62e76326 110
88a03fda 111void
112DelayUser::update(int incr)
113{
29b17d63 114 DelayUserUpdater updater(spec, incr);
115 buckets.head->walk (DelayUserUpdateWalkee, &updater);
88a03fda 116}
117
118void
119DelayUser::parse()
120{
121 spec.parse();
122}
123
124DelayIdComposite::Pointer
1e5562e3 125DelayUser::id(CompositePoolNode::CompositeSelectionDetails &details)
88a03fda 126{
98e025e1 127 if (!details.user || !details.user->user() || !details.user->user()->username())
62e76326 128 return new NullDelayId;
129
98e025e1 130 debugs(77, 3, HERE << "Adding a slow-down for User '" << details.user->user()->username() << "'");
f5691f9c 131 return new Id(this, details.user->user());
88a03fda 132}
133
134void *
135DelayUser::Id::operator new(size_t size)
136{
137 DelayPools::MemoryUsed += sizeof (Id);
138 return ::operator new (size);
139}
140
141void
142DelayUser::Id::operator delete (void *address)
143{
144 DelayPools::MemoryUsed -= sizeof (Id);
145 ::operator delete (address);
146}
147
88a03fda 148void *
149DelayUserBucket::operator new(size_t size)
150{
151 DelayPools::MemoryUsed += sizeof (DelayUserBucket);
152 return ::operator new (size);
153}
154
155void
56a49fda 156DelayUserBucket::operator delete(void *address)
88a03fda 157{
56a49fda
AJ
158 DelayPools::MemoryUsed -= sizeof(DelayUserBucket);
159 ::operator delete(address);
88a03fda 160}
161
d87154ee 162DelayUserBucket::DelayUserBucket(Auth::User::Pointer aUser) : authUser(aUser)
88a03fda 163{
bf8fe701 164 debugs(77, 3, "DelayUserBucket::DelayUserBucket");
88a03fda 165}
166
167DelayUserBucket::~DelayUserBucket()
168{
56a49fda 169 authUser = NULL;
bf8fe701 170 debugs(77, 3, "DelayUserBucket::~DelayUserBucket");
88a03fda 171}
172
173void
174DelayUserBucket::stats (StoreEntry *entry) const
175{
176 storeAppendPrintf(entry, " %s:", authUser->username());
56a49fda 177 theBucket.stats(entry);
88a03fda 178}
179
d87154ee 180DelayUser::Id::Id(DelayUser::Pointer aDelayUser, Auth::User::Pointer aUser) : theUser(aDelayUser)
88a03fda 181{
88a03fda 182 theBucket = new DelayUserBucket(aUser);
29b17d63 183 DelayUserBucket::Pointer const *existing = theUser->buckets.find(theBucket, DelayUserCmp);
62e76326 184
29b17d63 185 if (existing) {
62e76326 186 theBucket = *existing;
187 return;
29b17d63 188 }
62e76326 189
88a03fda 190 theBucket->theBucket.init(theUser->spec);
29b17d63 191 theUser->buckets.head = theUser->buckets.head->insert (theBucket, DelayUserCmp);
88a03fda 192}
193
194DelayUser::Id::~Id()
195{
bf8fe701 196 debugs(77, 3, "DelayUser::Id::~Id");
88a03fda 197}
198
199int
200DelayUser::Id::bytesWanted (int min, int max) const
201{
202 return theBucket->theBucket.bytesWanted(min,max);
203}
204
205void
206DelayUser::Id::bytesIn(int qty)
207{
208 theBucket->theBucket.bytesIn(qty);
209}
62e76326 210
79fc6915 211#endif /* USE_DELAY_POOLS && USE_AUTH */