time_t clientIdlePconn;
time_t serverIdlePconn;
time_t ftpClientIdle;
+ time_t pconnLifetime; ///< pconn_lifetime in squid.conf
time_t siteSelect;
time_t deadPeer;
int icp_query; /* msec */
request_timeout, persistent_request_timeout and quick_abort values.
DOC_END
+NAME: pconn_lifetime
+COMMENT: time-units
+TYPE: time_t
+LOC: Config.Timeout.pconnLifetime
+DEFAULT: 0 seconds
+DOC_START
+ Desired maximum lifetime of a persistent connection.
+ When set, Squid will close a now-idle persistent connection that
+ exceeded configured lifetime instead of moving the connection into
+ the idle connection pool (or equivalent). No effect on ongoing/active
+ transactions. Connection lifetime is the time period from the
+ connection acceptance or opening time until "now".
+
+ This limit is useful in environments with long-lived connections
+ where Squid configuration or environmental factors change during a
+ single connection lifetime. If unrestricted, some connections may
+ last for hours and even days, ignoring those changes that should
+ have affected their behavior or their existence.
+
+ Currently, a new lifetime value supplied via Squid reconfiguration
+ has no effect on already idle connections unless they become busy.
+
+ When set to '0' this limit is not used.
+DOC_END
+
NAME: half_closed_clients
TYPE: onoff
LOC: Config.onoff.half_closed_clients
typedef CommCbMemFunT<ConnStateData, CommTimeoutCbParams> TimeoutDialer;
AsyncCall::Pointer timeoutCall = JobCallback(33, 5,
TimeoutDialer, this, ConnStateData::requestTimeout);
- commSetConnTimeout(clientConnection, idleTimeout(), timeoutCall);
+ commSetConnTimeout(clientConnection, clientConnection->timeLeft(idleTimeout()), timeoutCall);
readSomeData();
/** Please don't do anything with the FD past here! */
if (concurrentRequestQueueFilled())
break;
+ /*Do not read more requests if persistent connection lifetime exceeded*/
+ if (Config.Timeout.pconnLifetime && clientConnection->lifeTime() > Config.Timeout.pconnLifetime) {
+ flags.readMore = false;
+ break;
+ }
+
// try to parse the PROXY protocol header magic bytes
if (needProxyProtocolHeader_ && !parseProxyProtocolHeader())
break;
// The peer wants to close the pinned connection
debugs(88, 3, "pinned reply forces close");
request->flags.proxyKeepalive = false;
- } else if (http->getConn() && http->getConn()->port->listenConn == NULL) {
- // The listening port closed because of a reconfigure
- debugs(88, 3, "listening port closed");
- request->flags.proxyKeepalive = false;
+ } else if (http->getConn()) {
+ ConnStateData * conn = http->getConn();
+ if (!Comm::IsConnOpen(conn->port->listenConn)) {
+ // The listening port closed because of a reconfigure
+ debugs(88, 3, "listening port closed");
+ request->flags.proxyKeepalive = false;
+ } else if (Config.Timeout.pconnLifetime && conn->clientConnection->lifeTime() > Config.Timeout.pconnLifetime && conn->getConcurrentRequestCount() <= 1) {
+ // The persistent connection lifetime exceeded and we are the last parsed request
+ debugs(88, 3, "persistent connection lifetime exceeded");
+ request->flags.proxyKeepalive = false;
+ }
}
// Decide if we send chunked reply
#include "comm/Connection.h"
#include "fde.h"
#include "neighbors.h"
+#include "SquidConfig.h"
#include "SquidTime.h"
class CachePeer;
}
}
+time_t
+Comm::Connection::timeLeft(const time_t idleTimeout) const
+{
+ if (!Config.Timeout.pconnLifetime)
+ return idleTimeout;
+
+ const time_t lifeTimeLeft = lifeTime() < Config.Timeout.pconnLifetime ? Config.Timeout.pconnLifetime - lifeTime() : 1;
+ return min(lifeTimeLeft, idleTimeout);
+}
/** The time the connection started */
time_t startTime() const {return startTime_;}
+ /** The connection lifetime */
+ time_t lifeTime() const {return squid_curtime - startTime_;}
+
+ /** The time left for this connection*/
+ time_t timeLeft(const time_t idleTimeout) const;
+
void noteStart() {startTime_ = squid_curtime;}
private:
/** These objects may not be exactly duplicated. Use copyDetails() instead. */
comm_read(conn, fakeReadBuf_, sizeof(fakeReadBuf_), readCall);
AsyncCall::Pointer timeoutCall = commCbCall(5,4, "IdleConnList::Timeout",
CommTimeoutCbPtrFun(IdleConnList::Timeout, this));
- commSetConnTimeout(conn, Config.Timeout.serverIdlePconn, timeoutCall);
+ commSetConnTimeout(conn, conn->timeLeft(Config.Timeout.serverIdlePconn), timeoutCall);
}
/// Determine whether an entry in the idle list is available for use.