From: wessels <> Date: Sun, 10 Aug 1997 10:42:32 +0000 (+0000) Subject: SERVER-SIDE PERSISTENT CONNECTIONS: X-Git-Tag: SQUID_3_0_PRE1~4841 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=603a02fd0546277c038c9ab1bc2481a8d42d707e;p=thirdparty%2Fsquid.git SERVER-SIDE PERSISTENT CONNECTIONS: - 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 --- diff --git a/src/Makefile.in b/src/Makefile.in index 1a0d0b7c83..4a4473d186 100644 --- a/src/Makefile.in +++ b/src/Makefile.in @@ -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 \ diff --git a/src/cf.data.pre b/src/cf.data.pre index 8e1e00ab2a..300d8ae9ae 100644 --- a/src/cf.data.pre +++ b/src/cf.data.pre @@ -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) diff --git a/src/client.cc b/src/client.cc index c06f08e647..9ca67a0bf8 100644 --- a/src/client.cc +++ b/src/client.cc @@ -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 diff --git a/src/client_db.cc b/src/client_db.cc index 6a7f462429..1ad5c66acd 100644 --- a/src/client_db.cc +++ b/src/client_db.cc @@ -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); } diff --git a/src/client_side.cc b/src/client_side.cc index e24f1f84a7..b284ef9724 100644 --- a/src/client_side.cc +++ b/src/client_side.cc @@ -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; diff --git a/src/comm.cc b/src/comm.cc index 07938aa802..0d2f644c5b 100644 --- a/src/comm.cc +++ b/src/comm.cc @@ -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 diff --git a/src/defines.h b/src/defines.h index 2841cc42a6..2f2e5feefb 100644 --- a/src/defines.h +++ b/src/defines.h @@ -220,3 +220,6 @@ #define AUTH_MSG_SZ 4096 #define HTTP_REPLY_BUF_SZ 4096 + +#define HTTP_PROXYING (1<<0) +#define HTTP_KEEPALIVE (1<<1) diff --git a/src/errorpage.cc b/src/errorpage.cc index c002de8da5..1cdd354d79 100644 --- a/src/errorpage.cc +++ b/src/errorpage.cc @@ -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; diff --git a/src/http.cc b/src/http.cc index a07bad73b7..54812e1aaf 100644 --- a/src/http.cc +++ b/src/http.cc @@ -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) { diff --git a/src/main.cc b/src/main.cc index c41e87b73d..35afb63d0a 100644 --- a/src/main.cc +++ b/src/main.cc @@ -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)) diff --git a/src/neighbors.cc b/src/neighbors.cc index 1507217a97..40d596c11a 100644 --- a/src/neighbors.cc +++ b/src/neighbors.cc @@ -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)); diff --git a/src/net_db.cc b/src/net_db.cc index 4ed4986b58..8dbc2184a0 100644 --- a/src/net_db.cc +++ b/src/net_db.cc @@ -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 index 0000000000..d18404b296 --- /dev/null +++ b/src/pconn.cc @@ -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; +} diff --git a/src/protos.h b/src/protos.h index 11d5aea64c..77828db367 100644 --- a/src/protos.h +++ b/src/protos.h @@ -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)); diff --git a/src/ssl.cc b/src/ssl.cc index 46666e4efe..5e5f36f993 100644 --- a/src/ssl.cc +++ b/src/ssl.cc @@ -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)); diff --git a/src/stat.cc b/src/stat.cc index feb1e202f8..6e7ad68c7e 100644 --- a/src/stat.cc +++ b/src/stat.cc @@ -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; imem_obj; assert(mem != NULL); diff --git a/src/structs.h b/src/structs.h index f6256aca8b..0cd76761df 100644 --- a/src/structs.h +++ b/src/structs.h @@ -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 { diff --git a/src/tunnel.cc b/src/tunnel.cc index 0b10c634ee..585fcc1d88 100644 --- a/src/tunnel.cc +++ b/src/tunnel.cc @@ -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)); diff --git a/src/typedefs.h b/src/typedefs.h index e345652fd7..a69ff73544 100644 --- a/src/typedefs.h +++ b/src/typedefs.h @@ -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 *)); diff --git a/src/url.cc b/src/url.cc index 1f12b09e1c..f03d876923 100644 --- a/src/url.cc +++ b/src/url.cc @@ -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;