FwdServer *fs = servers;
const char *host;
unsigned short port;
- const char *domain = NULL;
int ctimeout;
int ftimeout = Config.Timeout.forward - (squid_curtime - start_t);
#if LINUX_TPROXY
debugs(17, 3, "fwdConnectStart: " << url);
if (fs->_peer) {
- host = fs->_peer->host;
- port = fs->_peer->http_port;
ctimeout = fs->_peer->connect_timeout > 0 ? fs->_peer->connect_timeout
: Config.Timeout.peer_connect;
-
- if (fs->_peer->options.originserver)
- domain = request->host;
} else {
- host = request->host;
- port = request->port;
ctimeout = Config.Timeout.connect;
}
if (ftimeout < ctimeout)
ctimeout = ftimeout;
- fd = fwdPconnPool->pop(host, port, domain, client_addr, checkRetriable());
+ if(fs->_peer) {
+ host = fs->_peer->host;
+ port = fs->_peer->http_port;
+ fd = fwdPconnPool->pop(fs->_peer->name, fs->_peer->http_port, request->host, client_addr, checkRetriable());
+ }
+ else {
+ host = request->host;
+ port = request->port;
+ fd = fwdPconnPool->pop(host, port, NULL, client_addr, checkRetriable());
+ }
if (fd >= 0) {
debugs(17, 3, "fwdConnectStart: reusing pconn FD " << fd);
server_fd = fd;
/* NOTREACHED */
}
+/**
+ * Decide where details need to be gathered to correctly describe a persistent connection.
+ * What is needed:
+ * \item host name of server at other end of this link (either peer or requested host)
+ * \item port to which we connected the other end of this link (for peer or request)
+ * \item domain for which the connection is supposed to be used
+ * \item address of the client for which we made the connection
+ */
void
-
-FwdState::pconnPush(int fd, const char *host, int port, const char *domain, struct IN_ADDR *client_addr)
+FwdState::pconnPush(int fd, const peer *_peer, const HttpRequest *req, const char *domain, struct in_addr *client_addr)
{
- fwdPconnPool->push(fd, host, port, domain, client_addr);
+ if (_peer) {
+ fwdPconnPool->push(fd, _peer->name, _peer->http_port, domain, client_addr);
+ } else {
+ /* small performance improvement, using NULL for domain instead of listing it twice */
+ /* although this will leave a gap open for url-rewritten domains to share a link */
+ fwdPconnPool->push(fd, req->host, req->port, NULL, client_addr);
+ }
}
void
-
/*
- * $Id: pconn.cc,v 1.53.4.1 2008/02/24 12:06:41 amosjeffries Exp $
+ * $Id$
*
* DEBUG: section 48 Persistent Connections
* AUTHOR: Duane Wessels
PconnPool::key(const char *host, u_short port, const char *domain, struct IN_ADDR *client_address)
{
- LOCAL_ARRAY(char, buf, SQUIDHOSTNAMELEN * 2 + 10);
+ LOCAL_ARRAY(char, buf, SQUIDHOSTNAMELEN * 3 + 10);
if (domain && client_address)
- snprintf(buf, SQUIDHOSTNAMELEN * 2 + 10, "%s:%d-%s/%s", host, (int) port, inet_ntoa(*client_address), domain);
+ snprintf(buf, SQUIDHOSTNAMELEN * 3 + 10, "%s:%d-%s/%s", host, (int) port, inet_ntoa(*client_address), domain);
else if (domain && (!client_address))
- snprintf(buf, SQUIDHOSTNAMELEN * 2 + 10, "%s:%d/%s", host, (int) port, domain);
+ snprintf(buf, SQUIDHOSTNAMELEN * 3 + 10, "%s:%d/%s", host, (int) port, domain);
else if ((!domain) && client_address)
- snprintf(buf, SQUIDHOSTNAMELEN * 2 + 10, "%s:%d-%s", host, (int) port, inet_ntoa(*client_address));
+ snprintf(buf, SQUIDHOSTNAMELEN * 3 + 10, "%s:%d-%s", host, (int) port, inet_ntoa(*client_address));
else
- snprintf(buf, SQUIDHOSTNAMELEN * 2 + 10, "%s:%d", host, (int) port);
+ snprintf(buf, SQUIDHOSTNAMELEN * 3 + 10, "%s:%d", host, (int) port);
+ debugs(48,6,"PconnPool::key(" << host << "," << port << "," << domain << "," << inet_ntoa(*client_address) << "is {" << buf << "}" );
return buf;
}
}
}
+void
+PconnPool::dumpHash(StoreEntry *e)
+{
+ int i;
+ hash_link *walker = NULL;
+ hash_table *hid = table;
+ hash_first(hid);
+
+ for (i = 0, walker = hid->next; walker; walker = hash_next(hid)) {
+ storeAppendPrintf(e, "\t item %5d: %s\n", i++, (char *)(walker->key));
+ }
+}
+
/* ========== PconnPool PUBLIC FUNCTIONS ============================================ */
PconnPool::PconnPool(const char *aDescr) : table(NULL), descr(aDescr)
} else if (shutting_down)
{
comm_close(fd);
+ debugs(48, 3, "PconnPool::push: Squid is shutting down. Refusing to do anything");
return;
}
if (list == NULL)
{
list = new IdleConnList(aKey, this);
- debugs(48, 3, "pconnNew: adding " << hashKeyStr(&list->hash));
+ debugs(48, 3, "PconnPool::push: new IdleConnList for {" << hashKeyStr(&list->hash) << "}" );
hash_join(table, &list->hash);
+ } else {
+ debugs(48, 3, "PconnPool::push: found IdleConnList for {" << hashKeyStr(&list->hash) << "}" );
}
list->push(fd);
debugs(48, 3, "PconnPool::push: pushed FD " << fd << " for " << aKey);
}
-/*
+/**
* Return a pconn fd for host:port if available and retriable.
* Otherwise, return -1.
*
* transactions create persistent connections but are not retriable.
*/
int
-
-PconnPool::pop(const char *host, u_short port, const char *domain, struct IN_ADDR *client_address, bool isRetriable)
+PconnPool::pop(const char *host, u_short port, const char *domain, struct in_addr *client_address, bool isRetriable)
{
- IdleConnList *list;
const char * aKey = key(host, port, domain, client_address);
- list = (IdleConnList *)hash_lookup(table, aKey);
- if (list == NULL)
+ IdleConnList *list = (IdleConnList *)hash_lookup(table, aKey);
+ if (list == NULL) {
+ debugs(48, 3, "PconnPool::pop: lookup for key {" << aKey << "} failed.");
return -1;
+ } else {
+ debugs(48, 3, "PconnPool::pop: found " << hashKeyStr(&list->hash) << (isRetriable?"(to use)":"(to kill)") );
+ }
int fd = list->findUseableFD(); // search from the end. skip pending reads.
int i;
for (i = 0; i < poolCount; i++) {
+ storeAppendPrintf(e, "\n Pool %d Stats\n", i);
(*(pools+i))->dumpHist(e);
+ storeAppendPrintf(e, "\n Pool %d Hash Table\n",i);
+ (*(pools+i))->dumpHash(e);
}
}