============================================================
--- src/HttpHeader.c	f130fccd6139140980f19965058577fb573780f7
+++ src/HttpHeader.c	ad0e2fa0c182a0de43098501794c580de94bcd8d
@@ -105,6 +105,7 @@
     {"Proxy-Authentication-Info", HDR_PROXY_AUTHENTICATION_INFO, ftStr},
     {"Proxy-Authorization", HDR_PROXY_AUTHORIZATION, ftStr},
     {"Proxy-Connection", HDR_PROXY_CONNECTION, ftStr},
+    {"Proxy-support", HDR_PROXY_SUPPORT, ftStr},
     {"Public", HDR_PUBLIC, ftStr},
     {"Range", HDR_RANGE, ftPRange},
     {"Referer", HDR_REFERER, ftStr},
@@ -151,6 +152,7 @@
     HDR_IF_MATCH, HDR_IF_NONE_MATCH,
     HDR_LINK, HDR_PRAGMA,
     HDR_PROXY_CONNECTION,
+    HDR_PROXY_SUPPORT,
     HDR_TRANSFER_ENCODING,
     HDR_UPGRADE,
     HDR_VARY,
============================================================
--- src/client_side.c	612eaa9339b03fb38a570b1f7c846f2da9d19a50
+++ src/client_side.c	aeb1c49f1a704cceb4928f31ac6df0b91c200cad
@@ -373,6 +373,7 @@
 	new_request->http_ver = old_request->http_ver;
 	httpHeaderAppend(&new_request->header, &old_request->header);
 	new_request->client_addr = old_request->client_addr;
+	new_request->client_port = old_request->client_port;
 	new_request->my_addr = old_request->my_addr;
 	new_request->my_port = old_request->my_port;
 	new_request->flags = old_request->flags;
@@ -1032,7 +1033,7 @@
 	if (request->range)
 	    request->flags.range = 1;
     }
-    if (httpHeaderHas(req_hdr, HDR_AUTHORIZATION))
+    if ((httpHeaderHas(req_hdr, HDR_AUTHORIZATION)) || (request->flags.pinned))
 	request->flags.auth = 1;
     if (request->login[0] != '\0')
 	request->flags.auth = 1;
@@ -1442,8 +1443,12 @@
 			(value[4] == '\0' || value[4] == ' '))
 		    ||
 		    (strncasecmp(value, "Negotiate", 9) == 0 &&
-			(value[9] == '\0' || value[9] == ' ')))
-		    httpHeaderDelAt(hdr, pos);
+			(value[9] == '\0' || value[9] == ' '))) {
+		    httpHeaderPutStr(hdr, HDR_PROXY_SUPPORT, "Session-Based-Authentication");
+		    httpHeaderPutStr(hdr, HDR_CONNECTION, "Proxy-support");
+		    request->flags.pinned=1;
+		    break;
+		}
 	    }
 	}
     }
@@ -3202,6 +3207,7 @@
 	    safe_free(http->log_uri);
 	    http->log_uri = xstrdup(urlCanonicalClean(request));
 	    request->client_addr = conn->peer.sin_addr;
+	    request->client_port = conn->peer.sin_port;
 	    request->my_addr = conn->me.sin_addr;
 	    request->my_port = ntohs(conn->me.sin_port);
 	    request->http_ver = http->http_ver;
============================================================
--- src/enums.h	6689def91d90a86446f75e526b7a15306ac61594
+++ src/enums.h	d3225c7b17f9312bef8509d7dd1284df1f0fcf98
@@ -245,6 +245,7 @@
 #if X_ACCELERATOR_VARY
     HDR_X_ACCELERATOR_VARY,
 #endif
+    HDR_PROXY_SUPPORT,
     HDR_OTHER,
     HDR_ENUM_END
 } http_hdr_type;
============================================================
--- src/forward.c	eabf7a764371d5d1f1de54c194248c210bec17b5
+++ src/forward.c	bde01cf37e23444aea4910eed79e76d3371277fb
@@ -143,6 +150,8 @@
 	return 0;
     if (fwdState->request->flags.body_sent)
 	return 0;
+    if (fwdState->request->flags.pinned)
+	return 0;
     return 1;
 }
 
@@ -350,6 +359,14 @@
     int ftimeout = Config.Timeout.forward - (squid_curtime - fwdState->start);
     struct in_addr outgoing;
     unsigned short tos;
+    struct in_addr *client_addr=NULL;
+    u_short client_port=0;
+
+    if(fwdState->request->flags.pinned) {
+	client_addr=&fwdState->request->client_addr;
+	client_port=fwdState->request->client_port;
+    }
+
     assert(fs);
     assert(fwdState->server_fd == -1);
     debug(17, 3) ("fwdConnectStart: %s\n", url);
@@ -372,7 +398,7 @@
 	ftimeout = 5;
     if (ftimeout < ctimeout)
 	ctimeout = ftimeout;
-    if ((fd = pconnPop(host, port)) >= 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	70d4f23441904ca38b3b064cd5bf45b744af1370
+++ src/http.c	69d4e2cd7969e575f5cdba81916aab1f9b2c6223
@@ -564,6 +564,8 @@
     int bin;
     int clen;
     size_t read_sz = SQUID_TCP_SO_RCVBUF;
+    struct in_addr *client_addr=NULL;
+    u_short client_port=0;
 #if DELAY_POOLS
     delay_id delay_id;
 #endif
@@ -579,6 +581,11 @@
     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;
+    }
+
     errno = 0;
     statCounter.syscalls.sock.reads++;
     len = FD_READ_METHOD(fd, buf, read_sz);
@@ -739,9 +752,9 @@
 		    comm_remove_close_handler(fd, httpStateFree, httpState);
 		    fwdUnregister(fd, httpState->fwd);
 		    if (request->flags.accelerated && Config.Accel.single_host && Config.Accel.host)
-			pconnPush(fd, Config.Accel.host, Config.Accel.port);
+			pconnPush(fd, Config.Accel.host, Config.Accel.port, client_addr, client_port);
 		    else
-			pconnPush(fd, request->host, request->port);
+			pconnPush(fd, request->host, request->port, client_addr, client_port);
 		    fwdComplete(httpState->fwd);
 		    httpState->fd = -1;
 		    httpStateFree(fd, httpState);
============================================================
--- src/pconn.c	b92717711418c48f60d127e43fea65752a667d66
+++ src/pconn.c	5f83c46e535d572c2a6d6f55389e635926c3feee
@@ -49,7 +49,6 @@
 
 static PF pconnRead;
 static PF pconnTimeout;
-static const char *pconnKey(const char *host, u_short port);
 static hash_table *table = NULL;
 static struct _pconn *pconnNew(const char *key);
 static void pconnDelete(struct _pconn *p);
@@ -58,12 +57,17 @@
 static MemPool *pconn_data_pool = NULL;
 static MemPool *pconn_fds_pool = NULL;
 
-static const char *
-pconnKey(const char *host, u_short port)
+#define PCONN_KEYLEN (SQUIDHOSTNAMELEN + 30)
+
+static inline const int
+pconnKey(char *buf, const char *peer, u_short port, struct in_addr *client_address, u_short client_port)
 {
-    LOCAL_ARRAY(char, buf, SQUIDHOSTNAMELEN + 10);
-    snprintf(buf, SQUIDHOSTNAMELEN + 10, "%s.%d", host, (int) port);
-    return buf;
+    if ( client_address == NULL ) {
+        return snprintf(buf, PCONN_KEYLEN, "%s.%d", peer, (int) port);
+    }else{
+        return snprintf(buf, PCONN_KEYLEN, "%s.%d.%s.%d",
+		peer, (int) port, inet_ntoa(*client_address), (int) client_port);
+    }
 }
 
 static struct _pconn *
@@ -184,11 +188,11 @@
 }
 
 void
-pconnPush(int fd, const char *host, u_short port)
+pconnPush(int fd, const char *peer, u_short port, struct in_addr *client_address, u_short client_port)
 {
     struct _pconn *p;
     int *old;
-    LOCAL_ARRAY(char, key, SQUIDHOSTNAMELEN + 10);
+    LOCAL_ARRAY(char, key, PCONN_KEYLEN);
     LOCAL_ARRAY(char, desc, FD_DESC_SZ);
     if (fdUsageHigh()) {
 	debug(48, 3) ("pconnPush: Not many unused FDs\n");
@@ -199,7 +203,7 @@
 	return;
     }
     assert(table != NULL);
-    strcpy(key, pconnKey(host, port));
+    pconnKey(key, peer, port, client_address, client_port);
     p = (struct _pconn *) hash_lookup(table, key);
     if (p == NULL)
 	p = pconnNew(key);
@@ -217,20 +221,20 @@
     p->fds[p->nfds++] = fd;
     commSetSelect(fd, COMM_SELECT_READ, pconnRead, p, 0);
     commSetTimeout(fd, Config.Timeout.pconn, pconnTimeout, p);
-    snprintf(desc, FD_DESC_SZ, "%s idle connection", host);
+    snprintf(desc, FD_DESC_SZ, "%s idle connection", peer);
     fd_note(fd, desc);
     debug(48, 3) ("pconnPush: pushed FD %d for %s\n", fd, key);
 }
 
 int
-pconnPop(const char *host, u_short port)
+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, SQUIDHOSTNAMELEN + 10);
+    LOCAL_ARRAY(char, key, PCONN_KEYLEN);
     assert(table != NULL);
-    strcpy(key, pconnKey(host, port));
+    pconnKey(key, peer, port, client_address, client_port);
     hptr = hash_lookup(table, key);
     if (hptr != NULL) {
 	p = (struct _pconn *) hptr;
============================================================
--- src/protos.h	24cb1a4562e33e16ac98068a665abba386b418af
+++ src/protos.h	d924404fa81b7d01e6af2836d2ff9e49c5ddabcd
@@ -1139,8 +1146,8 @@
 extern int errorReservePageId(const char *page_name);
 extern ErrorState *errorCon(err_type type, http_status);
 
-extern void pconnPush(int, const char *host, u_short port);
-extern int pconnPop(const char *host, u_short port);
+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	825043409b63de2a3a51d8fb1a0af6faeb9e34eb
+++ src/structs.h	8c514b042f35f6fd32b0a73cf21a9643cf2d6cd4
@@ -1647,6 +1663,7 @@
     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 {
@@ -1692,6 +1709,7 @@
     int imslen;
     int max_forwards;
     /* these in_addr's could probably be sockaddr_in's */
+    in_port_t client_port;
     struct in_addr client_addr;
     struct in_addr my_addr;
     unsigned short my_port;
