]> git.ipfire.org Git - thirdparty/squid.git/blame - src/DelayUser.cc
Source Format Enforcement (#763)
[thirdparty/squid.git] / src / DelayUser.cc
CommitLineData
88a03fda 1/*
f70aedc4 2 * Copyright (C) 1996-2021 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
88a03fda 21DelayUser::DelayUser()
22{
23 DelayPools::registerForUpdates (this);
24}
25
1a005c0e 26static Splay<DelayUserBucket::Pointer>::SPLAYFREE DelayUserFree;
29b17d63 27
88a03fda 28DelayUser::~DelayUser()
29{
30 DelayPools::deregisterForUpdates (this);
d6349cfb 31 buckets.destroy(DelayUserFree);
29b17d63 32}
33
1a005c0e 34static Splay<DelayUserBucket::Pointer>::SPLAYCMP DelayUserCmp;
29b17d63 35
36int
37DelayUserCmp(DelayUserBucket::Pointer const &left, DelayUserBucket::Pointer const &right)
38{
98e025e1
AJ
39 /* Verify for re-currance of Bug 2127. either of these missing will crash strcasecmp() */
40 assert(left->authUser->username() != NULL);
41 assert(right->authUser->username() != NULL);
42
29b17d63 43 /* for rate limiting, case insensitive */
44 return strcasecmp(left->authUser->username(), right->authUser->username());
45}
46
47void
48DelayUserFree(DelayUserBucket::Pointer &)
62e76326 49{}
29b17d63 50
51void
52DelayUserStatsWalkee(DelayUserBucket::Pointer const &current, void *state)
53{
54 current->stats ((StoreEntry *)state);
88a03fda 55}
56
d6349cfb
FC
57struct DelayUserStatsVisitor {
58 StoreEntry *se;
59 explicit DelayUserStatsVisitor(StoreEntry *s) : se(s) {}
60 void operator() (DelayUserBucket::Pointer const &current) {
61 current->stats(se);
62 }
63};
64
88a03fda 65void
66DelayUser::stats(StoreEntry * sentry)
67{
68 spec.stats (sentry, "Per User");
62e76326 69
88a03fda 70 if (spec.restore_bps == -1)
62e76326 71 return;
72
88a03fda 73 storeAppendPrintf(sentry, "\t\tCurrent: ");
62e76326 74
d6349cfb 75 if (buckets.empty()) {
62e76326 76 storeAppendPrintf (sentry, "Not used yet.\n\n");
77 return;
88a03fda 78 }
62e76326 79
d6349cfb
FC
80 DelayUserStatsVisitor visitor(sentry);
81 buckets.visit(visitor);
88a03fda 82 storeAppendPrintf(sentry, "\n\n");
83}
84
85void
86DelayUser::dump(StoreEntry *entry) const
87{
88 spec.dump(entry);
89}
90
26ac0430
AJ
91struct DelayUserUpdater {
92 DelayUserUpdater (DelaySpec &_spec, int _incr):spec(_spec),incr(_incr) {};
62e76326 93
29b17d63 94 DelaySpec spec;
95 int incr;
96};
62e76326 97
29b17d63 98void
99DelayUserUpdateWalkee(DelayUserBucket::Pointer const &current, void *state)
100{
101 DelayUserUpdater *t = (DelayUserUpdater *)state;
102 /* This doesn't change the value of the DelayUserBucket, so is safe */
103 const_cast<DelayUserBucket *>(current.getRaw())->theBucket.update(t->spec, t->incr);
104}
62e76326 105
d6349cfb
FC
106struct DelayUserUpdateVisitor {
107 DelayUserUpdater *t;
108 DelayUserUpdateVisitor(DelayUserUpdater *updater) : t(updater) {}
109 void operator() (DelayUserBucket::Pointer const &current) {
110 const_cast<DelayUserBucket *>(current.getRaw())->theBucket.update(t->spec, t->incr);
111 }
112};
113
88a03fda 114void
115DelayUser::update(int incr)
116{
29b17d63 117 DelayUserUpdater updater(spec, incr);
d6349cfb
FC
118 DelayUserUpdateVisitor visitor(&updater);
119 buckets.visit(visitor);
88a03fda 120}
121
122void
123DelayUser::parse()
124{
125 spec.parse();
126}
127
128DelayIdComposite::Pointer
1e5562e3 129DelayUser::id(CompositePoolNode::CompositeSelectionDetails &details)
88a03fda 130{
98e025e1 131 if (!details.user || !details.user->user() || !details.user->user()->username())
62e76326 132 return new NullDelayId;
133
98e025e1 134 debugs(77, 3, HERE << "Adding a slow-down for User '" << details.user->user()->username() << "'");
f5691f9c 135 return new Id(this, details.user->user());
88a03fda 136}
137
d87154ee 138DelayUserBucket::DelayUserBucket(Auth::User::Pointer aUser) : authUser(aUser)
88a03fda 139{
bf8fe701 140 debugs(77, 3, "DelayUserBucket::DelayUserBucket");
88a03fda 141}
142
143DelayUserBucket::~DelayUserBucket()
144{
56a49fda 145 authUser = NULL;
bf8fe701 146 debugs(77, 3, "DelayUserBucket::~DelayUserBucket");
88a03fda 147}
148
149void
150DelayUserBucket::stats (StoreEntry *entry) const
151{
152 storeAppendPrintf(entry, " %s:", authUser->username());
56a49fda 153 theBucket.stats(entry);
88a03fda 154}
155
d87154ee 156DelayUser::Id::Id(DelayUser::Pointer aDelayUser, Auth::User::Pointer aUser) : theUser(aDelayUser)
88a03fda 157{
88a03fda 158 theBucket = new DelayUserBucket(aUser);
29b17d63 159 DelayUserBucket::Pointer const *existing = theUser->buckets.find(theBucket, DelayUserCmp);
62e76326 160
29b17d63 161 if (existing) {
62e76326 162 theBucket = *existing;
163 return;
29b17d63 164 }
62e76326 165
88a03fda 166 theBucket->theBucket.init(theUser->spec);
d6349cfb 167 theUser->buckets.insert (theBucket, DelayUserCmp);
88a03fda 168}
169
170DelayUser::Id::~Id()
171{
bf8fe701 172 debugs(77, 3, "DelayUser::Id::~Id");
88a03fda 173}
174
175int
176DelayUser::Id::bytesWanted (int min, int max) const
177{
178 return theBucket->theBucket.bytesWanted(min,max);
179}
180
181void
182DelayUser::Id::bytesIn(int qty)
183{
184 theBucket->theBucket.bytesIn(qty);
185}
62e76326 186
79fc6915 187#endif /* USE_DELAY_POOLS && USE_AUTH */
f53969cc 188