The unified diff between revisions [a8f17161..] and [4d68673c..] is displayed below. It can also be downloaded as a raw diff.
#
#
# patch "include/autoconf.h.in"
# from [8eb88c7b2be03f205a474a72d77f991efb926408]
# to [e31503b186fbbd9d8929fc359d4f8854a0ae73ba]
#
# patch "src/HttpRequest.c"
# from [597291cfa1e0f424bbe5163a389fac4d3df15ca6]
# to [c7bf9949beedd2ef15ebf64c1e516d81aa8f2185]
#
# patch "src/client_side.c"
# from [88a65f4660b1ec5b9f8f47f165c77182055cc453]
# to [aeb1c49f1a704cceb4928f31ac6df0b91c200cad]
#
# patch "src/forward.c"
# from [e2fc1a6c5fd200cd0174d0c5c2743c0e2c4942be]
# to [bde01cf37e23444aea4910eed79e76d3371277fb]
#
# patch "src/http.c"
# from [b0bbfbeb452d1642a4dc436c4c59565fd7a66354]
# to [69d4e2cd7969e575f5cdba81916aab1f9b2c6223]
#
# patch "src/pconn.c"
# from [29ed4b99506a1610a2e266faf97e49fc4f027913]
# to [5f83c46e535d572c2a6d6f55389e635926c3feee]
#
# patch "src/protos.h"
# from [0415ef0095c3ae7a42ac90385638ebe76af6d316]
# to [d924404fa81b7d01e6af2836d2ff9e49c5ddabcd]
#
# patch "src/structs.h"
# from [cc6dcb3d613d4ba93f19194205ec9916efd19e7d]
# to [8c514b042f35f6fd32b0a73cf21a9643cf2d6cd4]
#
============================================================
--- include/autoconf.h.in 8eb88c7b2be03f205a474a72d77f991efb926408
+++ include/autoconf.h.in e31503b186fbbd9d8929fc359d4f8854a0ae73ba
@@ -154,6 +154,11 @@
#define USE_WCCP 1
/*
+ * Define to enable WCCPv2
+ */
+#define USE_WCCPv2 1
+
+/*
* Define this to include code which lets you specify access control
* elements based on ethernet hardware addresses. This code uses
* functions found in 4.4 BSD derviations (e.g. FreeBSD, ?).
============================================================
--- src/HttpRequest.c 597291cfa1e0f424bbe5163a389fac4d3df15ca6
+++ src/HttpRequest.c c7bf9949beedd2ef15ebf64c1e516d81aa8f2185
@@ -67,9 +67,6 @@ requestDestroy(request_t * req)
httpHdrCcDestroy(req->cache_control);
if (req->range)
httpHdrRangeDestroy(req->range);
- if (req->pinned_connection)
- cbdataUnlock(req->pinned_connection);
- req->pinned_connection = NULL;
memFree(req, MEM_REQUEST_T);
}
============================================================
--- src/client_side.c 88a65f4660b1ec5b9f8f47f165c77182055cc453
+++ src/client_side.c aeb1c49f1a704cceb4928f31ac6df0b91c200cad
@@ -965,8 +965,6 @@ connStateFree(int fd, void *data)
safe_free(connState->in.buf);
/* XXX account connState->in.buf */
pconnHistCount(0, connState->nrequests);
- if (connState->pinning.fd >= 0)
- comm_close(connState->pinning.fd);
cbdataFree(connState);
#ifdef _SQUID_LINUX_
/* prevent those nasty RST packets */
@@ -1035,32 +1033,10 @@ clientInterpretRequestHeaders(clientHttp
if (request->range)
request->flags.range = 1;
}
- if (http->conn->pinning.fd != -1) {
+ if ((httpHeaderHas(req_hdr, HDR_AUTHORIZATION)) || (request->flags.pinned))
request->flags.auth = 1;
- request->pinned_connection = http->conn;
- cbdataLock(request->pinned_connection);
- } else if (httpHeaderHas(req_hdr, HDR_AUTHORIZATION)) {
- HttpHeaderPos pos = HttpHeaderInitPos;
- HttpHeaderEntry *e;
+ if (request->login[0] != '\0')
request->flags.auth = 1;
- if (!Config.onoff.pipeline_prefetch) {
- while ((e = httpHeaderGetEntry(req_hdr, &pos))) {
- if (e->id == HDR_AUTHORIZATION) {
- const char *value = strBuf(e->value);
- if ((strncasecmp(value, "NTLM", 4) == 0 &&
- (value[4] == '\0' || value[4] == ' '))
- ||
- (strncasecmp(value, "Negotiate", 9) == 0 &&
- (value[9] == '\0' || value[9] == ' '))) {
- request->pinned_connection = http->conn;
- cbdataLock(request->pinned_connection);
- break;
- }
- }
- }
- }
- } else if (request->login[0] != '\0')
- request->flags.auth = 1;
if (httpHeaderHas(req_hdr, HDR_VIA)) {
String s = httpHeaderGetList(req_hdr, HDR_VIA);
/*
@@ -1470,6 +1446,7 @@ clientBuildReplyHeader(clientHttpRequest
(value[9] == '\0' || value[9] == ' '))) {
httpHeaderPutStr(hdr, HDR_PROXY_SUPPORT, "Session-Based-Authentication");
httpHeaderPutStr(hdr, HDR_CONNECTION, "Proxy-support");
+ request->flags.pinned=1;
break;
}
}
@@ -2194,11 +2171,6 @@ clientKeepaliveNextRequest(clientHttpReq
debug(33, 3) ("clientKeepaliveNextRequest: FD %d\n", conn->fd);
conn->defer.until = 0; /* Kick it to read a new request */
httpRequestFree(http);
- if (conn->pinning.pinned && conn->pinning.fd == -1) {
- debug(33, 2) ("clientKeepaliveNextRequest: FD %d Connection was pinned but server side gone. Terminating client connection\n", conn->fd);
- comm_close(conn->fd);
- return;
- }
if ((http = conn->chr) == NULL) {
debug(33, 5) ("clientKeepaliveNextRequest: FD %d reading next req\n",
conn->fd);
@@ -3608,7 +3580,6 @@ httpAccept(int sock, void *data)
connState->fd = fd;
connState->in.size = CLIENT_REQ_BUF_SZ;
connState->in.buf = memAllocate(MEM_CLIENT_REQ_BUF);
- connState->pinning.fd = -1;
/* XXX account connState->in.buf */
comm_add_close_handler(fd, connStateFree, connState);
if (Config.onoff.log_fqdn)
@@ -4025,26 +3996,3 @@ varyEvaluateMatch(StoreEntry * entry, re
}
}
}
-
-/* This is a handler normally called by comm_close() */
-static void
-clientPinnedConnectionClosed(int fd, void *data)
-{
- ConnStateData *conn = data;
- conn->pinning.fd = -1;
- safe_free(conn->pinning.host);
- /* NOTE: pinning.pinned should be kept. This combined with fd == -1 indicates that the host connection has gone away */
-}
-
-void
-clientPinConnection(ConnStateData *conn, const char *host, int port, int fd)
-{
- if (conn->pinning.fd == fd)
- return;
- assert(conn->pinning.fd == -1);
- conn->pinning.fd = fd;
- conn->pinning.host = xstrdup(host);
- conn->pinning.port = port;
- conn->pinning.pinned = 1;
- comm_add_close_handler(fd, clientPinnedConnectionClosed, conn);
-}
============================================================
--- src/forward.c e2fc1a6c5fd200cd0174d0c5c2743c0e2c4942be
+++ src/forward.c bde01cf37e23444aea4910eed79e76d3371277fb
@@ -150,7 +150,7 @@ fwdCheckRetry(FwdState * fwdState)
return 0;
if (fwdState->request->flags.body_sent)
return 0;
- if (fwdState->request->pinned_connection)
+ if (fwdState->request->flags.pinned)
return 0;
return 1;
}
@@ -345,19 +345,6 @@ getOutgoingTOS(request_t * request)
return aclMapTOS(Config.accessList.outgoing_tos, &ch);
}
-static int
-getPinnedFD(ConnStateData *conn, request_t *request)
-{
- if (conn->pinning.fd < 0)
- return -1;
- if (strcasecmp(conn->pinning.host, request->host) != 0)
- return -1;
- if (conn->pinning.port != request->port)
- return -1;
-
- return conn->pinning.fd;
-}
-
static void
fwdConnectStart(void *data)
{
@@ -372,12 +359,21 @@ fwdConnectStart(void *data)
int ftimeout = Config.Timeout.forward - (squid_curtime - fwdState->start);
struct in_addr outgoing;
unsigned short tos;
- struct in_addr *local=NULL;
+ struct in_addr *client_addr=NULL;
+ u_short client_port=0;
#if LINUX_TPROXY
struct in_tproxy itp;
+#endif
- if ( Config.onoff.linux_tproxy )
- local=&fwdState->src.sin_addr;
+ if(fwdState->request->flags.pinned) {
+ client_addr=&fwdState->request->client_addr;
+ client_port=fwdState->request->client_port;
+ }
+#if LINUX_TPROXY
+ else if ( ( Config.onoff.linux_tproxy ) &&
+ ( (fwdState->request->my_port == Config.tproxy_port) || (Config.tproxy_port == 0) )) {
+ client_addr=&fwdState->request->client_addr;
+ }
#endif
assert(fs);
@@ -402,20 +398,7 @@ fwdConnectStart(void *data)
ftimeout = 5;
if (ftimeout < ctimeout)
ctimeout = ftimeout;
- if (fwdState->request->pinned_connection) {
- fd = getPinnedFD(fwdState->request->pinned_connection, fwdState->request);
- if (fd < 0) {
- debug(17, 1) ("fwdConnectStart: Pinned connection to %s:%d gone, aborting request\n", fwdState->request->host, fwdState->request->port);
- storeAbort(fwdState->entry);
- return;
- }
- fwdState->server_fd = fd;
- fwdState->n_tries++;
- comm_add_close_handler(fd, fwdServerClosed, fwdState);
- fwdConnectDone(fd, COMM_OK, fwdState);
- return;
- }
- if ((fd = pconnPop(host, port, local)) >= 0) {
+ if ((fd = pconnPop(host, port, client_addr, client_port)) >= 0) {
if (fwdCheckRetriable(fwdState)) {
debug(17, 3) ("fwdConnectStart: reusing pconn FD %d\n", fd);
fwdState->server_fd = fd;
============================================================
--- src/http.c b0bbfbeb452d1642a4dc436c4c59565fd7a66354
+++ src/http.c 69d4e2cd7969e575f5cdba81916aab1f9b2c6223
@@ -550,30 +550,6 @@ httpPconnTransferDone(HttpStateData * ht
return 1;
}
-/* Small helper function to verify if connection pinning is supported or not
- */
-static int
-peer_supports_connection_pinning(HttpStateData *httpState)
-{
- const HttpReply *rep = httpState->entry->mem_obj->reply;
- const HttpHeader *hdr = &rep->header;
- int rc;
- String header;
-
- if (!httpState->peer)
- return 1;
-
- if (!httpHeaderHas(hdr, HDR_PROXY_SUPPORT))
- return 0;
-
- header = httpHeaderGetStrOrList(hdr, HDR_PROXY_SUPPORT);
- /* XXX This ought to be done in a case-insensitive manner */
- rc = (strStr(header, "Session-Based-Authentication") != NULL);
- stringClean(&header);
-
- return rc;
-}
-
/* This will be called when data is ready to be read from fd. Read until
* error or connection closed. */
/* XXX this function is too long! */
@@ -588,7 +564,8 @@ httpReadReply(int fd, void *data)
int bin;
int clen;
size_t read_sz = SQUID_TCP_SO_RCVBUF;
- struct in_addr *local=NULL;
+ struct in_addr *client_addr=NULL;
+ u_short client_port=0;
#if DELAY_POOLS
delay_id delay_id;
#endif
@@ -604,10 +581,15 @@ httpReadReply(int fd, void *data)
else
delay_id = delayMostBytesAllowed(entry->mem_obj, &read_sz);
#endif
-
+ if ( httpState->request->flags.pinned ) {
+ client_addr=&httpState->request->client_addr;
+ client_port=httpState->request->client_port;
+ }
#if LINUX_TPROXY
- if ( Config.onoff.linux_tproxy )
- local=&httpState->request->client_addr;
+ else if ( ( Config.onoff.linux_tproxy ) &&
+ ( (httpState->request->my_port == Config.tproxy_port) || (Config.tproxy_port == 0) )) {
+ client_addr=&httpState->request->client_addr;
+ }
#endif
errno = 0;
@@ -769,12 +751,10 @@ httpReadReply(int fd, void *data)
#endif
comm_remove_close_handler(fd, httpStateFree, httpState);
fwdUnregister(fd, httpState->fwd);
- if (request->pinned_connection && peer_supports_connection_pinning(httpState))
- clientPinConnection(request->pinned_connection, request->host, request->port, fd);
- else if (request->flags.accelerated && Config.Accel.single_host && Config.Accel.host)
- pconnPush(fd, Config.Accel.host, Config.Accel.port, local);
+ if (request->flags.accelerated && Config.Accel.single_host && Config.Accel.host)
+ pconnPush(fd, Config.Accel.host, Config.Accel.port, client_addr, client_port);
else
- pconnPush(fd, request->host, request->port, local);
+ pconnPush(fd, request->host, request->port, client_addr, client_port);
fwdComplete(httpState->fwd);
httpState->fd = -1;
httpStateFree(fd, httpState);
============================================================
--- src/pconn.c 29ed4b99506a1610a2e266faf97e49fc4f027913
+++ src/pconn.c 5f83c46e535d572c2a6d6f55389e635926c3feee
@@ -57,16 +57,16 @@ static MemPool *pconn_fds_pool = NULL;
static MemPool *pconn_data_pool = NULL;
static MemPool *pconn_fds_pool = NULL;
-#define PCONN_KEYLEN (SQUIDHOSTNAMELEN + 24)
+#define PCONN_KEYLEN (SQUIDHOSTNAMELEN + 30)
static inline const int
-pconnKey(char *buf, const char *peer, u_short port, struct in_addr *local)
+pconnKey(char *buf, const char *peer, u_short port, struct in_addr *client_address, u_short client_port)
{
- if ( local == NULL ) {
+ if ( client_address == NULL ) {
return snprintf(buf, PCONN_KEYLEN, "%s.%d", peer, (int) port);
}else{
- return snprintf(buf, PCONN_KEYLEN, "%s.%d.%s",
- peer, (int) port, inet_ntoa(*local));
+ return snprintf(buf, PCONN_KEYLEN, "%s.%d.%s.%d",
+ peer, (int) port, inet_ntoa(*client_address), (int) client_port);
}
}
@@ -188,7 +188,7 @@ void
}
void
-pconnPush(int fd, const char *peer, u_short port, struct in_addr *local)
+pconnPush(int fd, const char *peer, u_short port, struct in_addr *client_address, u_short client_port)
{
struct _pconn *p;
int *old;
@@ -203,7 +203,7 @@ pconnPush(int fd, const char *peer, u_sh
return;
}
assert(table != NULL);
- pconnKey(key, peer, port, local);
+ pconnKey(key, peer, port, client_address, client_port);
p = (struct _pconn *) hash_lookup(table, key);
if (p == NULL)
p = pconnNew(key);
@@ -227,14 +227,14 @@ int
}
int
-pconnPop(const char *peer, u_short port, struct in_addr *local)
+pconnPop(const char *peer, u_short port, struct in_addr *client_address, u_short client_port)
{
struct _pconn *p;
hash_link *hptr;
int fd = -1;
LOCAL_ARRAY(char, key, PCONN_KEYLEN);
assert(table != NULL);
- pconnKey(key, peer, port, local);
+ pconnKey(key, peer, port, client_address, client_port);
hptr = hash_lookup(table, key);
if (hptr != NULL) {
p = (struct _pconn *) hptr;
============================================================
--- src/protos.h 0415ef0095c3ae7a42ac90385638ebe76af6d316
+++ src/protos.h d924404fa81b7d01e6af2836d2ff9e49c5ddabcd
@@ -141,7 +141,6 @@ extern int isTcpHit(log_type);
extern void clientHttpConnectionsClose(void);
extern StoreEntry *clientCreateStoreEntry(clientHttpRequest *, method_t, request_flags);
extern int isTcpHit(log_type);
-extern void clientPinConnection(ConnStateData *conn, const char *host, int port, int fd);
extern int commSetNonBlocking(int fd);
extern int commUnsetNonBlocking(int fd);
@@ -1147,8 +1146,8 @@ extern ErrorState *errorCon(err_type typ
extern int errorReservePageId(const char *page_name);
extern ErrorState *errorCon(err_type type, http_status);
-extern void pconnPush(int, const char *peer, u_short port, struct in_addr *local);
-extern int pconnPop(const char *peer, u_short port, struct in_addr *local);
+extern void pconnPush(int, const char *peer, u_short port, struct in_addr *client_address, u_short client_port);
+extern int pconnPop(const char *peer, u_short port, struct in_addr *client_address, u_short client_port);
extern void pconnInit(void);
extern int asnMatchIp(void *, struct in_addr);
============================================================
--- src/structs.h cc6dcb3d613d4ba93f19194205ec9916efd19e7d
+++ src/structs.h 8c514b042f35f6fd32b0a73cf21a9643cf2d6cd4
@@ -1168,12 +1168,6 @@ struct _ConnStateData {
int n;
time_t until;
} defer;
- struct {
- int fd; /* pinned server side connection */
- char *host; /* host name of pinned connection */
- int port; /* port of pinned connection */
- int pinned; /* this connection was pinned */
- } pinning;
};
struct _ipcache_addrs {
@@ -1669,6 +1663,7 @@ struct _request_flags {
unsigned int body_sent:1;
unsigned int reset_tcp:1;
unsigned int must_keepalive:1;
+ unsigned int pinned:1; /* If set, this request is tightly tied to a client-side connection */
};
struct _link_list {
@@ -1727,7 +1722,6 @@ struct _request_t {
const char *vary_headers; /* Used when varying entities are detected. Changes how the store key is calculated */
BODY_HANDLER *body_reader;
void *body_reader_data;
- ConnStateData *pinned_connection; /* If set then this request is tighly tied to the corresponding client side connetion */
};
struct _cachemgr_passwd {