]> git.ipfire.org Git - thirdparty/squid.git/commitdiff
SERVER-SIDE PERSISTENT CONNECTIONS:
authorwessels <>
Sun, 10 Aug 1997 10:42:32 +0000 (10:42 +0000)
committerwessels <>
Sun, 10 Aug 1997 10:42:32 +0000 (10:42 +0000)
- Added pconn.c
- Addec Cofig.Timeout.pconn; default 120 seconds
- Added httpState->flags
- Added flags arg to httpBuildRequestHeader()
- Added HTTP_PROXYING and HTTP_KEEPALIVE flags
- Added 'Connection' to allowed HTTP headers (http-anon.c)
- Added 'Proxy-Connection' to allowed HTTP headers (http-anon.c)
- Merged proxyhttpStart() with httpStart() and crated new
  httpBuildState().
- New httpPconnTransferDone() detects end-of-data on persistent
  connections.

Other casualties:
- clean up casting of HASHCMP functions
- changed comm_open to return -1 instead of wierd COMM_ERROR
- cbdata-ify comm_close_handler stuff
- make some args const
- changed some PARAMS(()) to CNCB's
- Fixed cachemgrShutdown() not being used

21 files changed:
src/Makefile.in
src/cf.data.pre
src/client.cc
src/client_db.cc
src/client_side.cc
src/comm.cc
src/defines.h
src/errorpage.cc
src/http.cc
src/main.cc
src/neighbors.cc
src/net_db.cc
src/pconn.cc [new file with mode: 0644]
src/protos.h
src/ssl.cc
src/stat.cc
src/store.cc
src/structs.h
src/tunnel.cc
src/typedefs.h
src/url.cc

index 1a0d0b7c832f55cdb71f56d93be6a0b42a3113b8..4a4473d186a2482b021b87a98ef7563c633cd23e 100644 (file)
@@ -1,7 +1,7 @@
 #
 #  Makefile for the Squid Object Cache server
 #
-#  $Id: Makefile.in,v 1.84 1997/07/28 06:40:50 wessels Exp $
+#  $Id: Makefile.in,v 1.85 1997/08/10 04:42:32 wessels Exp $
 #
 #  Uncomment and customize the following to suit your needs:
 #
@@ -111,6 +111,7 @@ OBJS                = \
                net_db.o \
                objcache.o \
                pass.o \
+               pconn.o \
                peer_select.o \
                proto.o \
                redirect.o \
index 8e1e00ab2a82d375f37be56b7bfafa62702647da..300d8ae9aef64eddb2b493e7f2aa9f2a6667dcae 100644 (file)
@@ -1082,6 +1082,16 @@ DOC_START
 client_lifetime 1 day
 DOC_END
 
+NAME: pconn_timeout
+TYPE: time_t
+LOC: Config.Timeout.pconn
+DEFAULT: 120 seconds
+DOC_START
+       Timeout for idle persistent connections to servers and other
+       proxies.
+pconn_timeout 120 seconds
+DOC_END
+
 
 NAME: shutdown_lifetime
 COMMENT: (in seconds)
index c06f08e6474a69289e5f208c6fc712ba5c2577e1..9ca67a0bf8c70783d4a11974444cf6eadcf17daa 100644 (file)
@@ -1,10 +1,6 @@
 
-
-
-
-
 /*
- * $Id: client.cc,v 1.23 1997/07/28 06:40:51 wessels Exp $
+ * $Id: client.cc,v 1.24 1997/08/10 04:42:34 wessels Exp $
  *
  * DEBUG: section 0     WWW Client
  * AUTHOR: Harvest Derived
index 6a7f46242923a7aa85c6b480fe895a731d04e845..1ad5c66acd73be422e8136ea29cd4efc5751bb3a 100644 (file)
@@ -1,6 +1,6 @@
 
 /*
- * $Id: client_db.cc,v 1.16 1997/07/28 06:40:52 wessels Exp $
+ * $Id: client_db.cc,v 1.17 1997/08/10 04:42:34 wessels Exp $
  *
  * DEBUG: section 0     Client Database
  * AUTHOR: Duane Wessels
@@ -61,9 +61,7 @@ clientdbInit(void)
 {
     if (client_table)
        return;
-    client_table = hash_create((int (*)_PARAMS((const char *, const char *))) strcmp,
-       229,
-       hash_string);
+    client_table = hash_create((HASHCMP *) strcmp, 229, hash_string);
     client_info_sz = sizeof(ClientInfo);
 }
 
index e24f1f84a7516b642e6fb6ee4b3d7025dbd3a632..b284ef9724e4745cfe81a577baa3aa78ad65de83 100644 (file)
@@ -1,6 +1,6 @@
 
 /*
- * $Id: client_side.cc,v 1.120 1997/07/28 06:40:52 wessels Exp $
+ * $Id: client_side.cc,v 1.121 1997/08/10 04:42:35 wessels Exp $
  *
  * DEBUG: section 33    Client-side Routines
  * AUTHOR: Duane Wessels
@@ -528,7 +528,8 @@ clientConstructTraceEcho(clientHttpRequest * http)
        NULL,                   /* in_len */
        buf + len,
        8192 - len,
-       http->conn->fd);
+       http->conn->fd,
+       0);                     /* flags */
     http->log_type = LOG_TCP_MISS;
     http->http_code = 200;
     return buf;
index 07938aa802ea47221d5be1498bd449fd9cc71ffe..0d2f644c5b21c8d04a8e93848f30991a35192929 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * $Id: comm.cc,v 1.183 1997/07/26 04:48:26 wessels Exp $
+ * $Id: comm.cc,v 1.184 1997/08/10 04:42:36 wessels Exp $
  *
  * DEBUG: section 5     Socket Functions
  * AUTHOR: Harvest Derived
@@ -269,7 +269,7 @@ comm_open(int sock_type,
        default:
            debug(50, 0) ("comm_open: socket failure: %s\n", xstrerror());
        }
-       return (COMM_ERROR);
+       return -1;
     }
     /* update fdstat */
     debug(5, 5) ("comm_open: FD %d is a new socket\n", new_socket);
@@ -285,14 +285,14 @@ comm_open(int sock_type,
     if (addr.s_addr != no_addr.s_addr) {
        if (commBind(new_socket, addr, port) != COMM_OK) {
            comm_close(new_socket);
-           return COMM_ERROR;
+           return -1;
        }
     }
     F->local_port = port;
 
     if (BIT_TEST(flags, COMM_NONBLOCKING))
        if (commSetNonBlocking(new_socket) == COMM_ERROR)
-           return COMM_ERROR;
+           return -1;
 #ifdef TCP_NODELAY
     if (sock_type == SOCK_STREAM)
        commSetTcpNoDelay(new_socket);
@@ -564,7 +564,9 @@ commCallCloseHandlers(int fd)
     debug(5, 5) ("commCallCloseHandlers: FD %d\n", fd);
     while ((ch = F->close_handler) != NULL) {
        F->close_handler = ch->next;
-       ch->handler(fd, ch->data);
+       if (cbdataValid(ch->data))
+           ch->handler(fd, ch->data);
+       cbdataUnlock(ch->data);
        safe_free(ch);
     }
 }
@@ -1098,6 +1100,7 @@ comm_add_close_handler(int fd, PF * handler, void *data)
     new->data = data;
     new->next = fd_table[fd].close_handler;
     fd_table[fd].close_handler = new;
+    cbdataLock(data);
 }
 
 void
index 2841cc42a6f5d488444ab4548be502a794fbd2f5..2f2e5feefb5ecaea6fbb199622bdef86f5c0b077 100644 (file)
 
 #define AUTH_MSG_SZ 4096
 #define HTTP_REPLY_BUF_SZ 4096
+
+#define HTTP_PROXYING          (1<<0)
+#define HTTP_KEEPALIVE         (1<<1)
index c002de8da599b12c9f92db82d96fa4fd9bf6e9ac..1cdd354d791e909cfcd37f462d8a9fa7f2becd59 100644 (file)
@@ -1,6 +1,6 @@
 
 /*
- * $Id: errorpage.cc,v 1.61 1997/07/28 06:40:54 wessels Exp $
+ * $Id: errorpage.cc,v 1.62 1997/08/10 04:42:37 wessels Exp $
  *
  * DEBUG: section 4     Error Generation
  * AUTHOR: Duane Wessels
@@ -185,7 +185,7 @@ errorSend(int fd, ErrorState * err)
 }
 
 void
-errorAppendEntry(StoreEntry * entry, ErrorState * err)
+errorAppendEntry(const StoreEntry * entry, ErrorState * err)
 {
     char *buf;
     int len;
index a07bad73b7fcad1066cbbead950ea24474b52e92..54812e1aaf51433905f85cbd812791b3116a893d 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * $Id: http.cc,v 1.180 1997/07/28 06:40:57 wessels Exp $
+ * $Id: http.cc,v 1.181 1997/08/10 04:42:38 wessels Exp $
  *
  * DEBUG: section 11    Hypertext Transfer Protocol (HTTP)
  * AUTHOR: Harvest Derived
@@ -210,9 +210,11 @@ static void httpMakePrivate _PARAMS((StoreEntry *));
 static void httpMakePublic _PARAMS((StoreEntry *));
 static char *httpStatusString _PARAMS((int status));
 static STABH httpAbort;
+static HttpStateData *httpBuildState _PARAMS((int, StoreEntry *, request_t *, peer *));
+static int httpSocketOpen _PARAMS((StoreEntry *, const request_t *));
 
 static void
-httpStateFree(int fd, void *data)
+httpStateFree(int fdunused, void *data)
 {
     HttpStateData *httpState = data;
     if (httpState == NULL)
@@ -557,6 +559,40 @@ httpProcessReplyHeader(HttpStateData * httpState, const char *buf, int size)
     }
 }
 
+static int
+httpPconnTransferDone(HttpStateData * httpState)
+{
+    /* return 1 if we got the last of the data on a persistent connection */
+    MemObject *mem = httpState->entry->mem_obj;
+    struct _http_reply *reply = mem->reply;
+    debug(0, 0) ("httpPconnTransferDone: FD %d\n", httpState->fd);
+    if (!BIT_TEST(httpState->flags, HTTP_KEEPALIVE))
+       return 0;
+    debug(0, 0) ("httpPconnTransferDone: content_length=%d\n",
+       reply->content_length);
+    /*
+     * !200 replies maybe don't have content-length, so
+     * if we saw the end of the headers then try being persistent.
+     */
+    if (reply->code != 200)
+       if (httpState->reply_hdr_state > 1)
+           return 1;
+    /*
+     * If there is no content-length, then we probably can't be persistent
+     */
+    if (reply->content_length == 0)
+       return 0;
+    /*
+     * If there is a content_length, see if we've got all of it.  If so,
+     * then we can recycle this connection.
+     */
+    debug(0, 0) ("httpPconnTransferDone: hdr_sz=%d\n", reply->hdr_sz);
+    debug(0, 0) ("httpPconnTransferDone: e_current_len=%d\n",
+       mem->e_current_len);
+    if (mem->e_current_len < reply->content_length + reply->hdr_sz)
+       return 0;
+    return 1;
+}
 
 /* This will be called when data is ready to be read from fd.  Read until
  * error or connection closed. */
@@ -567,6 +603,7 @@ httpReadReply(int fd, void *data)
     HttpStateData *httpState = data;
     LOCAL_ARRAY(char, buf, SQUID_TCP_SO_RCVBUF);
     StoreEntry *entry = httpState->entry;
+    const request_t *request = httpState->request;
     int len;
     int bin;
     int clen;
@@ -652,10 +689,15 @@ httpReadReply(int fd, void *data)
        if (httpState->reply_hdr_state < 2)
            httpProcessReplyHeader(httpState, buf, len);
        storeAppend(entry, buf, len);
-       commSetSelect(fd,
-           COMM_SELECT_READ,
-           httpReadReply,
-           httpState, 0);
+       if (httpPconnTransferDone(httpState)) {
+           pconnPush(fd, request->host, request->port);
+           comm_remove_close_handler(fd, httpStateFree, httpState);
+           storeComplete(entry);       /* deallocates mem_obj->request */
+           httpState->fd = -1;
+           httpStateFree(-1, httpState);
+       } else {
+           commSetSelect(fd, COMM_SELECT_READ, httpReadReply, httpState, 0);
+       }
     }
 }
 
@@ -717,7 +759,8 @@ httpBuildRequestHeader(request_t * request,
     size_t * in_len,
     char *hdr_out,
     size_t out_sz,
-    int cfd)
+    int cfd,
+    int flags)
 {
     LOCAL_ARRAY(char, ybuf, MAX_URL + 32);
     char *xbuf = get_free_4k_page();
@@ -820,6 +863,15 @@ httpBuildRequestHeader(request_t * request,
            assert(strstr(url, request->urlpath));
        }
     }
+    /* maybe append Connection: Keep-Alive */
+    if (BIT_TEST(flags, HTTP_KEEPALIVE)) {
+       if (BIT_TEST(flags, HTTP_PROXYING)) {
+           sprintf(ybuf, "Proxy-Connection: Keep-Alive");
+       } else {
+           sprintf(ybuf, "Connection: Keep-Alive");
+       }
+       httpAppendRequestHeader(hdr_out, ybuf, &len, out_sz, 1);
+    }
     httpAppendRequestHeader(hdr_out, null_string, &len, out_sz, 1);
     put_free_4k_page(xbuf);
     put_free_4k_page(viabuf);
@@ -871,13 +923,18 @@ httpSendRequest(int fd, void *data)
        cfd = -1;
     else
        cfd = entry->mem_obj->fd;
+    if (httpState->neighbor != NULL)
+       BIT_SET(httpState->flags, HTTP_PROXYING);
+    if (req->method == METHOD_GET)
+       BIT_SET(httpState->flags, HTTP_KEEPALIVE);
     len = httpBuildRequestHeader(req,
        httpState->orig_request ? httpState->orig_request : req,
        entry,
        NULL,
        buf,
        buflen,
-       cfd);
+       cfd,
+       httpState->flags);
     debug(11, 6) ("httpSendRequest: FD %d:\n%s\n", fd, buf);
     comm_write(fd,
        buf,
@@ -889,62 +946,97 @@ httpSendRequest(int fd, void *data)
     httpState->orig_request = NULL;
 }
 
-void
-proxyhttpStart(request_t * orig_request,
-    StoreEntry * entry,
-    peer * e)
+static int
+httpSocketOpen(StoreEntry * entry, const request_t * request)
 {
-    HttpStateData *httpState;
-    request_t *request;
     int fd;
     ErrorState *err;
-    debug(11, 3) ("proxyhttpStart: \"%s %s\"\n",
-       RequestMethodStr[orig_request->method], entry->url);
-    if (e->options & NEIGHBOR_PROXY_ONLY)
-#if DONT_USE_VM
-       storeReleaseRequest(entry);
-#else
-       storeStartDeleteBehind(entry);
-#endif
-    /* Create socket. */
     fd = comm_open(SOCK_STREAM,
        0,
        Config.Addrs.tcp_outgoing,
        0,
        COMM_NONBLOCKING,
        entry->url);
-    if (fd == COMM_ERROR) {
-       debug(11, 4) ("proxyhttpStart: Failed because we're out of sockets.\n");
+    if (fd < 0) {
+       debug(11, 4) ("httpSocketOpen: Failed because we're out of sockets.\n");
        err = xcalloc(1, sizeof(ErrorState));
        err->type = ERR_SOCKET_FAILURE;
        err->http_status = HTTP_INTERNAL_SERVER_ERROR;
        err->errno = errno;
+       if (request)
+           err->request = requestLink(request);
        errorAppendEntry(entry, err);
        storeAbort(entry, 0);
-       return;
     }
+    return fd;
+}
+
+static HttpStateData *
+httpBuildState(int fd, StoreEntry * entry, request_t * orig_request, peer * e)
+{
+    HttpStateData *httpState = xcalloc(1, sizeof(HttpStateData));
+    request_t *request;
     storeLockObject(entry);
-    httpState = xcalloc(1, sizeof(HttpStateData));
     cbdataAdd(httpState);
     httpState->entry = entry;
-    request = get_free_request_t();
-    httpState->request = requestLink(request);
-    httpState->neighbor = e;
-    httpState->orig_request = requestLink(orig_request);
     httpState->fd = fd;
+    if (e) {
+       request = get_free_request_t();
+       request->method = orig_request->method;
+       xstrncpy(request->host, e->host, SQUIDHOSTNAMELEN);
+       request->port = e->http_port;
+       xstrncpy(request->urlpath, entry->url, MAX_URL);
+       httpState->request = requestLink(request);
+       httpState->neighbor = e;
+       httpState->orig_request = requestLink(orig_request);
+       BIT_SET(request->flags, REQ_PROXYING);
+    } else {
+       httpState->request = requestLink(orig_request);
+    }
     /* register the handler to free HTTP state data when the FD closes */
-    comm_add_close_handler(httpState->fd,
-       httpStateFree,
+    comm_add_close_handler(httpState->fd, httpStateFree, httpState);
+    return httpState;
+}
+
+void
+httpStart(request_t * request, StoreEntry * entry, peer * e)
+{
+    HttpStateData *httpState;
+    int fd;
+    debug(11, 3) ("httpStart: \"%s %s\"\n",
+       RequestMethodStr[request->method], entry->url);
+    if (e) {
+       if (e->options & NEIGHBOR_PROXY_ONLY)
+#if DONT_USE_VM
+           storeReleaseRequest(entry);
+#else
+           storeStartDeleteBehind(entry);
+#endif
+       if ((fd = pconnPop(e->host, e->http_port)) >= 0) {
+           debug(0, 0) ("httpStart: reusing pconn FD %d\n", fd);
+           httpState = httpBuildState(fd, entry, request, e);
+           httpConnectDone(fd, COMM_OK, httpState);
+           return;
+       }
+    } else {
+       if ((fd = pconnPop(request->host, request->port)) >= 0) {
+           debug(0, 0) ("httpStart: reusing pconn FD %d\n", fd);
+           httpState = httpBuildState(fd, entry, request, e);
+           httpConnectDone(fd, COMM_OK, httpState);
+           return;
+       }
+    }
+    if ((fd = httpSocketOpen(entry, NULL)) < 0)
+       return;
+    httpState = httpBuildState(fd, entry, request, e);
+    storeRegisterAbort(entry, httpAbort, httpState);
+    commSetTimeout(httpState->fd,
+       Config.Timeout.connect,
+       httpTimeout,
        httpState);
-    request->method = orig_request->method;
-    xstrncpy(request->host, e->host, SQUIDHOSTNAMELEN);
-    request->port = e->http_port;
-    xstrncpy(request->urlpath, entry->url, MAX_URL);
-    BIT_SET(request->flags, REQ_PROXYING);
-    commSetTimeout(fd, Config.Timeout.connect, httpTimeout, httpState);
     commConnectStart(httpState->fd,
-       request->host,
-       request->port,
+       httpState->request->host,
+       httpState->request->port,
        httpConnectDone,
        httpState);
 }
@@ -985,50 +1077,6 @@ httpConnectDone(int fd, int status, void *data)
     }
 }
 
-void
-httpStart(request_t * request, StoreEntry * entry)
-{
-    int fd;
-    HttpStateData *httpState;
-    ErrorState *err;
-    debug(11, 3) ("httpStart: \"%s %s\"\n",
-       RequestMethodStr[request->method], entry->url);
-    /* Create socket. */
-    fd = comm_open(SOCK_STREAM,
-       0,
-       Config.Addrs.tcp_outgoing,
-       0,
-       COMM_NONBLOCKING,
-       entry->url);
-    if (fd == COMM_ERROR) {
-       debug(11, 4) ("httpStart: Failed because we're out of sockets.\n");
-       err = xcalloc(1, sizeof(ErrorState));
-       err->type = ERR_SOCKET_FAILURE;
-       err->http_status = HTTP_INTERNAL_SERVER_ERROR;
-       err->errno = errno;
-       err->request = requestLink(request);
-       errorAppendEntry(entry, err);
-       storeAbort(entry, 0);
-       return;
-    }
-    storeLockObject(entry);
-    httpState = xcalloc(1, sizeof(HttpStateData));
-    cbdataAdd(httpState);
-    httpState->entry = entry;
-    httpState->request = requestLink(request);
-    httpState->fd = fd;
-    comm_add_close_handler(httpState->fd,
-       httpStateFree,
-       httpState);
-    storeRegisterAbort(entry, httpAbort, httpState);
-    commSetTimeout(fd, Config.Timeout.connect, httpTimeout, httpState);
-    commConnectStart(httpState->fd,
-       request->host,
-       request->port,
-       httpConnectDone,
-       httpState);
-}
-
 void
 httpReplyHeaderStats(StoreEntry * entry)
 {
index c41e87b73da4d66b6bc1f753cc89c280233f0995..35afb63d0ac27ee55c3210702a703aa32ea22f28 100644 (file)
@@ -1,6 +1,6 @@
 
 /*
- * $Id: main.cc,v 1.171 1997/08/09 05:42:34 wessels Exp $
+ * $Id: main.cc,v 1.172 1997/08/10 04:42:41 wessels Exp $
  *
  * DEBUG: section 1     Startup and Main Loop
  * AUTHOR: Harvest Derived
@@ -518,6 +518,7 @@ mainInitialize(void)
        /* after this point we want to see the mallinfo() output */
        do_mallinfo = 1;
        mimeInit(Config.mimeTablePathname);
+       pconnInit();
     }
     serverConnectionsOpen();
     if (theOutIcpConnection >= 0 && (!Config2.Accel.on || Config.onoff.accel_with_proxy))
index 1507217a972cf8e4a4b457793c7b85a7edf7af7a..40d596c11a4679e88f2ca04677e32ca903226176 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * $Id: neighbors.cc,v 1.155 1997/08/09 00:01:32 wessels Exp $
+ * $Id: neighbors.cc,v 1.156 1997/08/10 04:42:42 wessels Exp $
  *
  * DEBUG: section 15    Neighbor Routines
  * AUTHOR: Harvest Derived
@@ -119,7 +119,7 @@ static void peerRefreshDNS _PARAMS((void *));
 static IPH peerDNSConfigure;
 static void peerCheckConnect _PARAMS((void *));
 static IPH peerCheckConnect2;
-static void peerCheckConnectDone _PARAMS((int, int, void *));
+static CNCB peerCheckConnectDone;
 static void peerCountMcastPeersDone _PARAMS((void *data));
 static void peerCountMcastPeersStart _PARAMS((void *data));
 static void peerCountMcastPeersSchedule _PARAMS((peer * p, time_t when));
index 4ed4986b58f413f741c5fa41169396698401e730..8dbc2184a0c69fa4d13c79c0fbfaf3bc88aa9154 100644 (file)
@@ -1,6 +1,6 @@
 
 /*
- * $Id: net_db.cc,v 1.45 1997/07/16 23:01:31 wessels Exp $
+ * $Id: net_db.cc,v 1.46 1997/08/10 04:42:42 wessels Exp $
  *
  * DEBUG: section 37    Network Measurement Database
  * AUTHOR: Duane Wessels
@@ -438,8 +438,8 @@ netdbInit(void)
 #if USE_ICMP
     if (addr_table)
        return;
-    addr_table = hash_create((int (*)_PARAMS((const char *, const char *))) strcmp, 229, hash_string);
-    host_table = hash_create((int (*)_PARAMS((const char *, const char *))) strcmp, 467, hash_string);
+    addr_table = hash_create((HASHCMP *) strcmp, 229, hash_string);
+    host_table = hash_create((HASHCMP *) strcmp, 467, hash_string);
     eventAdd("netdbSaveState", netdbSaveState, NULL, 3617);
     netdbReloadState();
 #endif
diff --git a/src/pconn.cc b/src/pconn.cc
new file mode 100644 (file)
index 0000000..d18404b
--- /dev/null
@@ -0,0 +1,139 @@
+
+#include "squid.h"
+
+#define PCONN_MAX_FDS 10
+
+struct _pconn {
+    char *key;
+    struct _pconn *next;
+    int fds[PCONN_MAX_FDS];
+    int nfds;
+};
+
+static PF pconnRead;
+static PF pconnTimeout;
+static char *pconnKey _PARAMS((const char *host, u_short port));
+static hash_table *table = NULL;
+static struct _pconn *pconnNew _PARAMS((const char *key));
+static void pconnDelete _PARAMS((struct _pconn * p));
+static void pconnRemoveFD _PARAMS((struct _pconn * p, int fd));
+
+
+static char *
+pconnKey(const char *host, u_short port)
+{
+    LOCAL_ARRAY(char, buf, SQUIDHOSTNAMELEN + 10);
+    snprintf(buf, SQUIDHOSTNAMELEN + 10, "%s.%d", host, (int) port);
+    return buf;
+}
+
+static struct _pconn *
+pconnNew(const char *key)
+{
+    struct _pconn *p = xcalloc(1, sizeof(struct _pconn));
+    p->key = xstrdup(key);
+    debug(0, 0) ("pconnNew: adding %s\n", p->key);
+    hash_join(table, (hash_link *) p);
+    return p;
+}
+
+static void
+pconnDelete(struct _pconn *p)
+{
+    hash_link *hptr = hash_lookup(table, p->key);
+    assert(hptr != NULL);
+    debug(0, 0) ("pconnDelete: deleting %s\n", p->key);
+    hash_remove_link(table, hptr);
+}
+
+static void
+pconnRemoveFD(struct _pconn *p, int fd)
+{
+    int i;
+    for (i = 0; i < p->nfds; i++) {
+       if (p->fds[i] == fd)
+           break;
+    }
+    assert(i < p->nfds);
+    debug(0, 0) ("pconnRemoveFD: found FD %d at index %d\n", fd, i);
+    for (; i < p->nfds - 1; i++)
+       p->fds[i] = p->fds[i + 1];
+    if (--p->nfds == 0)
+       pconnDelete(p);
+}
+
+static void
+pconnTimeout(int fd, void *data)
+{
+    struct _pconn *p = data;
+    assert(table != NULL);
+    debug(0, 0) ("pconnTimeout: FD %d %s\n", fd, p->key);
+    pconnRemoveFD(p, fd);
+    comm_close(fd);
+}
+
+static void
+pconnRead(int fd, void *data)
+{
+    LOCAL_ARRAY(char, buf, 256);
+    struct _pconn *p = data;
+    int n;
+    assert(table != NULL);
+    n = read(fd, buf, 256);
+    debug(0, 0) ("pconnRead: %d bytes from FD %d, %s\n", n, fd, p->key);
+    pconnRemoveFD(p, fd);
+    comm_close(fd);
+}
+
+
+/* ========== PUBLIC FUNCTIONS ============================================ */
+
+
+void
+pconnInit(void)
+{
+    assert(table == NULL);
+    table = hash_create((HASHCMP *) strcmp, 229, hash_string);
+    debug(0, 0) ("persistent connection module initialized\n");
+}
+
+void
+pconnPush(int fd, const char *host, u_short port)
+{
+    struct _pconn *p;
+    char *key = xstrdup(pconnKey(host, port));
+    assert(table != NULL);
+    p = (struct _pconn *) hash_lookup(table, key);
+    if (p == NULL)
+       p = pconnNew(key);
+    if (p->nfds == PCONN_MAX_FDS) {
+       debug(0, 0) ("pconnPush: %s already has %d unused connections\n",
+           key, p->nfds);
+       close(fd);
+       xfree(key);
+       return;
+    }
+    p->fds[p->nfds++] = fd;
+    commSetSelect(fd, COMM_SELECT_READ, pconnRead, p, 0);
+    commSetTimeout(fd, Config.Timeout.pconn, pconnTimeout, p);
+    debug(0, 0) ("pconnPush: pushed FD %d for %s\n", fd, key);
+}
+
+int
+pconnPop(const char *host, u_short port)
+{
+    struct _pconn *p;
+    hash_link *hptr;
+    int fd = -1;
+    char *key = xstrdup(pconnKey(host, port));
+    assert(table != NULL);
+    hptr = hash_lookup(table, key);
+    if (hptr != NULL) {
+       p = (struct _pconn *) hptr;
+       assert(p->nfds > 0);
+       fd = p->fds[0];
+       pconnRemoveFD(p, fd);
+    }
+    xfree(key);
+    return fd;
+}
index 11d5aea64cfe8dfe603df2bddafb42c3b93df64a..77828db367d22545ba565f760306a488dc4b4d15 100644 (file)
@@ -218,8 +218,7 @@ extern HASHHASH hash_url;
 extern HASHHASH hash4;
 
 extern int httpCachable _PARAMS((method_t));
-extern void proxyhttpStart _PARAMS((request_t *, StoreEntry *, peer *));
-extern void httpStart _PARAMS((request_t *, StoreEntry *));
+extern void httpStart _PARAMS((request_t *, StoreEntry *, peer *));
 extern void httpParseReplyHeaders _PARAMS((const char *, struct _http_reply *));
 extern void httpProcessReplyHeader _PARAMS((HttpStateData *, const char *, int));
 extern void httpReplyHeaderStats _PARAMS((StoreEntry *));
@@ -229,7 +228,8 @@ extern size_t httpBuildRequestHeader _PARAMS((request_t * request,
        size_t * in_len,
        char *hdr_out,
        size_t out_sz,
-       int cfd));
+       int cfd,
+       int flags));
 extern int httpAnonAllowed _PARAMS((const char *line));
 extern int httpAnonDenied _PARAMS((const char *line));
 extern char *httpReplyHeader _PARAMS((double ver,
@@ -424,7 +424,7 @@ extern void storeComplete _PARAMS((StoreEntry *));
 extern void storeInit _PARAMS((void));
 extern int storeClientWaiting _PARAMS((const StoreEntry *));
 extern void storeAbort _PARAMS((StoreEntry *, int));
-extern void storeAppend _PARAMS((StoreEntry *, const char *, int));
+extern void storeAppend _PARAMS((const StoreEntry *, const char *, int));
 extern int storeGetSwapSpace _PARAMS((int));
 extern void storeLockObject _PARAMS((StoreEntry *));
 extern void storeSwapInStart _PARAMS((StoreEntry *, SIH *, void *data));
@@ -527,7 +527,7 @@ extern method_t urlParseMethod _PARAMS((const char *));
 extern void urlInitialize _PARAMS((void));
 extern request_t *urlParse _PARAMS((method_t, char *));
 extern char *urlCanonical _PARAMS((const request_t *, char *));
-extern request_t *requestLink _PARAMS((request_t *));
+extern request_t *requestLink _PARAMS((const request_t *));
 extern void requestUnlink _PARAMS((request_t *));
 extern int matchDomainName _PARAMS((const char *d, const char *h));
 extern int urlCheckRequest _PARAMS((const request_t *));
@@ -542,7 +542,7 @@ extern void logUserAgent _PARAMS((const char *, const char *));
 extern peer_t parseNeighborType _PARAMS((const char *s));
 
 extern void errorSend _PARAMS((int fd, ErrorState *));
-extern void errorAppendEntry _PARAMS((StoreEntry *, ErrorState *));
+extern void errorAppendEntry _PARAMS((const StoreEntry *, ErrorState *));
 extern void errorInitialize _PARAMS((void));
 
 extern OBJH stat_io_get;
@@ -556,3 +556,7 @@ extern OBJH server_list;
 extern OBJH parameter_get;
 extern OBJH storeDirStats;
 extern OBJH pconnHistDump;
+
+extern void pconnPush _PARAMS((int, const char *host, u_short port));
+extern int pconnPop _PARAMS((const char *host, u_short port));
+extern void pconnInit _PARAMS((void));
index 46666e4efe49204f38fa6e7e811e62121144df02..5e5f36f99310380bd93dcb200ba96112b084d6e4 100644 (file)
@@ -1,6 +1,6 @@
 
 /*
- * $Id: ssl.cc,v 1.60 1997/07/28 06:41:03 wessels Exp $
+ * $Id: ssl.cc,v 1.61 1997/08/10 04:42:46 wessels Exp $
  *
  * DEBUG: section 26    Secure Sockets Layer Proxy
  * AUTHOR: Duane Wessels
@@ -58,7 +58,7 @@ static void sslProxyConnected _PARAMS((int fd, void *));
 static ERCB sslErrorComplete;
 static void sslClose _PARAMS((SslStateData * sslState));
 static void sslClientClosed _PARAMS((int fd, void *));
-static void sslConnectDone _PARAMS((int fd, int status, void *data));
+static CNCB sslConnectDone;
 static void sslStateFree _PARAMS((int fd, void *data));
 static void sslPeerSelectComplete _PARAMS((peer * p, void *data));
 static void sslPeerSelectFail _PARAMS((peer * p, void *data));
index feb1e202f80ae91d0939cfcd0a3e1b7ec1ac4a25..6e7ad68c7e80c371ef3d918183a540f5cc0dcb90 100644 (file)
@@ -1,6 +1,6 @@
 
 /*
- * $Id: stat.cc,v 1.152 1997/08/09 05:42:36 wessels Exp $
+ * $Id: stat.cc,v 1.153 1997/08/10 04:42:47 wessels Exp $
  *
  * DEBUG: section 18    Cache Manager Statistics
  * AUTHOR: Harvest Derived
@@ -197,10 +197,10 @@ statUtilization(cacheinfo * obj, StoreEntry * sentry, const char *desc)
 }
 
 void
-stat_utilization_get(StoreEntry *e)
+stat_utilization_get(StoreEntry * e)
 {
-       statUtilization(HTTPCacheInfo, e, "HTTP");
-       statUtilization(ICPCacheInfo, e, "ICP");
+    statUtilization(HTTPCacheInfo, e, "HTTP");
+    statUtilization(ICPCacheInfo, e, "ICP");
 }
 
 void
@@ -360,15 +360,15 @@ statObjects(StoreEntry * sentry, int vm_or_not)
 }
 
 void
-stat_objects_get(StoreEntry *e)
+stat_objects_get(StoreEntry * e)
 {
-       statObjects(e, 0);
+    statObjects(e, 0);
 }
 
 void
-stat_vmobjects_get(StoreEntry *e)
+stat_vmobjects_get(StoreEntry * e)
 {
-       statObjects(e, 1);
+    statObjects(e, 1);
 }
 
 void
@@ -887,8 +887,8 @@ stat_init(cacheinfo ** object, const char *logfilename)
        obj->proto_stat_data[i].kb.now = 0;
     }
     *object = obj;
-       for (i=0; i<PCONN_HIST_SZ; i++)
-               client_pconn_hist[i] = 0;
+    for (i = 0; i < PCONN_HIST_SZ; i++)
+       client_pconn_hist[i] = 0;
 }
 
 void
index aaeabfff4c78019881a9af8b8a34663ce8e2d4e3..321f433173cc29385f374ac427788049f7113541 100644 (file)
@@ -1,6 +1,6 @@
 
 /*
- * $Id: store.cc,v 1.278 1997/07/28 06:41:05 wessels Exp $
+ * $Id: store.cc,v 1.279 1997/08/10 04:42:48 wessels Exp $
  *
  * DEBUG: section 20    Storeage Manager
  * AUTHOR: Harvest Derived
@@ -909,7 +909,7 @@ storeStartDeleteBehind(StoreEntry * e)
 
 /* Append incoming data from a primary server to an entry. */
 void
-storeAppend(StoreEntry * e, const char *buf, int len)
+storeAppend(const StoreEntry * e, const char *buf, int len)
 {
     MemObject *mem = e->mem_obj;
     assert(mem != NULL);
index f6256aca8b4aa834bfb021ec5ae8e009622a07e7..0cd76761dfb8a7f4adb861efb6fd3470dd4657db 100644 (file)
@@ -113,6 +113,7 @@ struct _SquidConfig {
        time_t lifetime;
        time_t connect;
        time_t request;
+       time_t pconn;
     } Timeout;
     size_t maxRequestSize;
     struct {
@@ -382,6 +383,7 @@ struct _HttpStateData {
     int eof;                   /* reached end-of-object? */
     request_t *orig_request;
     int fd;                    /* needed as identifier for ipcache */
+    int flags;
 };
 
 struct _icpUdpData {
index 0b10c634ee26b8497feb722e82e0d80110981b09..585fcc1d882867865283cd36d3b28a53509cc1e8 100644 (file)
@@ -1,6 +1,6 @@
 
 /*
- * $Id: tunnel.cc,v 1.60 1997/07/28 06:41:03 wessels Exp $
+ * $Id: tunnel.cc,v 1.61 1997/08/10 04:42:46 wessels Exp $
  *
  * DEBUG: section 26    Secure Sockets Layer Proxy
  * AUTHOR: Duane Wessels
@@ -58,7 +58,7 @@ static void sslProxyConnected _PARAMS((int fd, void *));
 static ERCB sslErrorComplete;
 static void sslClose _PARAMS((SslStateData * sslState));
 static void sslClientClosed _PARAMS((int fd, void *));
-static void sslConnectDone _PARAMS((int fd, int status, void *data));
+static CNCB sslConnectDone;
 static void sslStateFree _PARAMS((int fd, void *data));
 static void sslPeerSelectComplete _PARAMS((peer * p, void *data));
 static void sslPeerSelectFail _PARAMS((peer * p, void *data));
index e345652fd760f98be790a3679786701a6a13016d..a69ff7354449b5cf837333b7cbec681c37f89edb 100644 (file)
@@ -75,7 +75,7 @@ typedef struct _ErrorState ErrorState;
 
 typedef void AIOCB _PARAMS((void *, int aio_return, int aio_errno));
 typedef void CWCB _PARAMS((int fd, char *, int size, int errflag, void *data));
-typedef void CNCB _PARAMS((int fd, int status, void *data));
+typedef void CNCB _PARAMS((int fd, int status, void *));
 typedef void FREE _PARAMS((void *));
 typedef void FOCB _PARAMS((void *, int fd));
 typedef void EVH _PARAMS((void *));
index 1f12b09e1c77699d780e94d7f4e4d344b0f54ec4..f03d87692367fceaa0d7c3cc69a6adc5b0627652 100644 (file)
@@ -1,6 +1,6 @@
 
 /*
- * $Id: url.cc,v 1.60 1997/07/16 20:32:22 wessels Exp $
+ * $Id: url.cc,v 1.61 1997/08/10 04:42:50 wessels Exp $
  *
  * DEBUG: section 23    URL Parsing
  * AUTHOR: Duane Wessels
@@ -338,7 +338,7 @@ urlClean(char *dirty)
 
 
 request_t *
-requestLink(request_t * request)
+requestLink(const request_t * request)
 {
     request->link_count++;
     return request;