]>
Commit | Line | Data |
---|---|---|
88a03fda | 1 | /* |
5b74111a | 2 | * Copyright (C) 1996-2018 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 | 21 | DelayUser::DelayUser() |
22 | { | |
23 | DelayPools::registerForUpdates (this); | |
24 | } | |
25 | ||
1a005c0e | 26 | static Splay<DelayUserBucket::Pointer>::SPLAYFREE DelayUserFree; |
29b17d63 | 27 | |
88a03fda | 28 | DelayUser::~DelayUser() |
29 | { | |
30 | DelayPools::deregisterForUpdates (this); | |
d6349cfb | 31 | buckets.destroy(DelayUserFree); |
29b17d63 | 32 | } |
33 | ||
1a005c0e | 34 | static Splay<DelayUserBucket::Pointer>::SPLAYCMP DelayUserCmp; |
29b17d63 | 35 | |
36 | int | |
37 | DelayUserCmp(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 | ||
47 | void | |
48 | DelayUserFree(DelayUserBucket::Pointer &) | |
62e76326 | 49 | {} |
29b17d63 | 50 | |
51 | void | |
52 | DelayUserStatsWalkee(DelayUserBucket::Pointer const ¤t, void *state) | |
53 | { | |
54 | current->stats ((StoreEntry *)state); | |
88a03fda | 55 | } |
56 | ||
d6349cfb FC |
57 | struct DelayUserStatsVisitor { |
58 | StoreEntry *se; | |
59 | explicit DelayUserStatsVisitor(StoreEntry *s) : se(s) {} | |
60 | void operator() (DelayUserBucket::Pointer const ¤t) { | |
61 | current->stats(se); | |
62 | } | |
63 | }; | |
64 | ||
88a03fda | 65 | void |
66 | DelayUser::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 | ||
85 | void | |
86 | DelayUser::dump(StoreEntry *entry) const | |
87 | { | |
88 | spec.dump(entry); | |
89 | } | |
90 | ||
26ac0430 AJ |
91 | struct DelayUserUpdater { |
92 | DelayUserUpdater (DelaySpec &_spec, int _incr):spec(_spec),incr(_incr) {}; | |
62e76326 | 93 | |
29b17d63 | 94 | DelaySpec spec; |
95 | int incr; | |
96 | }; | |
62e76326 | 97 | |
29b17d63 | 98 | void |
99 | DelayUserUpdateWalkee(DelayUserBucket::Pointer const ¤t, 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 |
106 | struct DelayUserUpdateVisitor { |
107 | DelayUserUpdater *t; | |
108 | DelayUserUpdateVisitor(DelayUserUpdater *updater) : t(updater) {} | |
109 | void operator() (DelayUserBucket::Pointer const ¤t) { | |
110 | const_cast<DelayUserBucket *>(current.getRaw())->theBucket.update(t->spec, t->incr); | |
111 | } | |
112 | }; | |
113 | ||
88a03fda | 114 | void |
115 | DelayUser::update(int incr) | |
116 | { | |
29b17d63 | 117 | DelayUserUpdater updater(spec, incr); |
d6349cfb FC |
118 | DelayUserUpdateVisitor visitor(&updater); |
119 | buckets.visit(visitor); | |
88a03fda | 120 | } |
121 | ||
122 | void | |
123 | DelayUser::parse() | |
124 | { | |
125 | spec.parse(); | |
126 | } | |
127 | ||
128 | DelayIdComposite::Pointer | |
1e5562e3 | 129 | DelayUser::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 | 138 | DelayUserBucket::DelayUserBucket(Auth::User::Pointer aUser) : authUser(aUser) |
88a03fda | 139 | { |
bf8fe701 | 140 | debugs(77, 3, "DelayUserBucket::DelayUserBucket"); |
88a03fda | 141 | } |
142 | ||
143 | DelayUserBucket::~DelayUserBucket() | |
144 | { | |
56a49fda | 145 | authUser = NULL; |
bf8fe701 | 146 | debugs(77, 3, "DelayUserBucket::~DelayUserBucket"); |
88a03fda | 147 | } |
148 | ||
149 | void | |
150 | DelayUserBucket::stats (StoreEntry *entry) const | |
151 | { | |
152 | storeAppendPrintf(entry, " %s:", authUser->username()); | |
56a49fda | 153 | theBucket.stats(entry); |
88a03fda | 154 | } |
155 | ||
d87154ee | 156 | DelayUser::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 | ||
170 | DelayUser::Id::~Id() | |
171 | { | |
bf8fe701 | 172 | debugs(77, 3, "DelayUser::Id::~Id"); |
88a03fda | 173 | } |
174 | ||
175 | int | |
176 | DelayUser::Id::bytesWanted (int min, int max) const | |
177 | { | |
178 | return theBucket->theBucket.bytesWanted(min,max); | |
179 | } | |
180 | ||
181 | void | |
182 | DelayUser::Id::bytesIn(int qty) | |
183 | { | |
184 | theBucket->theBucket.bytesIn(qty); | |
185 | } | |
62e76326 | 186 | |
79fc6915 | 187 | #endif /* USE_DELAY_POOLS && USE_AUTH */ |
f53969cc | 188 |