]> git.ipfire.org Git - thirdparty/squid.git/commitdiff
2.3 branch merge
authorwessels <>
Mon, 2 Aug 1999 12:18:26 +0000 (12:18 +0000)
committerwessels <>
Mon, 2 Aug 1999 12:18:26 +0000 (12:18 +0000)
25 files changed:
src/access_log.cc
src/acl.cc
src/cf.data.pre
src/client_side.cc
src/debug.cc
src/defines.h
src/dns_internal.cc
src/enums.h
src/forward.cc
src/http.cc
src/internal.cc
src/main.cc
src/protos.h
src/ssl.cc
src/store.cc
src/store_client.cc
src/store_log.cc
src/store_swapin.cc
src/store_swapout.cc
src/structs.h
src/tools.cc
src/tunnel.cc
src/url.cc
src/useragent.cc
src/wccp.cc

index 9acc98853cbf4624b6e1789d79ea3012a2af2378..9c2a1c5b774dc04d1e4c6ed988d8ad93266ba1d9 100644 (file)
@@ -1,7 +1,7 @@
 
 
 /*
- * $Id: access_log.cc,v 1.51 1999/05/26 17:07:56 wessels Exp $
+ * $Id: access_log.cc,v 1.52 1999/08/02 06:18:26 wessels Exp $
  *
  * DEBUG: section 46    Access Log
  * AUTHOR: Duane Wessels
@@ -314,13 +314,13 @@ accessLogRotate(void)
        i--;
        snprintf(from, MAXPATHLEN, "%s.%d", fname, i - 1);
        snprintf(to, MAXPATHLEN, "%s.%d", fname, i);
-       rename(from, to);
+       xrename(from, to);
     }
     /* Rotate the current log to .0 */
     file_close(LogfileFD);     /* always close */
     if (Config.Log.rotateNumber > 0) {
        snprintf(to, MAXPATHLEN, "%s.%d", fname, 0);
-       rename(fname, to);
+       xrename(fname, to);
     }
     /* Reopen the log.  It may have been renamed "manually" */
     LogfileFD = file_open(fname, O_WRONLY | O_CREAT);
index b029b0449c81a74827ae1c5f2a4d4ef6a0dec3d0..957bbb68db3f17e14f76eec17299115dfdfabb79 100644 (file)
@@ -1,6 +1,6 @@
 
 /*
- * $Id: acl.cc,v 1.206 1999/07/07 02:13:40 wessels Exp $
+ * $Id: acl.cc,v 1.207 1999/08/02 06:18:28 wessels Exp $
  *
  * DEBUG: section 28    Access Control
  * AUTHOR: Duane Wessels
@@ -993,7 +993,6 @@ aclDecodeProxyAuth(const char *proxy_auth, char **user, char **password, char *b
 {
     char *sent_auth;
     char *cleartext;
-
     debug(28, 6) ("aclDecodeProxyAuth: header = '%s'\n", proxy_auth);
     if (proxy_auth == NULL)
        return 0;
@@ -1018,6 +1017,11 @@ aclDecodeProxyAuth(const char *proxy_auth, char **user, char **password, char *b
        debug(28, 1) ("aclDecodeProxyAuth: no password in proxy authorization header '%s'\n", proxy_auth);
        return 0;
     }
+    if (**password == '\0') {
+       debug(28, 1) ("aclDecodeProxyAuth: Disallowing empty password,"
+           "user is '%s'\n", *user);
+       return 0;
+    }
     return 1;
 }
 
@@ -1043,7 +1047,8 @@ aclMatchProxyAuth(wordlist * data, const char *proxy_auth, acl_proxy_auth_user *
     debug(28, 5) ("aclMatchProxyAuth: checking user '%s'\n", user);
 
     if (auth_user) {
-       /* This should be optimized to a boolean argument indicating that the
+       /*
+        * This should be optimized to a boolean argument indicating that the
         * password is invalid, instead of passing full acl_proxy_auth_user
         * structures, and all messing with checklist->proxy_auth should
         * be restricted the functions that deal with the authenticator.
@@ -1057,8 +1062,11 @@ aclMatchProxyAuth(wordlist * data, const char *proxy_auth, acl_proxy_auth_user *
            debug(28, 4) ("aclMatchProxyAuth: authentication failed for user '%s'\n",
                user);
            aclFreeProxyAuthUser(auth_user);
-           /* copy username to request for logging on client-side unless ident
-            * is known (do not override ident with false proxy auth names) */
+           /*
+            * copy username to request for logging on client-side
+            * unless ident is known (do not override ident with
+            * false proxy auth names)
+            */
            if (!*checklist->request->user_ident)
                xstrncpy(checklist->request->user_ident, user, USER_IDENT_SZ);
            return -2;
@@ -1899,11 +1907,9 @@ aclDomainCompare(const void *data, splayNode * n)
        d2++;
     l1 = strlen(d1);
     l2 = strlen(d2);
-    while (d1[l1] == d2[l2]) {
+    while (d1[--l1] == d2[--l2]) {
        if ((l1 == 0) && (l2 == 0))
            return 0;           /* d1 == d2 */
-       l1--;
-       l2--;
        if (0 == l1) {
            if ('.' == d2[l2 - 1]) {
                debug(28, 0) ("WARNING: %s is a subdomain of %s\n", d2, d1);
index 1ff3aebae33968bd765066955de5707fbf7f1841..1f404584c92c79de4a322b28a07df0268d2406c2 100644 (file)
@@ -1,6 +1,6 @@
 
 #
-# $Id: cf.data.pre,v 1.160 1999/07/13 14:51:07 wessels Exp $
+# $Id: cf.data.pre,v 1.161 1999/08/02 06:18:30 wessels Exp $
 #
 #
 # SQUID Internet Object Cache  http://squid.nlanr.net/Squid/
@@ -1060,7 +1060,7 @@ DOC_END
 NAME: request_body_max_size
 COMMENT: (KB)
 TYPE: b_size_t
-DEFAULT: 100 KB
+DEFAULT: 1 MB
 LOC: Config.maxRequestBodySize
 DOC_START
        This specifies the maximum size for an HTTP request body.
@@ -1069,7 +1069,7 @@ DOC_START
        than this limit receives an "Invalid Request" error message.
        If you set this parameter to a zero, there will be no limit
        imposed.
-request_body_max_size 100 KB
+request_body_max_size 1 MB
 DOC_END
 
 NAME: reply_body_max_size
@@ -1795,6 +1795,15 @@ DOC_START
 unique_hostname www-cache1.foo.org
 DOC_END
 
+
+NAME: hostname_aliases
+TYPE: wordlist
+LOC: Config.hostnameAliases
+DEFAULT: none
+DOC_START
+       A list of other DNS names that your cache has.
+DOC_END
+
 COMMENT_START
  OPTIONS FOR THE CACHE REGISTRATION SERVICE
  -----------------------------------------------------------------------------
index b72c7b131d5633ab8b7ae591e8e143e3174f921e..512cb703e18ed084c819b0f2e9b47a3e54d41dac 100644 (file)
@@ -1,6 +1,6 @@
 
 /*
- * $Id: client_side.cc,v 1.460 1999/07/13 14:51:09 wessels Exp $
+ * $Id: client_side.cc,v 1.461 1999/08/02 06:18:32 wessels Exp $
  *
  * DEBUG: section 33    Client-side Routines
  * AUTHOR: Duane Wessels
@@ -861,7 +861,7 @@ clientSetKeepaliveFlag(clientHttpRequest * http)
 static int
 clientCheckContentLength(request_t * r)
 {
-    int has_cont_len = (httpHeaderGetInt(&r->header, HDR_CONTENT_LENGTH) >= 0);
+    int has_cont_len = (r->content_length >= 0);
     switch (r->method) {
     case METHOD_PUT:
     case METHOD_POST:
@@ -1914,7 +1914,7 @@ clientProcessRequest(clientHttpRequest * http)
        }
        /* yes, continue */
        http->log_type = LOG_TCP_MISS;
-    } else if (r->body) {
+    } else if (r->content_length > 0) {
        http->log_type = LOG_TCP_MISS;
        /* XXX oof, POST can be cached! */
        pumpInit(fd, r, http->uri);
@@ -2268,7 +2268,6 @@ clientReadRequest(int fd, void *data)
     int k;
     request_t *request = NULL;
     int size;
-    int cont_len;
     method_t method;
     clientHttpRequest *http = NULL;
     clientHttpRequest **H = NULL;
@@ -2394,7 +2393,7 @@ clientReadRequest(int fd, void *data)
            request->flags.accelerated = http->flags.accel;
            if (!http->flags.internal) {
                if (internalCheck(strBuf(request->urlpath))) {
-                   if (0 == strcasecmp(request->host, internalHostname()) &&
+                   if (internalHostnameIs(request->host) &&
                        request->port == Config.Port.http->i) {
                        http->flags.internal = 1;
                    } else if (internalStaticCheck(strBuf(request->urlpath))) {
@@ -2404,6 +2403,11 @@ clientReadRequest(int fd, void *data)
                    }
                }
            }
+           /*
+            * cache the Content-length value in request_t.
+            */
+           request->content_length = httpHeaderGetInt(&request->header,
+               HDR_CONTENT_LENGTH);
            request->flags.internal = http->flags.internal;
            safe_free(prefix);
            safe_free(http->log_uri);
@@ -2442,9 +2446,8 @@ clientReadRequest(int fd, void *data)
             * because there is a reqeust body following and we
             * don't want to parse it as though it was new request.
             */
-           cont_len = httpHeaderGetInt(&request->header, HDR_CONTENT_LENGTH);
-           if (cont_len >= 0) {
-               int copy_len = XMIN(conn->in.offset, cont_len);
+           if (request->content_length >= 0) {
+               int copy_len = XMIN(conn->in.offset, request->content_length);
                if (copy_len > 0) {
                    assert(conn->in.offset >= copy_len);
                    request->body_sz = copy_len;
@@ -2459,11 +2462,11 @@ clientReadRequest(int fd, void *data)
                 * be arriving on the client socket.  Lets cancel
                 * the read handler until this request gets forwarded.
                 */
-               if (request->body_sz < cont_len)
+               if (request->body_sz < request->content_length)
                    commSetSelect(fd, COMM_SELECT_READ, NULL, NULL, 0);
-               if (cont_len < 0)
+               if (request->content_length < 0)
                    (void) 0;
-               else if (cont_len > Config.maxRequestBodySize) {
+               else if (request->content_length > Config.maxRequestBodySize) {
                    err = errorCon(ERR_TOO_BIG, HTTP_REQUEST_ENTITY_TOO_LARGE);
                    err->request = requestLink(request);
                    http->entry = clientCreateStoreEntry(http,
@@ -2482,12 +2485,16 @@ clientReadRequest(int fd, void *data)
            k = conn->in.size - 1 - conn->in.offset;
            if (k == 0) {
                if (conn->in.offset >= Config.maxRequestHeaderSize) {
+                   int fd = open("/tmp/error:request-too-large", O_WRONLY | O_CREAT | O_TRUNC);
+                   if (fd >= 0) {
+                       write(fd, conn->in.buf, conn->in.offset);
+                       close(fd);
+                   }
                    /* The request is too large to handle */
-                   debug(33, 0) ("Request won't fit in buffer.\n");
-                   debug(33, 0) ("Config 'request_header_max_size'= %d bytes.\n",
-                       Config.maxRequestHeaderSize);
-                   debug(33, 0) ("This request = %d bytes.\n",
+                   debug(33, 0) ("Request header is too large (%d bytes)\n",
                        (int) conn->in.offset);
+                   debug(33, 1) ("Config 'request_header_max_size'= %d bytes.\n",
+                       Config.maxRequestHeaderSize);
                    err = errorCon(ERR_TOO_BIG, HTTP_REQUEST_ENTITY_TOO_LARGE);
                    http = parseHttpRequestAbort(conn, "error:request-too-large");
                    /* add to the client request queue */
index 1d3d600a5d197b1342a5ab95d2ed20c1d0920db5..596ca54e6d6defab38a5c4e82d5fdc04f0fbb398 100644 (file)
@@ -1,6 +1,6 @@
 
 /*
- * $Id: debug.cc,v 1.75 1999/04/15 06:15:51 wessels Exp $
+ * $Id: debug.cc,v 1.76 1999/08/02 06:18:33 wessels Exp $
  *
  * DEBUG: section 0     Debug Routines
  * AUTHOR: Harvest Derived
@@ -202,6 +202,11 @@ _db_rotate_log(void)
            return;
 #endif
 
+    /*
+     * NOTE: we cannot use xrename here without having it in a
+     * separate file -- tools.c has too many dependencies to be
+     * used everywhere debug.c is used.
+     */
     /* Rotate numbers 0 through N up one */
     for (i = Config.Log.rotateNumber; i > 1;) {
        i--;
index 0c5b0a0182a6a67017fc4007ff8fc0d338ff50da..2f2ab6785e0826a0043695bb2fcd42b34a7f664c 100644 (file)
@@ -1,6 +1,6 @@
 
 /*
- * $Id: defines.h,v 1.75 1999/07/13 14:51:10 wessels Exp $
+ * $Id: defines.h,v 1.76 1999/08/02 06:18:34 wessels Exp $
  *
  *
  * SQUID Internet Object Cache  http://squid.nlanr.net/Squid/
 #ifndef _PATH_DEVNULL
 #define _PATH_DEVNULL "/dev/null"
 #endif
+
+#if USE_ASYNC_IO
+#ifndef NUMTHREADS
+#define NUMTHREADS 16
+#endif
+#endif
index 1acc10f36c39aebfbf3bd620a62cd8fd8b358e3a..ba2b93d160b8467bcc3e3f703ac2f2050494bf39 100644 (file)
@@ -1,6 +1,6 @@
 
 /*
- * $Id: dns_internal.cc,v 1.14 1999/07/13 14:51:11 wessels Exp $
+ * $Id: dns_internal.cc,v 1.15 1999/08/02 06:18:34 wessels Exp $
  *
  * DEBUG: section 78    DNS lookups; interacts with lib/rfc1035.c
  * AUTHOR: Duane Wessels
@@ -354,7 +354,6 @@ void
 idnsInit(void)
 {
     static int init = 0;
-    memDataInit(MEM_IDNS_QUERY, "idns_query", sizeof(idns_query), 0);
     if (DnsSocket < 0) {
        DnsSocket = comm_open(SOCK_DGRAM,
            0,
@@ -369,11 +368,12 @@ idnsInit(void)
     if (nns == 0)
        idnsParseResolvConf();
     if (!init) {
+       memDataInit(MEM_IDNS_QUERY, "idns_query", sizeof(idns_query), 0);
        cachemgrRegister("idns",
            "Internal DNS Statistics",
            idnsStats, 0, 1);
+       init++;
     }
-    init++;
 }
 
 void
index a7b7fb55837b072f0803d09d8d07fab6508d3387..9f7a5e8181a0bebfa40e326be55753e6147cb4a3 100644 (file)
@@ -1,6 +1,6 @@
 
 /*
- * $Id: enums.h,v 1.159 1999/07/13 14:51:12 wessels Exp $
+ * $Id: enums.h,v 1.160 1999/08/02 06:18:35 wessels Exp $
  *
  *
  * SQUID Internet Object Cache  http://squid.nlanr.net/Squid/
@@ -364,6 +364,7 @@ enum {
     METHOD_CONNECT,            /* 101 */
     METHOD_TRACE,              /* 110 */
     METHOD_PURGE,              /* 111 */
+    METHOD_OPTIONS,
 #ifndef RFC_2518
     METHOD_PROPFIND,
     METHOD_PROPPATCH,
index eb69b9e4ca253b28e251714a80dac38d1a67145c..e953521476114c646fb16143d40fbfce11c8cd58 100644 (file)
@@ -1,6 +1,6 @@
 
 /*
- * $Id: forward.cc,v 1.63 1999/06/24 22:53:45 wessels Exp $
+ * $Id: forward.cc,v 1.64 1999/08/02 06:18:36 wessels Exp $
  *
  * DEBUG: section 17    Request Forwarding
  * AUTHOR: Duane Wessels
@@ -112,7 +112,7 @@ fwdCheckRetry(FwdState * fwdState)
        return 0;
     if (fwdState->flags.dont_retry)
        return 0;
-    if (fwdState->request->body)
+    if (fwdState->request->content_length >= 0)
        if (0 == pumpRestart(fwdState->request))
            return 0;
     return 1;
@@ -296,6 +296,7 @@ fwdDispatch(FwdState * fwdState)
     peer *p;
     request_t *request = fwdState->request;
     StoreEntry *entry = fwdState->entry;
+    ErrorState *err;
     debug(17, 3) ("fwdDispatch: FD %d: Fetching '%s %s'\n",
        fwdState->client_fd,
        RequestMethodStr[request->method],
@@ -313,6 +314,7 @@ fwdDispatch(FwdState * fwdState)
     assert(fwdState->server_fd > -1);
     if (fwdState->servers && (p = fwdState->servers->peer)) {
        p->stats.fetches++;
+       fwdState->request->peer_login = p->login;
        httpStart(fwdState);
     } else {
        switch (request->protocol) {
@@ -339,7 +341,20 @@ fwdDispatch(FwdState * fwdState)
        default:
            debug(17, 1) ("fwdDispatch: Cannot retrieve '%s'\n",
                storeUrl(entry));
-           fwdFail(fwdState, errorCon(ERR_UNSUP_REQ, HTTP_BAD_REQUEST));
+           err = errorCon(ERR_UNSUP_REQ, HTTP_BAD_REQUEST);
+           err->request = requestLink(request);
+           fwdFail(fwdState, err);
+           /*
+            * Force a persistent connection to be closed because
+            * some Netscape browsers have a bug that sends CONNECT
+            * requests as GET's over persistent connections.
+            */
+           request->flags.proxy_keepalive = 0;
+           /*
+            * Set the dont_retry flag becuase this is not a
+            * transient (network) error; its a bug.
+            */
+           fwdState->flags.dont_retry = 1;
            comm_close(fwdState->server_fd);
            break;
        }
@@ -361,7 +376,7 @@ fwdReforward(FwdState * fwdState)
     }
     if (fwdState->n_tries > 9)
        return 0;
-    if (fwdState->request->body)
+    if (fwdState->request->content_length >= 0)
        if (0 == pumpRestart(fwdState->request))
            return 0;
     assert(fs);
index d28034ec226be740f101768958f8cd2e3038728d..73ed6a6299f140bf07001d856a306f3e0a5eceba 100644 (file)
@@ -1,6 +1,6 @@
 
 /*
- * $Id: http.cc,v 1.351 1999/07/13 14:51:14 wessels Exp $
+ * $Id: http.cc,v 1.352 1999/08/02 06:18:37 wessels Exp $
  *
  * DEBUG: section 11    Hypertext Transfer Protocol (HTTP)
  * AUTHOR: Harvest Derived
@@ -727,9 +727,9 @@ httpBuildRequestHeader(request_t * request,
     }
     /* append Proxy-Authorization if configured for peer, and proxying */
     if (!httpHeaderHas(hdr_out, HDR_PROXY_AUTHORIZATION)) {
-       if (request->flags.proxying && request->peer_login) {
+       if (request->flags.proxying && orig_request->peer_login) {
            httpHeaderPutStrf(hdr_out, HDR_PROXY_AUTHORIZATION, "Basic %s",
-               base64_encode(request->peer_login));
+               base64_encode(orig_request->peer_login));
        }
     }
     /* append Cache-Control, add max-age if not there already */
@@ -800,7 +800,7 @@ httpSendRequest(HttpStateData * httpState)
 
     debug(11, 5) ("httpSendRequest: FD %d: httpState %p.\n", httpState->fd, httpState);
 
-    if (httpState->orig_request->body)
+    if (httpState->orig_request->content_length > 0)
        sendHeaderDone = httpSendRequestEntry;
     else
        sendHeaderDone = httpSendComplete;
@@ -860,7 +860,6 @@ httpStart(FwdState * fwd)
        xstrncpy(proxy_req->host, httpState->peer->host, SQUIDHOSTNAMELEN);
        proxy_req->port = httpState->peer->http_port;
        proxy_req->flags = orig_req->flags;
-       proxy_req->peer_login = httpState->peer->login;
        httpState->request = requestLink(proxy_req);
        httpState->orig_request = requestLink(orig_req);
        proxy_req->flags.proxying = 1;
index cb44e857502a0cb55460c2a86c4511b6c21cee5c..4abff0a13f9f2b6e0bf95d4f71cfc250ed58e024 100644 (file)
@@ -1,6 +1,6 @@
 
 /*
- * $Id: internal.cc,v 1.15 1998/11/12 06:28:11 wessels Exp $
+ * $Id: internal.cc,v 1.16 1999/08/02 06:18:38 wessels Exp $
  *
  * DEBUG: section 76    Internal Squid Object handling
  * AUTHOR: Duane, Alex, Henrik
@@ -46,10 +46,28 @@ internalStart(request_t * request, StoreEntry * entry)
     const char *upath = strBuf(request->urlpath);
     debug(76, 3) ("internalStart: %s requesting '%s'\n",
        inet_ntoa(request->client_addr), upath);
-    if (0 == strcmp(upath, "/squid-internal-dynamic/netdb"))
+    if (0 == strcmp(upath, "/squid-internal-dynamic/netdb")) {
        netdbBinaryExchange(entry);
-    else {
-       debugObj(76, 1, "internalStart: unknown request:\n", request, (ObjPackMethod) & httpRequestPack);
+    } else if (0 == strcmp(upath, "/squid-internal-periodic/store_digest")) {
+#if USE_CACHE_DIGESTS
+       const char *msgbuf = "This cache is currently building its digest.\n";
+#else
+       const char *msgbuf = "This cache does not suport Cache Digests.\n";
+#endif
+       httpReplySetHeaders(entry->mem_obj->reply,
+           1.0,
+           HTTP_NOT_FOUND,
+           "Not Found",
+           "text/plain",
+           strlen(msgbuf),
+           squid_curtime,
+           -2);
+       httpReplySwapOut(entry->mem_obj->reply, entry);
+       storeAppend(entry, msgbuf, strlen(msgbuf));
+       storeComplete(entry);
+    } else {
+       debugObj(76, 1, "internalStart: unknown request:\n",
+           request, (ObjPackMethod) & httpRequestPack);
        err = errorCon(ERR_INVALID_REQ, HTTP_NOT_FOUND);
        err->request = requestLink(request);
        errorAppendEntry(entry, err);
@@ -110,3 +128,15 @@ internalHostname(void)
     Tolower(host);
     return host;
 }
+
+int
+internalHostnameIs(const char *arg)
+{
+    wordlist *w;
+    if (0 == strcmp(arg, internalHostname()))
+       return 1;
+    for (w = Config.hostnameAliases; w; w = w->next)
+       if (0 == strcmp(arg, w->key))
+           return 1;
+    return 0;
+}
index 8e890cda8ed6ae9a5a11b69460b3f21256590b2d..e880a43e5bccd2c80eb96f80c2743afd0d203e98 100644 (file)
@@ -1,6 +1,6 @@
 
 /*
- * $Id: main.cc,v 1.303 1999/07/13 14:51:15 wessels Exp $
+ * $Id: main.cc,v 1.304 1999/08/02 06:18:38 wessels Exp $
  *
  * DEBUG: section 1     Startup and Main Loop
  * AUTHOR: Harvest Derived
@@ -349,6 +349,9 @@ mainReconfigure(void)
 #endif
     redirectInit();
     authenticateInit();
+#if USE_WCCP
+    wccpInit();
+#endif
     serverConnectionsOpen();
     if (theOutIcpConnection >= 0) {
        if (!Config2.Accel.on || Config.onoff.accel_with_proxy)
@@ -468,14 +471,14 @@ mainInitialize(void)
 #ifdef SQUID_SNMP
     snmpInit();
 #endif
-#if USE_WCCP
-    wccpInit();
-#endif
 #if MALLOC_DBG
     malloc_debug(0, malloc_debug_level);
 #endif
 
     if (!configured_once) {
+#if USE_ASYNC_IO
+       aioInit();
+#endif
        unlinkdInit();
        urlInitialize();
        cachemgrInit();
@@ -493,6 +496,9 @@ mainInitialize(void)
 #endif
        fwdInit();
     }
+#if USE_WCCP
+    wccpInit();
+#endif
     serverConnectionsOpen();
     if (theOutIcpConnection >= 0) {
        if (!Config2.Accel.on || Config.onoff.accel_with_proxy)
@@ -525,10 +531,6 @@ mainInitialize(void)
            eventAdd("start_announce", start_announce, NULL, 3600.0, 1);
        eventAdd("ipcache_purgelru", ipcache_purgelru, NULL, 10.0, 1);
        eventAdd("fqdncache_purgelru", fqdncache_purgelru, NULL, 15.0, 1);
-#if USE_WCCP
-       if (Config.Wccp.router.s_addr != inet_addr("0.0.0.0"))
-           eventAdd("wccpHereIam", wccpHereIam, NULL, 10.0, 1);
-#endif
     }
     configured_once = 1;
 }
index c4f57ea24d52e8b0b605e02a433c542233f8c392..630239d630c3c6fef94e217703c74963fd399ec1 100644 (file)
@@ -1,6 +1,6 @@
 
 /*
- * $Id: protos.h,v 1.343 1999/07/21 22:08:12 glenn Exp $
+ * $Id: protos.h,v 1.344 1999/08/02 06:18:39 wessels Exp $
  *
  *
  * SQUID Internet Object Cache  http://squid.nlanr.net/Squid/
@@ -79,7 +79,9 @@ extern aio_result_t *aio_poll_done(void);
 extern int aio_operations_pending(void);
 extern int aio_overloaded(void);
 extern int aio_sync(void);
+extern int aio_get_queue_len(void);
 
+extern void aioInit(void);
 extern void aioCancel(int);
 extern void aioOpen(const char *, int, mode_t, AIOCB *, void *);
 extern void aioClose(int);
@@ -89,6 +91,7 @@ extern void aioStat(char *, struct stat *, AIOCB *, void *);
 extern void aioUnlink(const char *, AIOCB *, void *);
 extern void aioCheckCallbacks(void);
 extern void aioSync(void);
+extern int aioQueueSize(void);
 #endif
 
 /*
@@ -524,9 +527,6 @@ extern variable_list *snmp_meshCtblFn(variable_list *, snint *);
 #endif /* SQUID_SNMP */
 
 #if USE_WCCP
-extern PF wccpHandleUdp;
-extern EVH wccpHereIam;
-extern EVH wccpAssignBuckets;
 extern void wccpInit(void);
 extern void wccpConnectionOpen(void);
 extern void wccpConnectionShutdown(void);
@@ -995,7 +995,7 @@ extern void storeRebuildComplete(struct _store_rebuild_data *);
 /*
  * store_swapin.c
  */
-extern storeIOState *storeSwapInStart(StoreEntry *);
+extern void storeSwapInStart(store_client *);
 
 /*
  * store_swapout.c
@@ -1112,6 +1112,7 @@ extern void gb_flush(gb_t *);     /* internal, do not use this */
 extern int stringHasWhitespace(const char *);
 extern void linklistPush(link_list **, void *);
 extern void *linklistShift(link_list **);
+extern int xrename(const char *from, const char *to);
 
 #if USE_HTCP
 extern void htcpInit(void);
@@ -1173,6 +1174,7 @@ extern int internalStaticCheck(const char *urlpath);
 extern char *internalLocalUri(const char *dir, const char *name);
 extern char *internalRemoteUri(const char *, u_short, const char *, const char *);
 extern const char *internalHostname(void);
+extern int internalHostnameIs(const char *);
 
 #if USE_CARP
 extern void carpInit(void);
index 7769b70867c90cba93451ad7d2691dc71264cfe2..12efc2cde68d98591564391e537689ebe1eb145c 100644 (file)
@@ -1,6 +1,6 @@
 
 /*
- * $Id: ssl.cc,v 1.98 1999/07/13 14:51:18 wessels Exp $
+ * $Id: ssl.cc,v 1.99 1999/08/02 06:18:41 wessels Exp $
  *
  * DEBUG: section 26    Secure Sockets Layer Proxy
  * AUTHOR: Duane Wessels
@@ -527,6 +527,12 @@ sslPeerSelectComplete(FwdServer * fs, void *data)
     } else {
        sslState->port = CACHE_HTTP_PORT;
     }
+    if (fs->peer) {
+       sslState->request->peer_login = fs->peer->login;
+       sslState->request->flags.proxying = 1;
+    } else {
+       sslState->request->flags.proxying = 0;
+    }
 #if DELAY_POOLS
     /* no point using the delayIsNoDelay stuff since ssl is nice and simple */
     if (g && g->options.no_delay && sslState->delay_id) {
index 8554039db051b6943ebfabd3b27e2a10ef399daf..fd340c94b579aaaf9592bddd0c017a4396d374b6 100644 (file)
@@ -1,6 +1,6 @@
 
 /*
- * $Id: store.cc,v 1.506 1999/07/13 14:51:21 wessels Exp $
+ * $Id: store.cc,v 1.507 1999/08/02 06:18:42 wessels Exp $
  *
  * DEBUG: section 20    Storage Manager
  * AUTHOR: Harvest Derived
@@ -185,7 +185,7 @@ storeHashInsert(StoreEntry * e, const cache_key * key)
     hash_join(store_table, (hash_link *) e);
 #if HEAP_REPLACEMENT
     if (EBIT_TEST(e->flags, ENTRY_SPECIAL)) {
-       debug(20, 4) ("storeHashInsert: not inserting special into store heap\n");
+       (void) 0;
     } else {
        e->node = heap_insert(store_heap, e);
        debug(20, 4) ("storeHashInsert: inserted node 0x%x\n", e->node);
@@ -235,10 +235,12 @@ storeLockObject(StoreEntry * e)
 {
     if (e->lock_count++ == 0) {
 #if HEAP_REPLACEMENT
-       /* there is no reason to take any action here.
-        * Squid by default is moving locked objects to the end of the LRU
-        * list to keep them from getting bumped into by the replacement
-        * algorithm.  We can't do that so we will just have to handle them.
+       /*
+        * There is no reason to take any action here.  Squid by
+        * default is moving locked objects to the end of the LRU
+        * list to keep them from getting bumped into by the
+        * replacement algorithm.  We can't do that so we will just
+        * have to handle them.
         */
        debug(20, 4) ("storeLockObject: just locked node 0x%x\n", e->node);
 #else
@@ -294,7 +296,8 @@ storeUnlockObject(StoreEntry * e)
             * Squid/LRU is moving things around in the linked list in order
             * to keep from bumping into them when purging from the LRU list.
             */
-           debug(20, 4) ("storeUnlockObject: purged private node 0x%x\n", e->node);
+           debug(20, 4) ("storeUnlockObject: purged private node 0x%x\n",
+               e->node);
 #else
            dlinkDelete(&e->lru, &store_list);
            dlinkAddTail(e, &e->lru, &store_list);
@@ -372,7 +375,8 @@ storeSetPublicKey(StoreEntry * e)
      */
 #if HEAP_REPLACEMENT
     if (EBIT_TEST(e->flags, RELEASE_REQUEST))
-       debug(20, 1) ("assertion failed: RELEASE key %s, url %s\n", e->key, mem->url);
+       debug(20, 1) ("assertion failed: RELEASE key %s, url %s\n",
+           e->key, mem->url);
 #endif
     assert(!EBIT_TEST(e->flags, RELEASE_REQUEST));
     newkey = storeKeyPublic(mem->url, mem->method);
@@ -558,8 +562,9 @@ storeCheckCachable(StoreEntry * e)
        store_check_cachable_hist.no.too_many_open_fds++;
 #if HEAP_REPLACEMENT
        /*
-        * With the HEAP-based replacement policies a low reference age should not
-        * prevent cacheability of an object.  We do not use LRU age at all.
+        * With the HEAP-based replacement policies a low reference
+        * age should not prevent cacheability of an object.  We
+        * do not use LRU age at all.
         */
 #else
     } else if (storeExpiredReferenceAge() < 300) {
@@ -711,7 +716,8 @@ storeGetMemSpace(int size)
        e->mem_obj->node = NULL;        /* no longer in the heap */
        if (storeEntryLocked(e)) {
            locked++;
-           debug(20, 5) ("storeGetMemSpace: locked key %s\n", storeKeyText(e->key));
+           debug(20, 5) ("storeGetMemSpace: locked key %s\n",
+               storeKeyText(e->key));
            linklistPush(e, &locked_entries);
            continue;
        }
@@ -829,8 +835,9 @@ storeMaintainSwapSpace(void *datanotused)
            continue;
        } else if (storeCheckExpired(e)) {
            /*
-            * Note: This will not check the reference age ifdef HEAP_REPLACEMENT,
-            * but it does some other useful checks...
+            * Note: This will not check the reference age ifdef
+            * HEAP_REPLACEMENT, but it does some other useful
+            * checks...
             */
            expired++;
            debug(20, 3) ("Released store object age %f size %d refs %d key %s\n",
@@ -839,9 +846,11 @@ storeMaintainSwapSpace(void *datanotused)
            storeRelease(e);
        } else {
            /*
-            * Did not expire the object so we need to add it back into the heap!
+            * Did not expire the object so we need to add it back
+            * into the heap!
             */
-           debug(20, 5) ("storeMaintainSwapSpace: non-expired %s\n", storeKeyText(e->key));
+           debug(20, 5) ("storeMaintainSwapSpace: non-expired %s\n",
+               storeKeyText(e->key));
            linklistAdd(e, &locked_entries);
            continue;
        }
@@ -1051,69 +1060,7 @@ storeInitHashValues(void)
 }
 
 #if HEAP_REPLACEMENT
-
-/*
- * For a description of these cache replacement policies see --
- *  http://www.hpl.hp.com/personal/John_Dilley/caching/wcw.html
- */
-
-/*
- * Key generation function to implement the LFU-DA policy (Least
- * Frequently Used with Dynamic Aging).  Similar to classical LFU
- * but with aging to handle turnover of the popular document set.
- * Maximizes byte hit rate by keeping more currently popular objects
- * in cache regardless of size.  Achieves lower hit rate than GDS
- * because there are more large objects in cache (so less room for
- * smaller popular objects).
- * 
- * This version implements a tie-breaker based upon recency
- * (e->lastref): for objects that have the same reference count
- * the most recent object wins (gets a higher key value).
- */
-static heap_key
-HeapKeyGen_StoreEntry_LFUDA(void *entry, double age)
-{
-    StoreEntry *e = entry;
-    double tie = (e->lastref > 1) ? (1.0 / e->lastref) : 1;
-    return age + e->refcount - tie;
-}
-
-
-/*
- * Key generation function to implement the GDS-Frequency policy.
- * Similar to Greedy Dual-Size Hits policy, but adds aging of
- * documents to prevent pollution.  Maximizes object hit rate by
- * keeping more small, popular objects in cache.  Achieves lower
- * byte hit rate than LFUDA because there are fewer large objects
- * in cache.
- * 
- * This version implements a tie-breaker based upon recency
- * (e->lastref): for objects that have the same reference count
- * the most recent object wins (gets a higher key value).
- */
-static heap_key
-HeapKeyGen_StoreEntry_GDSF(void *entry, double age)
-{
-    StoreEntry *e = entry;
-    double size = e->swap_file_sz ? e->swap_file_sz : 1.0;
-    double tie = (e->lastref > 1) ? (1.0 / e->lastref) : 1;
-    return age + ((double) e->refcount / size) - tie;
-}
-
-/* 
- * Key generation function to implement the LRU policy.  Normally
- * one would not do this with a heap -- use the linked list instead.
- * For testing and performance characterization it was useful.
- * Don't use it unless you are trying to compare performance among
- * heap-based replacement policies...
- */
-static heap_key
-HeapKeyGen_StoreEntry_LRU(void *entry, double age)
-{
-    StoreEntry *e = entry;
-    return (heap_key) e->lastref;
-}
-
+#include "store_heap_replacement.c"
 #endif
 
 void
@@ -1370,7 +1317,9 @@ storeEntryDump(const StoreEntry * e, int l)
     debug(20, l) ("StoreEntry->swap_status: %d\n", (int) e->swap_status);
 }
 
-/* NOTE, this function assumes only two mem states */
+/*
+ * NOTE, this function assumes only two mem states
+ */
 void
 storeSetMemStatus(StoreEntry * e, int new_status)
 {
@@ -1383,10 +1332,12 @@ storeSetMemStatus(StoreEntry * e, int new_status)
 #if HEAP_REPLACEMENT
        if (mem->node == NULL) {
            if (EBIT_TEST(e->flags, ENTRY_SPECIAL)) {
-               debug(20, 4) ("storeSetMemStatus: not inserting special %s\n", mem->url);
+               debug(20, 4) ("storeSetMemStatus: not inserting special %s\n",
+                   mem->url);
            } else {
                mem->node = heap_insert(inmem_heap, e);
-               debug(20, 4) ("storeSetMemStatus: inserted mem node 0x%x\n", mem->node);
+               debug(20, 4) ("storeSetMemStatus: inserted mem node 0x%x\n",
+                   mem->node);
            }
        }
 #else
index 24c817b468e1892677f6fbccad45eb78034abf46..3aae6d525593625106d5ec25f1acdd7644e9778c 100644 (file)
@@ -1,6 +1,6 @@
 
 /*
- * $Id: store_client.cc,v 1.74 1999/07/13 14:51:23 wessels Exp $
+ * $Id: store_client.cc,v 1.75 1999/08/02 06:18:43 wessels Exp $
  *
  * DEBUG: section 20    Storage Manager Client-Side Interface
  * AUTHOR: Duane Wessels
@@ -253,7 +253,7 @@ storeClientCopy2(StoreEntry * e, store_client * sc)
            callback(sc->callback_data, sc->copy_buf, -1);
        } else if (!sc->flags.disk_io_pending) {
            sc->flags.disk_io_pending = 1;
-           sc->swapin_sio = storeSwapInStart(e);
+           storeSwapInStart(sc);
            if (NULL == sc->swapin_sio) {
                sc->flags.disk_io_pending = 0;
                sc->callback = NULL;
index d1bbc1a4694558c238bc2c0303683d80e8ca40c1..9a2f1c0ea54b8a21771ad8544d6a704e870cd6c7 100644 (file)
@@ -1,6 +1,6 @@
 
 /*
- * $Id: store_log.cc,v 1.7 1999/05/26 17:08:04 wessels Exp $
+ * $Id: store_log.cc,v 1.8 1999/08/02 06:18:46 wessels Exp $
  *
  * DEBUG: section 20    Storage Manager Logging Functions
  * AUTHOR: Duane Wessels
@@ -111,12 +111,12 @@ storeLogRotate(void)
        i--;
        snprintf(from, MAXPATHLEN, "%s.%d", fname, i - 1);
        snprintf(to, MAXPATHLEN, "%s.%d", fname, i);
-       rename(from, to);
+       xrename(from, to);
     }
     /* Rotate the current log to .0 */
     if (Config.Log.rotateNumber > 0) {
        snprintf(to, MAXPATHLEN, "%s.%d", fname, 0);
-       rename(fname, to);
+       xrename(fname, to);
     }
     storelog_fd = file_open(fname, O_WRONLY | O_CREAT);
     if (storelog_fd < 0) {
index 2d2f6d0d55086724a731a07c9c58794eba933d60..b0e3b4f3ed2633de7bf43182fcc314ed0887b106 100644 (file)
@@ -1,6 +1,6 @@
 
 /*
- * $Id: store_swapin.cc,v 1.19 1999/06/25 23:37:33 wessels Exp $
+ * $Id: store_swapin.cc,v 1.20 1999/08/02 06:18:46 wessels Exp $
  *
  * DEBUG: section 20    Storage Manager Swapin Functions
  * AUTHOR: Duane Wessels
 
 #include "squid.h"
 
-typedef struct swapin_ctrl_t {
-    StoreEntry *e;
-    SIH *callback;
-    void *callback_data;
-    store_client *sc;
-} swapin_ctrl_t;
-
 static STIOCB storeSwapInFileClosed;
 
-storeIOState *
-storeSwapInStart(StoreEntry * e)
+void
+storeSwapInStart(store_client * sc)
 {
-    storeIOState *sio;
+    StoreEntry *e = sc->entry;
     assert(e->mem_status == NOT_IN_MEMORY);
     if (!EBIT_TEST(e->flags, ENTRY_VALIDATED)) {
        /* We're still reloading and haven't validated this entry yet */
-       return NULL;
+       return;
     }
     debug(20, 3) ("storeSwapInStart: called for %08X %s \n",
        e->swap_file_number, storeKeyText(e->key));
     if (e->swap_status != SWAPOUT_WRITING && e->swap_status != SWAPOUT_DONE) {
        debug(20, 1) ("storeSwapInStart: bad swap_status (%s)\n",
            swapStatusStr[e->swap_status]);
-       return NULL;
+       return;
     }
     if (e->swap_file_number < 0) {
        debug(20, 1) ("storeSwapInStart: swap_file_number < 0\n");
-       return NULL;
+       return;
     }
     assert(e->mem_obj != NULL);
     debug(20, 3) ("storeSwapInStart: Opening fileno %08X\n",
        e->swap_file_number);
-    sio = storeOpen(e->swap_file_number, O_RDONLY, storeSwapInFileClosed, NULL);
-    cbdataLock(sio);
-    return sio;
+    sc->swapin_sio = storeOpen(e->swap_file_number,
+       O_RDONLY,
+       storeSwapInFileClosed,
+       sc);
+    cbdataLock(sc->swapin_sio);
 }
 
 static void
 storeSwapInFileClosed(void *data, int errflag, storeIOState * sio)
 {
+    store_client *sc = data;
     debug(20, 3) ("storeSwapInFileClosed: sio=%p, errflag=%d\n",
        sio, errflag);
     cbdataUnlock(sio);
+    sc->swapin_sio = NULL;
 }
index b65349a26a3cffedf1d5b983e0cc5e2b674157b1..4df8cd2bc2f28b0b599071e96486b8aca22b2151 100644 (file)
@@ -1,6 +1,6 @@
 
 /*
- * $Id: store_swapout.cc,v 1.57 1999/07/13 14:51:26 wessels Exp $
+ * $Id: store_swapout.cc,v 1.58 1999/08/02 06:18:47 wessels Exp $
  *
  * DEBUG: section 20    Storage Manager Swapout Functions
  * AUTHOR: Duane Wessels
@@ -111,22 +111,23 @@ storeSwapOut(StoreEntry * e)
        (int) lowest_offset);
     new_mem_lo = lowest_offset;
     assert(new_mem_lo >= mem->inmem_lo);
-    /*
-     * We should only free up to what we know has been written to
-     * disk, not what has been queued for writing.  Otherwise there
-     * will be a chunk of the data which is not in memory and is
-     * not yet on disk.
-     */
     if (storeSwapOutAble(e)) {
+       /*
+        * We should only free up to what we know has been written
+        * to disk, not what has been queued for writing.  Otherwise
+        * there will be a chunk of the data which is not in memory
+        * and is not yet on disk.
+        */
        if ((on_disk = storeSwapOutObjectBytesOnDisk(mem)) < new_mem_lo)
            new_mem_lo = on_disk;
-    }
-    /*
-     * Else its not swap-able, and if we're freeing its data then
-     * we must make it private
-     */
-    else if (new_mem_lo > 0)
+    } else {
+       /*
+        * Its not swap-able, so we must make it PRIVATE.  Even if
+        * be only one MEM client and all others must read from
+        * disk.
+        */
        storeReleaseRequest(e);
+    }
     stmemFreeDataUpto(&mem->data_hdr, new_mem_lo);
     mem->inmem_lo = new_mem_lo;
     if (e->swap_status == SWAPOUT_WRITING)
index 490be500bfa15c0b842d1bc3a5b7efcf4f2f0931..b4952610ab64e884fb029b712d880970e14e8d64 100644 (file)
@@ -1,6 +1,6 @@
 
 /*
- * $Id: structs.h,v 1.304 1999/07/13 14:51:27 wessels Exp $
+ * $Id: structs.h,v 1.305 1999/08/02 06:18:48 wessels Exp $
  *
  *
  * SQUID Internet Object Cache  http://squid.nlanr.net/Squid/
@@ -321,6 +321,7 @@ struct _SquidConfig {
     char *mimeTablePathname;
     char *visibleHostname;
     char *uniqueHostname;
+    wordlist *hostnameAliases;
     char *errHtmlText;
     struct {
        char *host;
@@ -1392,6 +1393,7 @@ struct _storeIOState {
            } flags;
            const char *read_buf;
            link_list *pending_writes;
+           link_list *pending_reads;
        } aufs;
 #if USE_DISKD
        struct {
@@ -1428,6 +1430,7 @@ struct _request_t {
     HttpHeader header;
     char *body;
     size_t body_sz;
+    int content_length;
     HierarchyLogEntry hier;
     err_type err_type;
     char *peer_login;          /* Configured peer login:password */
index 42339f18f641c49a719b333d16168326e312a198..231dbd4e0af9c81d3fdd0b1b75b03c1bb890fcd7 100644 (file)
@@ -1,6 +1,6 @@
 
 /*
- * $Id: tools.cc,v 1.185 1999/07/13 14:51:28 wessels Exp $
+ * $Id: tools.cc,v 1.186 1999/08/02 06:18:49 wessels Exp $
  *
  * DEBUG: section 21    Misc Functions
  * AUTHOR: Harvest Derived
@@ -866,3 +866,20 @@ linklistShift(link_list ** L)
     xfree(l);
     return p;
 }
+
+
+/*
+ * Same as rename(2) but complains if something goes wrong;
+ * the caller is responsible for handing and explaining the 
+ * consequences of errors.
+ */
+int
+xrename(const char *from, const char *to)
+{
+    debug(21, 2) ("xrename: renaming %s to %s\n", from, to);
+    if (0 == rename(from, to))
+       return 0;
+    debug(21, errno == ENOENT ? 2 : 1) ("xrename: Cannot rename %s to %s: %s\n",
+       from, to, xstrerror());
+    return -1;
+}
index 3987087f6fca135d64dab622e269e5b43ad81684..3e7fefe1ac5044b21ec1061cedb218a142a54b82 100644 (file)
@@ -1,6 +1,6 @@
 
 /*
- * $Id: tunnel.cc,v 1.98 1999/07/13 14:51:18 wessels Exp $
+ * $Id: tunnel.cc,v 1.99 1999/08/02 06:18:41 wessels Exp $
  *
  * DEBUG: section 26    Secure Sockets Layer Proxy
  * AUTHOR: Duane Wessels
@@ -527,6 +527,12 @@ sslPeerSelectComplete(FwdServer * fs, void *data)
     } else {
        sslState->port = CACHE_HTTP_PORT;
     }
+    if (fs->peer) {
+       sslState->request->peer_login = fs->peer->login;
+       sslState->request->flags.proxying = 1;
+    } else {
+       sslState->request->flags.proxying = 0;
+    }
 #if DELAY_POOLS
     /* no point using the delayIsNoDelay stuff since ssl is nice and simple */
     if (g && g->options.no_delay && sslState->delay_id) {
index a176cb248c0a5c6ecf542bc90bf96c54416456f5..a998a2028ca06cb9b3a26bc1367671074ace7ad8 100644 (file)
@@ -1,6 +1,6 @@
 
 /*
- * $Id: url.cc,v 1.117 1999/06/18 04:25:01 wessels Exp $
+ * $Id: url.cc,v 1.118 1999/08/02 06:18:49 wessels Exp $
  *
  * DEBUG: section 23    URL Parsing
  * AUTHOR: Duane Wessels
@@ -45,6 +45,7 @@ const char *RequestMethodStr[] =
     "CONNECT",
     "TRACE",
     "PURGE",
+    "OPTIONS",
 #ifndef RFC_2518
     "PROPFIND",
     "PROPPATCH",
@@ -141,6 +142,8 @@ urlParseMethod(const char *s)
        return METHOD_TRACE;
     } else if (strcasecmp(s, "PURGE") == 0) {
        return METHOD_PURGE;
+    } else if (strcasecmp(s, "OPTIONS") == 0) {
+       return METHOD_OPTIONS;
 #ifndef RFC_2518
     } else if (strcasecmp(s, "PROPFIND") == 0) {
        return METHOD_PROPFIND;
index d21942bb3e0e56e03a1fdd11d0af9ea16613b16b..9037b50383931edc3cff393228f26d1bfcd8767d 100644 (file)
@@ -1,6 +1,6 @@
 
 /*
- * $Id: useragent.cc,v 1.17 1999/05/26 17:08:06 wessels Exp $
+ * $Id: useragent.cc,v 1.18 1999/08/02 06:18:50 wessels Exp $
  *
  * DEBUG: section 40    User-Agent logging
  * AUTHOR: Joe Ramey <ramey@csc.ti.com>
@@ -87,7 +87,7 @@ useragentRotateLog(void)
        i--;
        snprintf(from, MAXPATHLEN, "%s.%d", fname, i - 1);
        snprintf(to, MAXPATHLEN, "%s.%d", fname, i);
-       rename(from, to);
+       xrename(from, to);
     }
     if (cache_useragent_log) {
        file_close(fileno(cache_useragent_log));
@@ -97,7 +97,7 @@ useragentRotateLog(void)
     /* Rotate the current log to .0 */
     if (Config.Log.rotateNumber > 0) {
        snprintf(to, MAXPATHLEN, "%s.%d", fname, 0);
-       rename(fname, to);
+       xrename(fname, to);
     }
     useragentOpenLog();
 #endif
index b57c2157ef7d867d500dd97255abd405073a0231..57d15a2b27e9138156fedcd85eea57b0b7617fd4 100644 (file)
@@ -1,6 +1,6 @@
 
 /*
- * $Id: wccp.cc,v 1.8 1999/07/23 19:30:00 glenn Exp $
+ * $Id: wccp.cc,v 1.9 1999/08/02 06:18:51 wessels Exp $
  *
  * DEBUG: section 80     WCCP Support
  * AUTHOR: Glenn Chisholm
@@ -58,7 +58,7 @@ struct wccp_here_i_am_t {
 };
 
 struct wccp_cache_entry_t {
-    int ip_addr;
+    struct in_addr ip_addr;
     int revision;
     char hash[WCCP_HASH_SIZE];
     int reserved;
@@ -83,9 +83,13 @@ static int theInWccpConnection = -1;
 static int theOutWccpConnection = -1;
 static struct wccp_here_i_am_t wccp_here_i_am;
 static struct wccp_i_see_you_t wccp_i_see_you;
-static int change, local_ip;
+static int change;
+static struct in_addr local_ip;
 
-static int wccpLowestIP();
+static PF wccpHandleUdp;
+static int wccpLowestIP(void);
+static EVH wccpHereIam;
+static EVH wccpAssignBuckets;
 
 /*
  * The functions used during startup:
@@ -99,14 +103,16 @@ void
 wccpInit(void)
 {
     debug(80, 5) ("wccpInit: Called\n");
-
+    if (eventFind(wccpHereIam, NULL))
+       return;
     memset(&wccp_here_i_am, '\0', sizeof(wccp_here_i_am));
     wccp_here_i_am.type = htonl(WCCP_HERE_I_AM);
     wccp_here_i_am.version = htonl(WCCP_VERSION);
     wccp_here_i_am.revision = htonl(WCCP_REVISION);
-
     change = 1;
-
+    if (Config.Wccp.router.s_addr != any_addr.s_addr)
+       if (!eventFind(wccpHereIam, NULL))
+           eventAdd("wccpHereIam", wccpHereIam, NULL, 10.0, 1);
 }
 
 void
@@ -115,57 +121,58 @@ wccpConnectionOpen(void)
     u_short port = WCCP_PORT;
     struct sockaddr_in router, local;
     int local_len, router_len;
-
     debug(80, 5) ("wccpConnectionOpen: Called\n");
-    if (Config.Wccp.router.s_addr != inet_addr("0.0.0.0")) {
-       theInWccpConnection = comm_open(SOCK_DGRAM,
+    if (Config.Wccp.router.s_addr == any_addr.s_addr) {
+       debug(1, 1) ("WCCP Disabled.\n");
+       return;
+    }
+    theInWccpConnection = comm_open(SOCK_DGRAM,
+       0,
+       Config.Wccp.incoming,
+       port,
+       COMM_NONBLOCKING,
+       "WCCP Socket");
+    if (theInWccpConnection < 0)
+       fatal("Cannot open WCCP Port");
+    commSetSelect(theInWccpConnection,
+       COMM_SELECT_READ,
+       wccpHandleUdp,
+       NULL,
+       0);
+    debug(1, 1) ("Accepting WCCP messages on port %d, FD %d.\n",
+       (int) port, theInWccpConnection);
+    if (Config.Wccp.outgoing.s_addr != no_addr.s_addr) {
+       theOutWccpConnection = comm_open(SOCK_DGRAM,
            0,
-           Config.Wccp.incoming,
+           Config.Wccp.outgoing,
            port,
            COMM_NONBLOCKING,
-           "WCCP Port");
-       if (theInWccpConnection < 0)
-           fatal("Cannot open WCCP Port");
-       commSetSelect(theInWccpConnection, COMM_SELECT_READ, wccpHandleUdp, NULL, 0);
-       debug(1, 1) ("Accepting WCCP messages on port %d, FD %d.\n",
-           (int) port, theInWccpConnection);
-       if (Config.Wccp.outgoing.s_addr != no_addr.s_addr) {
-           theOutWccpConnection = comm_open(SOCK_DGRAM,
-               0,
-               Config.Wccp.outgoing,
-               port,
-               COMM_NONBLOCKING,
-               "WCCP Port");
-           if (theOutWccpConnection < 0)
-               fatal("Cannot open Outgoing WCCP Port");
-           commSetSelect(theOutWccpConnection,
-               COMM_SELECT_READ,
-               wccpHandleUdp,
-               NULL, 0);
-           debug(1, 1) ("Outgoing WCCP messages on port %d, FD %d.\n",
-               (int) port, theOutWccpConnection);
-           fd_note(theOutWccpConnection, "Outgoing WCCP socket");
-           fd_note(theInWccpConnection, "Incoming WCCP socket");
-       } else {
-           theOutWccpConnection = theInWccpConnection;
-       }
+           "WCCP Socket");
+       if (theOutWccpConnection < 0)
+           fatal("Cannot open Outgoing WCCP Port");
+       commSetSelect(theOutWccpConnection,
+           COMM_SELECT_READ,
+           wccpHandleUdp,
+           NULL, 0);
+       debug(1, 1) ("Outgoing WCCP messages on port %d, FD %d.\n",
+           (int) port, theOutWccpConnection);
+       fd_note(theOutWccpConnection, "Outgoing WCCP socket");
+       fd_note(theInWccpConnection, "Incoming WCCP socket");
     } else {
-       debug(1, 1) ("WCCP Disabled.\n");
+       theOutWccpConnection = theInWccpConnection;
     }
-
     router_len = sizeof(router);
     memset(&router, '\0', router_len);
     router.sin_family = AF_INET;
-    router.sin_port = htons(2048);
+    router.sin_port = htons(port);
     router.sin_addr = Config.Wccp.router;
     if (connect(theOutWccpConnection, (struct sockaddr *) &router, router_len))
        fatal("Unable to connect WCCP out socket");
-
     local_len = sizeof(local);
     memset(&local, '\0', local_len);
     if (getsockname(theOutWccpConnection, (struct sockaddr *) &local, &local_len))
        fatal("Unable to getsockname on WCCP out socket");
-    local_ip = local.sin_addr.s_addr;
+    local_ip.s_addr = local.sin_addr.s_addr;
 }
 
 void
@@ -198,7 +205,7 @@ wccpConnectionClose(void)
 /*          
  * Accept the UDP packet
  */
-void
+static void
 wccpHandleUdp(int sock, void *not_used)
 {
     struct sockaddr_in from;
@@ -234,24 +241,24 @@ wccpHandleUdp(int sock, void *not_used)
     }
     if (change != wccp_i_see_you.change) {
        change = wccp_i_see_you.change;
-       if (wccpLowestIP(wccp_i_see_you))
+       if (wccpLowestIP())
            if (!eventFind(wccpAssignBuckets, NULL))
                eventAdd("wccpAssignBuckets", wccpAssignBuckets, NULL, 30.0, 1);
     }
 }
 
-int
-wccpLowestIP()
+static int
+wccpLowestIP(void)
 {
     int loop;
     for (loop = 0; loop < ntohl(wccp_i_see_you.number); loop++) {
-       if (wccp_i_see_you.wccp_cache_entry[loop].ip_addr < local_ip)
-           return (0);
+       if (wccp_i_see_you.wccp_cache_entry[loop].ip_addr.s_addr < local_ip.s_addr)
+           return 0;
     }
-    return (1);
+    return 1;
 }
 
-void
+static void
 wccpHereIam(void *voidnotused)
 {
     debug(80, 6) ("wccpHereIam: Called\n");
@@ -262,17 +269,23 @@ wccpHereIam(void *voidnotused)
        sizeof(wccp_here_i_am),
        0);
 
-    eventAdd("wccpHereIam", wccpHereIam, NULL, 10.0, 1);
+    if (!eventFind(wccpHereIam, NULL))
+       eventAdd("wccpHereIam", wccpHereIam, NULL, 10.0, 1);
 }
 
-void
+static void
 wccpAssignBuckets(void *voidnotused)
 {
     struct wccp_assign_bucket_t wccp_assign_bucket;
-    int number_buckets, loop_buckets, loop, number_caches, \
-               bucket = 0, *caches, offset;
+    int number_buckets;
+    int loop_buckets;
+    int loop;
+    int number_caches;
+    int bucket = 0;
+    int *caches;
+    int offset;
     char buckets[WCCP_BUCKETS];
-    void *buf;
+    char *buf;
 
     debug(80, 6) ("wccpAssignBuckets: Called\n");
     memset(&wccp_assign_bucket, '\0', sizeof(wccp_assign_bucket));
@@ -285,7 +298,9 @@ wccpAssignBuckets(void *voidnotused)
 
     number_buckets = WCCP_BUCKETS / number_caches;
     for (loop = 0; loop < number_caches; loop++) {
-       caches[loop] = wccp_i_see_you.wccp_cache_entry[loop].ip_addr;
+       xmemcpy(&caches[loop],
+           &wccp_i_see_you.wccp_cache_entry[loop].ip_addr.s_addr,
+           sizeof(*caches));
        for (loop_buckets = 0; loop_buckets < number_buckets; loop_buckets++) {
            buckets[bucket++] = loop;
        }
@@ -296,16 +311,18 @@ wccpAssignBuckets(void *voidnotused)
     wccp_assign_bucket.id = wccp_i_see_you.id;
     wccp_assign_bucket.number = wccp_i_see_you.number;
 
-    memcpy(buf, &wccp_assign_bucket, offset);
-    memcpy(buf + offset, caches, (sizeof(*caches) * number_caches));
+    xmemcpy(buf, &wccp_assign_bucket, offset);
+    xmemcpy(buf + offset, caches, (sizeof(*caches) * number_caches));
     offset += (sizeof(*caches) * number_caches);
-    memcpy(buf + offset, buckets, WCCP_BUCKETS);
+    xmemcpy(buf + offset, buckets, WCCP_BUCKETS);
     offset += WCCP_BUCKETS;
     send(theOutWccpConnection,
        buf,
        offset,
        0);
     change = 0;
+    xfree(caches);
+    xfree(buf);
 }
 
 #endif /* USE_WCCP */