|
|
e6ac7e |
diff -up squid-3.5.20/src/comm/AcceptLimiter.cc.02396660 squid-3.5.20/src/comm/AcceptLimiter.cc
|
|
|
e6ac7e |
--- squid-3.5.20/src/comm/AcceptLimiter.cc.02396660 2019-06-05 13:18:11.000000000 +0200
|
|
|
e6ac7e |
+++ squid-3.5.20/src/comm/AcceptLimiter.cc 2019-06-05 13:21:29.000000000 +0200
|
|
|
e6ac7e |
@@ -24,42 +24,33 @@ Comm::AcceptLimiter::Instance()
|
|
|
e6ac7e |
void
|
|
|
e6ac7e |
Comm::AcceptLimiter::defer(const Comm::TcpAcceptor::Pointer &afd)
|
|
|
e6ac7e |
{
|
|
|
e6ac7e |
- ++ (afd->isLimited);
|
|
|
e6ac7e |
- debugs(5, 5, afd->conn << " x" << afd->isLimited);
|
|
|
e6ac7e |
+ debugs(5, 5, afd->conn << "; already queued: " << deferred_.size());
|
|
|
e6ac7e |
deferred_.push_back(afd);
|
|
|
e6ac7e |
}
|
|
|
e6ac7e |
|
|
|
e6ac7e |
void
|
|
|
e6ac7e |
Comm::AcceptLimiter::removeDead(const Comm::TcpAcceptor::Pointer &afd)
|
|
|
e6ac7e |
{
|
|
|
e6ac7e |
- uint64_t abandonedClients = 0;
|
|
|
e6ac7e |
- for (unsigned int i = 0; i < deferred_.size() && afd->isLimited > 0; ++i) {
|
|
|
e6ac7e |
- if (deferred_[i] == afd) {
|
|
|
e6ac7e |
- -- deferred_[i]->isLimited;
|
|
|
e6ac7e |
- deferred_[i] = NULL; // fast. kick() will skip empty entries later.
|
|
|
e6ac7e |
- debugs(5, 5, afd->conn << " x" << afd->isLimited);
|
|
|
e6ac7e |
- ++abandonedClients;
|
|
|
e6ac7e |
+ for (auto it = deferred_.begin(); it != deferred_.end(); ++it) {
|
|
|
e6ac7e |
+ if (*it == afd) {
|
|
|
e6ac7e |
+ *it = nullptr; // fast. kick() will skip empty entries later.
|
|
|
e6ac7e |
+ debugs(5,4, "Abandoned client TCP SYN by closing socket: " << afd->conn);
|
|
|
e6ac7e |
+ return;
|
|
|
e6ac7e |
}
|
|
|
e6ac7e |
}
|
|
|
e6ac7e |
- debugs(5,4, "Abandoned " << abandonedClients << " client TCP SYN by closing socket: " << afd->conn);
|
|
|
e6ac7e |
+ debugs(5,4, "Not found " << afd->conn << " in queue, size: " << deferred_.size());
|
|
|
e6ac7e |
}
|
|
|
e6ac7e |
|
|
|
e6ac7e |
void
|
|
|
e6ac7e |
Comm::AcceptLimiter::kick()
|
|
|
e6ac7e |
{
|
|
|
e6ac7e |
- // TODO: this could be optimized further with an iterator to search
|
|
|
e6ac7e |
- // looking for first non-NULL, followed by dumping the first N
|
|
|
e6ac7e |
- // with only one shift()/pop_front operation
|
|
|
e6ac7e |
- // OR, by reimplementing as a list instead of Vector.
|
|
|
e6ac7e |
-
|
|
|
e6ac7e |
debugs(5, 5, "size=" << deferred_.size());
|
|
|
e6ac7e |
- while (deferred_.size() > 0 && fdNFree() >= RESERVED_FD) {
|
|
|
e6ac7e |
+ while (deferred_.size() > 0 && Comm::TcpAcceptor::okToAccept()) {
|
|
|
e6ac7e |
/* NP: shift() is equivalent to pop_front(). Giving us a FIFO queue. */
|
|
|
e6ac7e |
TcpAcceptor::Pointer temp = deferred_.front();
|
|
|
e6ac7e |
deferred_.erase(deferred_.begin());
|
|
|
e6ac7e |
if (temp.valid()) {
|
|
|
e6ac7e |
debugs(5, 5, "doing one.");
|
|
|
e6ac7e |
- -- temp->isLimited;
|
|
|
e6ac7e |
temp->acceptNext();
|
|
|
e6ac7e |
break;
|
|
|
e6ac7e |
}
|
|
|
e6ac7e |
diff -up squid-3.5.20/src/comm/AcceptLimiter.h.02396660 squid-3.5.20/src/comm/AcceptLimiter.h
|
|
|
e6ac7e |
--- squid-3.5.20/src/comm/AcceptLimiter.h.02396660 2019-06-05 13:18:27.000000000 +0200
|
|
|
e6ac7e |
+++ squid-3.5.20/src/comm/AcceptLimiter.h 2019-06-05 13:22:09.000000000 +0200
|
|
|
e6ac7e |
@@ -11,7 +11,7 @@
|
|
|
e6ac7e |
|
|
|
e6ac7e |
#include "comm/TcpAcceptor.h"
|
|
|
e6ac7e |
|
|
|
e6ac7e |
-#include <vector>
|
|
|
e6ac7e |
+#include <deque>
|
|
|
e6ac7e |
|
|
|
e6ac7e |
namespace Comm
|
|
|
e6ac7e |
{
|
|
|
e6ac7e |
@@ -26,16 +26,6 @@ namespace Comm
|
|
|
e6ac7e |
* removeDead - used only by Comm layer ConnAcceptor to remove themselves when dying.
|
|
|
e6ac7e |
* kick - used by Comm layer when FD are closed.
|
|
|
e6ac7e |
*/
|
|
|
e6ac7e |
-/* TODO this algorithm can be optimized further:
|
|
|
e6ac7e |
- *
|
|
|
e6ac7e |
- * 1) reduce overheads by only pushing one entry per port to the list?
|
|
|
e6ac7e |
- * use TcpAcceptor::isLimited as a flag whether to re-list when kick()'ing
|
|
|
e6ac7e |
- * or to NULL an entry while scanning the list for empty spaces.
|
|
|
e6ac7e |
- * Side effect: TcpAcceptor->kick() becomes allowed to pull off multiple accept()'s in bunches
|
|
|
e6ac7e |
- *
|
|
|
e6ac7e |
- * 2) re-implement as a std::queue instead of std::vector
|
|
|
e6ac7e |
- * storing head/tail pointers for fast push/pop and avoiding the whole shift() overhead
|
|
|
e6ac7e |
- */
|
|
|
e6ac7e |
class AcceptLimiter
|
|
|
e6ac7e |
{
|
|
|
e6ac7e |
|
|
|
e6ac7e |
@@ -56,7 +46,7 @@ private:
|
|
|
e6ac7e |
static AcceptLimiter Instance_;
|
|
|
e6ac7e |
|
|
|
e6ac7e |
/** FIFO queue */
|
|
|
e6ac7e |
- std::vector<TcpAcceptor::Pointer> deferred_;
|
|
|
e6ac7e |
+ std::deque<TcpAcceptor::Pointer> deferred_;
|
|
|
e6ac7e |
};
|
|
|
e6ac7e |
|
|
|
e6ac7e |
}; // namepace Comm
|
|
|
e6ac7e |
diff -up squid-3.5.20/src/comm/TcpAcceptor.cc.02396660 squid-3.5.20/src/comm/TcpAcceptor.cc
|
|
|
e6ac7e |
--- squid-3.5.20/src/comm/TcpAcceptor.cc.02396660 2019-06-05 13:18:49.000000000 +0200
|
|
|
e6ac7e |
+++ squid-3.5.20/src/comm/TcpAcceptor.cc 2019-06-05 13:23:49.000000000 +0200
|
|
|
e6ac7e |
@@ -41,7 +41,6 @@ CBDATA_NAMESPACED_CLASS_INIT(Comm, TcpAc
|
|
|
e6ac7e |
Comm::TcpAcceptor::TcpAcceptor(const Comm::ConnectionPointer &newConn, const char *note, const Subscription::Pointer &aSub) :
|
|
|
e6ac7e |
AsyncJob("Comm::TcpAcceptor"),
|
|
|
e6ac7e |
errcode(0),
|
|
|
e6ac7e |
- isLimited(0),
|
|
|
e6ac7e |
theCallSub(aSub),
|
|
|
e6ac7e |
conn(newConn),
|
|
|
e6ac7e |
listenPort_()
|
|
|
e6ac7e |
@@ -50,7 +49,6 @@ Comm::TcpAcceptor::TcpAcceptor(const Com
|
|
|
e6ac7e |
Comm::TcpAcceptor::TcpAcceptor(const AnyP::PortCfgPointer &p, const char *note, const Subscription::Pointer &aSub) :
|
|
|
e6ac7e |
AsyncJob("Comm::TcpAcceptor"),
|
|
|
e6ac7e |
errcode(0),
|
|
|
e6ac7e |
- isLimited(0),
|
|
|
e6ac7e |
theCallSub(aSub),
|
|
|
e6ac7e |
conn(p->listenConn),
|
|
|
e6ac7e |
listenPort_(p)
|
|
|
e6ac7e |
@@ -227,7 +225,6 @@ Comm::TcpAcceptor::doAccept(int fd, void
|
|
|
e6ac7e |
} else {
|
|
|
e6ac7e |
afd->acceptNext();
|
|
|
e6ac7e |
}
|
|
|
e6ac7e |
- SetSelect(fd, COMM_SELECT_READ, Comm::TcpAcceptor::doAccept, afd, 0);
|
|
|
e6ac7e |
|
|
|
e6ac7e |
} catch (const std::exception &e) {
|
|
|
e6ac7e |
fatalf("FATAL: error while accepting new client connection: %s\n", e.what());
|
|
|
e6ac7e |
@@ -286,6 +283,7 @@ Comm::TcpAcceptor::acceptOne()
|
|
|
e6ac7e |
" accepted new connection " << newConnDetails <<
|
|
|
e6ac7e |
" handler Subscription: " << theCallSub);
|
|
|
e6ac7e |
notify(flag, newConnDetails);
|
|
|
e6ac7e |
+ SetSelect(conn->fd, COMM_SELECT_READ, doAccept, this, 0);
|
|
|
e6ac7e |
}
|
|
|
e6ac7e |
|
|
|
e6ac7e |
void
|
|
|
e6ac7e |
diff -up squid-3.5.20/src/comm/TcpAcceptor.h.02396660 squid-3.5.20/src/comm/TcpAcceptor.h
|
|
|
e6ac7e |
--- squid-3.5.20/src/comm/TcpAcceptor.h.02396660 2019-06-05 13:18:57.000000000 +0200
|
|
|
e6ac7e |
+++ squid-3.5.20/src/comm/TcpAcceptor.h 2019-06-05 13:25:05.000000000 +0200
|
|
|
e6ac7e |
@@ -74,9 +74,12 @@ public:
|
|
|
e6ac7e |
/// errno code of the last accept() or listen() action if one occurred.
|
|
|
e6ac7e |
int errcode;
|
|
|
e6ac7e |
|
|
|
e6ac7e |
+ /// Method to test if there are enough file descriptors to open a new client connection
|
|
|
e6ac7e |
+ /// if not the accept() will be postponed
|
|
|
e6ac7e |
+ static bool okToAccept();
|
|
|
e6ac7e |
+
|
|
|
e6ac7e |
protected:
|
|
|
e6ac7e |
friend class AcceptLimiter;
|
|
|
e6ac7e |
- int32_t isLimited; ///< whether this socket is delayed and on the AcceptLimiter queue.
|
|
|
e6ac7e |
|
|
|
e6ac7e |
private:
|
|
|
e6ac7e |
Subscription::Pointer theCallSub; ///< used to generate AsyncCalls handling our events.
|
|
|
e6ac7e |
@@ -91,10 +94,6 @@ private:
|
|
|
e6ac7e |
/// listen socket closure handler
|
|
|
e6ac7e |
AsyncCall::Pointer closer_;
|
|
|
e6ac7e |
|
|
|
e6ac7e |
- /// Method to test if there are enough file descriptors to open a new client connection
|
|
|
e6ac7e |
- /// if not the accept() will be postponed
|
|
|
e6ac7e |
- static bool okToAccept();
|
|
|
e6ac7e |
-
|
|
|
e6ac7e |
/// Method callback for whenever an FD is ready to accept a client connection.
|
|
|
e6ac7e |
static void doAccept(int fd, void *data);
|
|
|
e6ac7e |
|