--------------------- PatchSet 7122 Date: 2005/10/23 14:33:02 Author: hno Branch: pinning Tag: (none) Log: First stab at connection pinning. Actually seems to work, but needs to investigate if there is corner cases when the server aborts the connection.. Members: src/HttpHeader.c:1.10.6.24->1.10.6.24.2.1 src/HttpRequest.c:1.7.36.3->1.7.36.3.2.1 src/client_side.c:1.47.2.71->1.47.2.71.2.1 src/enums.h:1.29.2.17->1.29.2.17.2.1 src/forward.c:1.13.6.15->1.13.6.15.2.1 src/http.c:1.17.6.32->1.17.6.32.2.1 src/protos.h:1.41.6.33->1.41.6.33.2.1 src/structs.h:1.48.2.43->1.48.2.43.2.1 Index: squid/src/HttpHeader.c =================================================================== RCS file: /cvsroot/squid-sf//squid/src/HttpHeader.c,v retrieving revision 1.10.6.24 retrieving revision 1.10.6.24.2.1 diff -u -r1.10.6.24 -r1.10.6.24.2.1 --- squid/src/HttpHeader.c 10 Jun 2005 02:16:56 -0000 1.10.6.24 +++ squid/src/HttpHeader.c 23 Oct 2005 14:33:02 -0000 1.10.6.24.2.1 @@ -1,6 +1,6 @@ /* - * $Id: HttpHeader.c,v 1.10.6.24 2005/06/10 02:16:56 squidadm Exp $ + * $Id: HttpHeader.c,v 1.10.6.24.2.1 2005/10/23 14:33:02 hno Exp $ * * DEBUG: section 55 HTTP Header * AUTHOR: Alex Rousskov @@ -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}, Index: squid/src/HttpRequest.c =================================================================== RCS file: /cvsroot/squid-sf//squid/src/HttpRequest.c,v retrieving revision 1.7.36.3 retrieving revision 1.7.36.3.2.1 diff -u -r1.7.36.3 -r1.7.36.3.2.1 --- squid/src/HttpRequest.c 16 Sep 2005 02:13:25 -0000 1.7.36.3 +++ squid/src/HttpRequest.c 23 Oct 2005 14:33:03 -0000 1.7.36.3.2.1 @@ -1,6 +1,6 @@ /* - * $Id: HttpRequest.c,v 1.7.36.3 2005/09/16 02:13:25 squidadm Exp $ + * $Id: HttpRequest.c,v 1.7.36.3.2.1 2005/10/23 14:33:03 hno Exp $ * * DEBUG: section 73 HTTP Request * AUTHOR: Duane Wessels @@ -67,6 +67,9 @@ 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); } Index: squid/src/client_side.c =================================================================== RCS file: /cvsroot/squid-sf//squid/src/client_side.c,v retrieving revision 1.47.2.71 retrieving revision 1.47.2.71.2.1 diff -u -r1.47.2.71 -r1.47.2.71.2.1 --- squid/src/client_side.c 19 Oct 2005 02:13:20 -0000 1.47.2.71 +++ squid/src/client_side.c 23 Oct 2005 14:33:03 -0000 1.47.2.71.2.1 @@ -1,6 +1,6 @@ /* - * $Id: client_side.c,v 1.47.2.71 2005/10/19 02:13:20 squidadm Exp $ + * $Id: client_side.c,v 1.47.2.71.2.1 2005/10/23 14:33:03 hno Exp $ * * DEBUG: section 33 Client-side Routines * AUTHOR: Duane Wessels @@ -1027,9 +1027,31 @@ if (request->range) request->flags.range = 1; } - if (httpHeaderHas(req_hdr, HDR_AUTHORIZATION)) + if (http->conn->pinned_fd != -1) { request->flags.auth = 1; - if (request->login[0] != '\0') + request->pinned_connection = http->conn; + cbdataLock(request->pinned_connection); + } else if (httpHeaderHas(req_hdr, HDR_AUTHORIZATION)) { + HttpHeaderPos pos = HttpHeaderInitPos; + HttpHeaderEntry *e; + 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); @@ -1439,8 +1461,11 @@ (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"); + break; + } } } } @@ -2158,6 +2183,11 @@ debug(33, 3) ("clientKeepaliveNextRequest: FD %d\n", conn->fd); conn->defer.until = 0; /* Kick it to read a new request */ httpRequestFree(http); + if (conn->pinned && conn->pinned_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); @@ -3532,6 +3562,7 @@ connState->fd = fd; connState->in.size = CLIENT_REQ_BUF_SZ; connState->in.buf = memAllocate(MEM_CLIENT_REQ_BUF); + connState->pinned_fd = -1; /* XXX account connState->in.buf */ comm_add_close_handler(fd, connStateFree, connState); if (Config.onoff.log_fqdn) @@ -3948,3 +3979,22 @@ } } } + +/* This is a handler normally called by comm_close() */ +static void +clientPinnedConnectionClosed(int fd, void *data) +{ + ConnStateData *conn = data; + conn->pinned_fd = -1; +} + +void +clientPinConnection(ConnStateData *conn, int fd) +{ + if (conn->pinned_fd == fd) + return; + assert(conn->pinned_fd == -1); + conn->pinned_fd = fd; + conn->pinned = 1; + comm_add_close_handler(fd, clientPinnedConnectionClosed, conn); +} Index: squid/src/enums.h =================================================================== RCS file: /cvsroot/squid-sf//squid/src/enums.h,v retrieving revision 1.29.2.17 retrieving revision 1.29.2.17.2.1 diff -u -r1.29.2.17 -r1.29.2.17.2.1 --- squid/src/enums.h 21 Sep 2005 00:59:13 -0000 1.29.2.17 +++ squid/src/enums.h 23 Oct 2005 14:33:04 -0000 1.29.2.17.2.1 @@ -1,6 +1,6 @@ /* - * $Id: enums.h,v 1.29.2.17 2005/09/21 00:59:13 squidadm Exp $ + * $Id: enums.h,v 1.29.2.17.2.1 2005/10/23 14:33:04 hno Exp $ * * * SQUID Web Proxy Cache http://www.squid-cache.org/ @@ -245,6 +245,7 @@ #if X_ACCELERATOR_VARY HDR_X_ACCELERATOR_VARY, #endif + HDR_PROXY_SUPPORT, HDR_OTHER, HDR_ENUM_END } http_hdr_type; Index: squid/src/forward.c =================================================================== RCS file: /cvsroot/squid-sf//squid/src/forward.c,v retrieving revision 1.13.6.15 retrieving revision 1.13.6.15.2.1 diff -u -r1.13.6.15 -r1.13.6.15.2.1 --- squid/src/forward.c 2 Sep 2005 02:13:43 -0000 1.13.6.15 +++ squid/src/forward.c 23 Oct 2005 14:33:04 -0000 1.13.6.15.2.1 @@ -1,6 +1,6 @@ /* - * $Id: forward.c,v 1.13.6.15 2005/09/02 02:13:43 squidadm Exp $ + * $Id: forward.c,v 1.13.6.15.2.1 2005/10/23 14:33:04 hno Exp $ * * DEBUG: section 17 Request Forwarding * AUTHOR: Duane Wessels @@ -143,6 +143,8 @@ return 0; if (fwdState->request->flags.body_sent) return 0; + if (fwdState->request->pinned_connection) + return 0; return 1; } @@ -380,6 +382,14 @@ ftimeout = 5; if (ftimeout < ctimeout) ctimeout = ftimeout; + if (fwdState->request->pinned_connection && fwdState->request->pinned_connection->pinned_fd >= 0) { + fd = fwdState->request->pinned_connection->pinned_fd; + 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)) >= 0) { if (fwdCheckRetriable(fwdState)) { debug(17, 3) ("fwdConnectStart: reusing pconn FD %d\n", fd); Index: squid/src/http.c =================================================================== RCS file: /cvsroot/squid-sf//squid/src/http.c,v retrieving revision 1.17.6.32 retrieving revision 1.17.6.32.2.1 diff -u -r1.17.6.32 -r1.17.6.32.2.1 --- squid/src/http.c 19 Oct 2005 02:13:21 -0000 1.17.6.32 +++ squid/src/http.c 23 Oct 2005 14:33:04 -0000 1.17.6.32.2.1 @@ -1,6 +1,6 @@ /* - * $Id: http.c,v 1.17.6.32 2005/10/19 02:13:21 squidadm Exp $ + * $Id: http.c,v 1.17.6.32.2.1 2005/10/23 14:33:04 hno Exp $ * * DEBUG: section 11 Hypertext Transfer Protocol (HTTP) * AUTHOR: Harvest Derived @@ -738,7 +738,9 @@ #endif comm_remove_close_handler(fd, httpStateFree, httpState); fwdUnregister(fd, httpState->fwd); - if (request->flags.accelerated && Config.Accel.single_host && Config.Accel.host) + if (request->pinned_connection) + clientPinConnection(request->pinned_connection, fd); + else if (request->flags.accelerated && Config.Accel.single_host && Config.Accel.host) pconnPush(fd, Config.Accel.host, Config.Accel.port); else pconnPush(fd, request->host, request->port); Index: squid/src/protos.h =================================================================== RCS file: /cvsroot/squid-sf//squid/src/protos.h,v retrieving revision 1.41.6.33 retrieving revision 1.41.6.33.2.1 diff -u -r1.41.6.33 -r1.41.6.33.2.1 --- squid/src/protos.h 16 Sep 2005 02:13:25 -0000 1.41.6.33 +++ squid/src/protos.h 23 Oct 2005 14:33:04 -0000 1.41.6.33.2.1 @@ -1,6 +1,6 @@ /* - * $Id: protos.h,v 1.41.6.33 2005/09/16 02:13:25 squidadm Exp $ + * $Id: protos.h,v 1.41.6.33.2.1 2005/10/23 14:33:04 hno Exp $ * * * SQUID Web Proxy Cache http://www.squid-cache.org/ @@ -141,6 +141,7 @@ extern void clientHttpConnectionsClose(void); extern StoreEntry *clientCreateStoreEntry(clientHttpRequest *, method_t, request_flags); extern int isTcpHit(log_type); +extern void clientPinConnection(ConnStateData *conn, int fd); extern int commSetNonBlocking(int fd); extern int commUnsetNonBlocking(int fd); Index: squid/src/structs.h =================================================================== RCS file: /cvsroot/squid-sf//squid/src/structs.h,v retrieving revision 1.48.2.43 retrieving revision 1.48.2.43.2.1 diff -u -r1.48.2.43 -r1.48.2.43.2.1 --- squid/src/structs.h 4 Sep 2005 02:13:28 -0000 1.48.2.43 +++ squid/src/structs.h 23 Oct 2005 14:33:05 -0000 1.48.2.43.2.1 @@ -1,6 +1,6 @@ /* - * $Id: structs.h,v 1.48.2.43 2005/09/04 02:13:28 squidadm Exp $ + * $Id: structs.h,v 1.48.2.43.2.1 2005/10/23 14:33:05 hno Exp $ * * * SQUID Web Proxy Cache http://www.squid-cache.org/ @@ -1132,6 +1132,8 @@ int n; time_t until; } defer; + int pinned_fd; /* pinned server side connection */ + int pinned; /* this connection was pinned */ }; struct _ipcache_addrs { @@ -1680,6 +1682,7 @@ 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 {