]> git.ipfire.org Git - thirdparty/squid.git/blob - src/comm/AcceptLimiter.cc
SourceFormat Enforcement
[thirdparty/squid.git] / src / comm / AcceptLimiter.cc
1 /*
2 * Copyright (C) 1996-2017 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 "comm/AcceptLimiter.h"
11 #include "comm/Connection.h"
12 #include "comm/TcpAcceptor.h"
13 #include "fde.h"
14 #include "globals.h"
15
16 Comm::AcceptLimiter Comm::AcceptLimiter::Instance_;
17
18 Comm::AcceptLimiter &
19 Comm::AcceptLimiter::Instance()
20 {
21 return Instance_;
22 }
23
24 void
25 Comm::AcceptLimiter::defer(const Comm::TcpAcceptor::Pointer &afd)
26 {
27 ++ (afd->isLimited);
28 debugs(5, 5, afd->conn << " x" << afd->isLimited);
29 deferred_.push_back(afd);
30 }
31
32 void
33 Comm::AcceptLimiter::removeDead(const Comm::TcpAcceptor::Pointer &afd)
34 {
35 uint64_t abandonedClients = 0;
36 for (unsigned int i = 0; i < deferred_.size() && afd->isLimited > 0; ++i) {
37 if (deferred_[i] == afd) {
38 -- deferred_[i]->isLimited;
39 deferred_[i] = NULL; // fast. kick() will skip empty entries later.
40 debugs(5, 5, afd->conn << " x" << afd->isLimited);
41 ++abandonedClients;
42 }
43 }
44 debugs(5,4, "Abandoned " << abandonedClients << " client TCP SYN by closing socket: " << afd->conn);
45 }
46
47 void
48 Comm::AcceptLimiter::kick()
49 {
50 // TODO: this could be optimized further with an iterator to search
51 // looking for first non-NULL, followed by dumping the first N
52 // with only one shift()/pop_front operation
53 // OR, by reimplementing as a list instead of Vector.
54
55 debugs(5, 5, "size=" << deferred_.size());
56 while (deferred_.size() > 0 && fdNFree() >= RESERVED_FD) {
57 /* NP: shift() is equivalent to pop_front(). Giving us a FIFO queue. */
58 TcpAcceptor::Pointer temp = deferred_.front();
59 deferred_.erase(deferred_.begin());
60 if (temp.valid()) {
61 debugs(5, 5, "doing one.");
62 -- temp->isLimited;
63 temp->acceptNext();
64 break;
65 }
66 }
67 }
68