diff -urN squid-2.2.STABLE4/configure.in squid-2.2.STABLE4.DJL3/configure.in --- squid-2.2.STABLE4/configure.in Wed Apr 21 11:36:01 1999 +++ squid-2.2.STABLE4.DJL3/configure.in Thu Jul 22 20:09:19 1999 @@ -899,7 +899,6 @@ AC_CHECK_FUNCS(\ bcopy \ crypt \ - drand48 \ fchmod \ getdtablesize \ getpagesize \ @@ -933,7 +932,6 @@ srandom \ sysconf \ syslog \ - tempnam \ timegm \ vsnprintf \ ) diff -urN squid-2.2.STABLE4/lib/Makefile.in squid-2.2.STABLE4.DJL3/lib/Makefile.in --- squid-2.2.STABLE4/lib/Makefile.in Tue Aug 18 07:01:24 1998 +++ squid-2.2.STABLE4.DJL3/lib/Makefile.in Thu Jul 22 20:09:19 1999 @@ -68,7 +68,7 @@ distclean: clean -rm -f libregex.a - -rm -f Makefile + -rm -f Makefile Makefile.bak install: all diff -urN squid-2.2.STABLE4/makefile.in squid-2.2.STABLE4.DJL3/makefile.in --- squid-2.2.STABLE4/makefile.in Sat Jan 30 07:47:41 1999 +++ squid-2.2.STABLE4.DJL3/makefile.in Thu Jul 22 20:09:19 1999 @@ -37,11 +37,12 @@ almostclean: clean rm -f config.log makefile rm -f include/paths.h include/autoconf.h include/config.h - rm -f auth_modules/NCSA/Makefile auth_modules/dummy - @for dir in $(SUBDIRS) contrib; do \ + rm -f auth_modules/dummy + @for dir in $(SUBDIRS) contrib auth_modules/NCSA auth_modules/getpwnam; do \ echo Making distclean in $$dir; \ (cd $$dir; $(MAKE) $(MFLAGS) prefix="$(prefix)" distclean); \ done + @(echo Making clean in auth_modules/SMB; cd auth_modules/SMB; make clean) distclean: almostclean rm -f config.status config.cache diff -urN squid-2.2.STABLE4/src/Makefile.in squid-2.2.STABLE4.DJL3/src/Makefile.in --- squid-2.2.STABLE4/src/Makefile.in Sat Jan 23 03:07:01 1999 +++ squid-2.2.STABLE4.DJL3/src/Makefile.in Thu Jul 22 20:09:19 1999 @@ -84,6 +84,7 @@ asn.o \ @ASYNC_OBJS@ \ authenticate.o \ + charge.o \ cache_cf.o \ CacheDigest.o \ cache_manager.o \ @@ -360,7 +361,7 @@ -rm -f cf_gen cf_parser.c cf.data globals.c string_arrays.c distclean: clean - -rm -f Makefile squid.conf squid.conf.pre + -rm -f Makefile Makefile.bak squid.conf squid.conf.pre tags: ctags *.[ch] ../include/*.h ../lib/*.[ch] diff -urN squid-2.2.STABLE4/src/acl.c squid-2.2.STABLE4.DJL3/src/acl.c --- squid-2.2.STABLE4/src/acl.c Wed Jul 7 10:12:48 1999 +++ squid-2.2.STABLE4.DJL3/src/acl.c Thu Jul 22 20:09:20 1999 @@ -70,6 +70,8 @@ static void aclCheckCallback(aclCheck_t * checklist, allow_t answer); #if USE_IDENT static IDCB aclLookupIdentDone; +static void aclChargeStartIdent(aclCheck_t * checklist); +static void aclChargeDoneIdent(void * data, char *result); #endif static IPH aclLookupDstIPDone; static IPH aclLookupDstIPforASNDone; @@ -77,6 +79,8 @@ static FQDNH aclLookupDstFQDNDone; static void aclLookupProxyAuthStart(aclCheck_t * checklist); static void aclLookupProxyAuthDone(void *data, char *result); +static void aclChargeStartAuth(aclCheck_t * checklist); +static void aclChargeDoneAuth(void * data, char *result); static wordlist *aclDumpIpList(void *); static wordlist *aclDumpDomainList(void *data); static wordlist *aclDumpTimeSpecList(acl_time_data *); @@ -981,6 +985,8 @@ debug(28, 3) ("aclMatchUser: looking for '%s'\n", data->key); if (strcmp(data->key, "REQUIRED") == 0 && *user != '\0' && strcmp(user, "-") != 0) return 1; + if (strcmp(data->key, "CHARGE") == 0 && *user != '\0' && strcmp(user, "-") != 0) + return -3; if (strcmp(data->key, user) == 0) return 1; data = data->next; @@ -1020,9 +1026,10 @@ return 1; } -/* aclMatchProxyAuth can return three exit codes: +/* aclMatchProxyAuth can return five exit codes: * 0 : user denied access * 1 : user validated OK + * 2 : user validated OK, CHARGE * -1 : check the password for this user via an external authenticator * -2 : invalid Proxy-authorization: header; * ask for Proxy-Authorization: header @@ -1138,6 +1145,48 @@ checklist); } +#if USE_IDENT +static void +aclChargeDoneIdent(void *data, char *result) +{ + aclCheck_t *checklist = data; + debug(28, 4) ("aclChargeDoneIdent: result = %s\n", + result ? result : "NULL"); + if (result && (strncasecmp(result, "OK", 2) == 0)) + checklist->state[ACL_IDENT] = ACL_CHARGE_DONE_OK; + else + checklist->state[ACL_IDENT] = ACL_CHARGE_DONE_FAIL; + aclCheck(checklist); +} +#endif + +#if USE_IDENT +static void +aclChargeStartIdent(aclCheck_t * checklist) +{ + chargeStartCheck(checklist->request->user_ident, aclChargeDoneIdent, checklist); +} +#endif + +static void +aclChargeDoneAuth(void *data, char *result) +{ + aclCheck_t *checklist = data; + debug(28, 4) ("aclChargeDoneAuth: result = %s\n", + result ? result : "NULL"); + if (result && (strncasecmp(result, "OK", 2) == 0)) + checklist->state[ACL_PROXY_AUTH] = ACL_CHARGE_DONE_OK; + else + checklist->state[ACL_PROXY_AUTH] = ACL_CHARGE_DONE_FAIL; + aclCheck(checklist); +} + +static void +aclChargeStartAuth(aclCheck_t * checklist) +{ + chargeStartCheck(checklist->auth_user->user, aclChargeDoneAuth, checklist); +} + static int aclMatchInteger(intlist * data, int i) { @@ -1334,8 +1383,23 @@ /* NOTREACHED */ #if USE_IDENT case ACL_IDENT: - if (checklist->ident[0]) { - return aclMatchUser(ae->data, checklist->ident); + if (checklist->state[ACL_IDENT] == ACL_CHARGE_DONE_OK) { + r->flags.charge = 1; + return 1; + } else if (checklist->state[ACL_IDENT] == ACL_CHARGE_DONE_FAIL) { + return 0; + } else if (checklist->ident[0]) { + switch (aclMatchUser(ae->data, checklist->ident)) { + case 1: + /* matched */ + return 1; + case -3: + /* need charging info */ + checklist->state[ACL_IDENT] = ACL_CHARGE_NEEDED; + default: + /* fall-thru or not matched */ + return 0; + } } else { checklist->state[ACL_IDENT] = ACL_LOOKUP_NEEDED; return 0; @@ -1377,6 +1441,13 @@ * it is not forwarded to the next proxy */ r->flags.used_proxy_auth = 1; + /* Post-charging-lookup return */ + if (checklist->state[ACL_PROXY_AUTH] == ACL_CHARGE_DONE_OK) { + r->flags.charge = 1; + return 1; + } else if (checklist->state[ACL_PROXY_AUTH] == ACL_CHARGE_DONE_FAIL) { + return 0; + } /* Check the password */ switch (aclMatchProxyAuth(ae->data, header, @@ -1388,6 +1459,9 @@ case 1: /* user validated OK */ return 1; + case -3: + checklist->state[ACL_PROXY_AUTH] = ACL_CHARGE_NEEDED; + return 0; case -2: /* no such user OR we need a proxy authentication header */ checklist->state[ACL_PROXY_AUTH] = ACL_PROXY_AUTH_NEEDED; @@ -1477,6 +1551,7 @@ allow_t allow = ACCESS_DENIED; const acl_access *A; int match; + int saved_charge0, saved_charge1; ipcache_addrs *ia; while ((A = checklist->access_list) != NULL) { /* @@ -1490,7 +1565,10 @@ } debug(28, 3) ("aclCheck: checking '%s'\n", A->cfgline); allow = A->allow; + saved_charge0 = checklist->request->flags.charge; match = aclMatchAclList(A->acl_list, checklist); + saved_charge1 = checklist->request->flags.charge; + checklist->request->flags.charge = saved_charge0; if (checklist->state[ACL_DST_IP] == ACL_LOOKUP_NEEDED) { checklist->state[ACL_DST_IP] = ACL_LOOKUP_PENDING; ipcache_nbgethostbyname(checklist->request->host, @@ -1526,6 +1604,9 @@ aclLookupProxyAuthStart(checklist); checklist->state[ACL_PROXY_AUTH] = ACL_LOOKUP_PENDING; return; + } else if (checklist->state[ACL_PROXY_AUTH] == ACL_CHARGE_NEEDED) { + aclChargeStartAuth(checklist); + return; } else if (checklist->state[ACL_PROXY_AUTH] == ACL_PROXY_AUTH_NEEDED) { /* Special case. Client is required to resend the request * with authentication. The request is denied. @@ -1548,6 +1629,9 @@ allow = 0; match = -1; } + } else if(checklist->state[ACL_IDENT] == ACL_CHARGE_NEEDED) { + aclChargeStartIdent(checklist); + return; } #endif /* @@ -1558,6 +1642,7 @@ cbdataUnlock(A); if (match) { debug(28, 3) ("aclCheck: match found, returning %d\n", allow); + checklist->request->flags.charge = saved_charge1; aclCheckCallback(checklist, allow); return; } diff -urN squid-2.2.STABLE4/src/authenticate.c squid-2.2.STABLE4.DJL3/src/authenticate.c --- squid-2.2.STABLE4/src/authenticate.c Sat Dec 5 08:54:15 1998 +++ squid-2.2.STABLE4.DJL3/src/authenticate.c Thu Jul 22 20:09:20 1999 @@ -120,8 +120,8 @@ cachemgrRegister("authenticator", "User Authenticator Stats", authenticateStats, 0, 1); + init++; } - init++; } void diff -urN squid-2.2.STABLE4/src/cache_cf.c squid-2.2.STABLE4.DJL3/src/cache_cf.c --- squid-2.2.STABLE4/src/cache_cf.c Mon Apr 19 08:14:34 1999 +++ squid-2.2.STABLE4.DJL3/src/cache_cf.c Thu Jul 22 20:09:20 1999 @@ -989,6 +989,8 @@ } else if (!strcasecmp(token, "no-delay")) { p->options.no_delay = 1; #endif + } else if (!strcasecmp(token, "no-charge")) { + p->options.no_charge = 1; } else if (!strncasecmp(token, "login=", 6)) { p->login = xstrdup(token + 6); } else { diff -urN squid-2.2.STABLE4/src/cf.data.pre squid-2.2.STABLE4.DJL3/src/cf.data.pre --- squid-2.2.STABLE4/src/cf.data.pre Sat May 8 05:44:11 1999 +++ squid-2.2.STABLE4.DJL3/src/cf.data.pre Thu Jul 22 20:09:20 1999 @@ -223,6 +223,7 @@ no-digest no-netdb-exchange no-delay + no-charge login=user:password use 'proxy-only' to specify that objects fetched @@ -269,6 +270,9 @@ use 'no-delay' to prevent access to this neighbor from influencing the delay pools. + use 'no-charge' to prevent access to this neighbor + from being charged to the user. + use 'login=user:password' if this is a personal/workgroup proxy and your parent requires proxy authentication. @@ -998,6 +1002,47 @@ authenticate_ttl 3600 DOC_END +NAME: charge_program +TYPE: wordlist +LOC: Config.Program.charge +DEFAULT: none +DOC_START + Specify the command for the external charger. Such a program + reads a line containing "? username" or "- username bytes" and + replies with "OK" or "ERR" indicating if traffic should be + permitted in the case of "? username" or if the bytes have been + successfully charged for in the case of "- username bytes". + If you use an charger, make sure you have a proxy_auth acl with + a value of CHARGE. By default, the charge_program is not used. + + IMPORTANT: Charging is based on the logged username. If a + single request uses both proxy_auth and ident during its + acl checks, and finds it neccessary to look both up this will + probably (if you're doing something this strange you should + check the latest source code) be the proxy_auth, regardless of + which has the CHARGE tag on it. You should not find yourself + doing this. + + no-charge peer traffic is not charged, and cache hits are also + not charged. Otherwise, the charge program is called with a + reasonable estimation of the amount of incoming traffic. + +charge_program none +DOC_END + +NAME: charge_children +TYPE: int +DEFAULT: 5 +LOC: Config.chargeChildren +DOC_START + The number of charger processes to spawn (default 5). If you start + too few Squid will have to wait for them to process a backlog of + charging requests, slowing it down. When charging is done via a + (slow) network you are likely to need lots of charger processes. + +charge_children 5 +DOC_END + COMMENT_START OPTIONS FOR TUNING THE CACHE ----------------------------------------------------------------------------- @@ -1430,6 +1475,7 @@ acl aclname ident username ... # string match on ident output. # use REQUIRED to accept any non-null ident. + # use CHARGE to accept based on a charge_program [see charge_program]. acl aclname src_as number ... acl aclname dst_as number ... # Except for access control, AS numbers can be used for @@ -1443,6 +1489,7 @@ acl aclname proxy_auth username ... # list of valid usernames # use REQUIRED to accept any valid username. + # use CHARGE to accept based on a charge_program [see charge_program]. # # NOTE: when a Proxy-Authentication header is sent but it is not # needed during ACL checking the username is NOT logged diff -urN squid-2.2.STABLE4/src/charge.c squid-2.2.STABLE4.DJL3/src/charge.c --- squid-2.2.STABLE4/src/charge.c Thu Jan 1 08:00:00 1970 +++ squid-2.2.STABLE4.DJL3/src/charge.c Thu Jul 22 20:09:20 1999 @@ -0,0 +1,160 @@ + +/* + * $Id: charge.c,v 1.10 1998/12/05 00:54:15 wessels Exp $ + * + * DEBUG: section 29 Charger + * AUTHOR: David Luyer (from Duane Wessels' authenticate.c) + * + * SQUID Internet Object Cache http://squid.nlanr.net/Squid/ + * ---------------------------------------------------------- + * + * Squid is the result of efforts by numerous individuals from the + * Internet community. Development is led by Duane Wessels of the + * National Laboratory for Applied Network Research and funded by the + * National Science Foundation. Squid is Copyrighted (C) 1998 by + * Duane Wessels and the University of California San Diego. Please + * see the COPYRIGHT file for full details. Squid incorporates + * software developed and/or copyrighted by other sources. Please see + * the CREDITS file for full details. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111, USA. + * + */ + +#include "squid.h" + +typedef struct { + void *data; + RH *handler; +} chargeStateData; + +static HLPCB chargeHandleReply; +static void chargeStateFree(chargeStateData * r); +static helper *chargers = NULL; + +static void +chargeHandleReply(void *data, char *reply) +{ + chargeStateData *r = data; + int valid; + char *t = NULL; + debug(29, 5) ("chargeHandleReply: {%s}\n", reply ? reply : ""); + if (reply) { + if ((t = strchr(reply, ' '))) + *t = '\0'; + if (*reply == '\0') + reply = NULL; + } + valid = cbdataValid(r->data); + cbdataUnlock(r->data); + if (valid) + r->handler(r->data, reply); + chargeStateFree(r); +} + +static void +chargeStateFree(chargeStateData * r) +{ + cbdataFree(r); +} + +static void +chargeStats(StoreEntry * sentry) +{ + storeAppendPrintf(sentry, "Authenticator Statistics:\n"); + helperStats(sentry, chargers); +} + +static void +dummyCallback(void * data, char * unused) +{ + /* dummy */ + cbdataUnlock(data); +} + +static char * dummyData = "dummy"; + +/**** PUBLIC FUNCTIONS ****/ + +void +chargeStartCharge(const char * user, long qty) +{ + chargeStateData *r = NULL; + char buf[8192]; + assert(user); + debug(29, 5) ("chargeStartCharge: '%s' - %d\n", user, qty); + if (Config.Program.charge == NULL) + return; + r = xcalloc(1, sizeof(chargeStateData)); + cbdataAdd(r, cbdataXfree, 0); + r->handler = dummyCallback; + cbdataLock(dummyData); + r->data = dummyData; + snprintf(buf, 8192, "- %s %ld\n", user, qty); + helperSubmit(chargers, buf, dummyCallback, dummyData); +} + +void +chargeStartCheck(const char * user, RH * handler, void *data) +{ + chargeStateData *r = NULL; + char buf[8192]; + assert(user); + assert(handler); + debug(29, 5) ("chargeStartCheck: '%s'\n", user); + if (Config.Program.charge == NULL) { + handler(data, NULL); + return; + } + r = xcalloc(1, sizeof(chargeStateData)); + cbdataAdd(r, cbdataXfree, 0); + r->handler = handler; + cbdataLock(data); + r->data = data; + snprintf(buf, 8192, "? %s\n", user); + helperSubmit(chargers, buf, chargeHandleReply, r); +} + +void +chargeInit(void) +{ + static int init = 0; + if (!Config.Program.charge) + return; + if (chargers == NULL) + chargers = helperCreate("charger"); + chargers->cmdline = Config.Program.charge; + chargers->n_to_start = Config.chargeChildren; + chargers->ipc_type = IPC_TCP_SOCKET; + helperOpenServers(chargers); + if (!init) { + cachemgrRegister("charger", + "User Charger Stats", + chargeStats, 0, 1); + init++; + } +} + +void +chargeShutdown(void) +{ + if (!chargers) + return; + helperShutdown(chargers); + if (!shutting_down) + return; + helperFree(chargers); + chargers = NULL; +} diff -urN squid-2.2.STABLE4/src/client_side.c squid-2.2.STABLE4.DJL3/src/client_side.c --- squid-2.2.STABLE4/src/client_side.c Tue May 11 00:00:40 1999 +++ squid-2.2.STABLE4.DJL3/src/client_side.c Thu Jul 22 20:09:20 1999 @@ -637,6 +637,9 @@ if (http->entry) mem = http->entry->mem_obj; if (http->out.size || http->log_type) { + Packer p; + MemBuf mb; + http->al.icp.opcode = ICP_INVALID; http->al.url = http->log_uri; debug(33, 9) ("httpRequestFree: al.url='%s'\n", http->al.url); @@ -648,23 +651,21 @@ http->al.cache.size = http->out.size; http->al.cache.code = http->log_type; http->al.cache.msec = tvSubMsec(http->start, current_time); + http->al.http.method = request->method; + http->al.http.version = request->http_ver; + http->al.hier = request->hier; if (request->user_ident[0]) - http->al.cache.ident = request->user_ident; + http->al.cache.ident = request->user_ident; else - http->al.cache.ident = conn->ident; - if (request) { - Packer p; - MemBuf mb; - memBufDefInit(&mb); - packerToMemInit(&p, &mb); - httpHeaderPackInto(&request->header, &p); - http->al.http.method = request->method; - http->al.http.version = request->http_ver; - http->al.headers.request = xstrdup(mb.buf); - http->al.hier = request->hier; - packerClean(&p); - memBufClean(&mb); - } + http->al.cache.ident = conn->ident; + memBufDefInit(&mb); + packerToMemInit(&p, &mb); + httpHeaderPackInto(&request->header, &p); + http->al.headers.request = xstrdup(mb.buf); + packerClean(&p); + memBufClean(&mb); + if (request->flags.charge && request->hier.code != HIER_NONE) + chargeStartCharge(http->al.cache.ident, http->al.cache.size); accessLogLog(&http->al); clientUpdateCounters(http); clientdbUpdate(conn->peer.sin_addr, http->log_type, PROTO_HTTP, http->out.size); diff -urN squid-2.2.STABLE4/src/comm_select.c squid-2.2.STABLE4.DJL3/src/comm_select.c --- squid-2.2.STABLE4/src/comm_select.c Tue Jan 19 06:23:33 1999 +++ squid-2.2.STABLE4.DJL3/src/comm_select.c Fri Jul 23 22:03:37 1999 @@ -158,6 +158,31 @@ return 0; } +#if DELAY_POOLS +static int slowfdcnt = 0; +static int slowfdarr[SQUID_MAXFD]; + +static void +commAddSlowFd(int fd) +{ + assert(slowfdcnt < SQUID_MAXFD); + slowfdarr[slowfdcnt++] = fd; +} + +static int +commGetSlowFd(void) +{ + int whichfd, retfd; + + if(!slowfdcnt) + return -1; + whichfd = squid_random() % slowfdcnt; + retfd = slowfdarr[whichfd]; + slowfdarr[whichfd] = slowfdarr[--slowfdcnt]; + return retfd; +} +#endif + #if HAVE_POLL static int comm_check_incoming_poll_handlers(int nfds, int *fds) @@ -270,6 +295,9 @@ comm_poll(int msec) { struct pollfd pfds[SQUID_MAXFD]; +#if DELAY_POOLS + fd_set slowfds; +#endif PF *hdl = NULL; int fd; int i; @@ -299,8 +327,26 @@ int events; events = 0; /* Check each open socket for a handler. */ +#if DELAY_POOLS + if (fd_table[i].read_handler) { + switch (commDeferRead(i)) { + case 0: + events |= POLLRDNORM; + break; + case 1: + break; + case -1: + events |= POLLRDNORM; + FD_SET(i, &slowfds); + break; + default: + assert(!"commDeferRead(i) should return 0,1,-1"); + } + } +#else if (fd_table[i].read_handler && !commDeferRead(i)) events |= POLLRDNORM; +#endif if (fd_table[i].write_handler) events |= POLLWRNORM; if (events) { @@ -358,6 +404,12 @@ if (revents & (POLLRDNORM | POLLIN | POLLHUP | POLLERR)) { debug(5, 6) ("comm_poll: FD %d ready for reading\n", fd); if ((hdl = F->read_handler)) { +#if DELAY_POOLS + if (FD_ISSET(fd, &slowfds)) { + commAddSlowFd(fd); + goto skip_r; + } +#endif F->read_handler = NULL; hdl(fd, F->read_data); Counter.select_fds++; @@ -367,6 +419,9 @@ if (commCheckHTTPIncoming) comm_poll_http_incoming(); } +#if DELAY_POOLS + skip_r: +#endif if (revents & (POLLWRNORM | POLLOUT | POLLHUP | POLLERR)) { debug(5, 5) ("comm_poll: FD %d ready for writing\n", fd); if ((hdl = F->write_handler)) { @@ -408,6 +463,20 @@ comm_poll_icp_incoming(); if (callhttp) comm_poll_http_incoming(); +#if DELAY_POOLS + while((fd = commGetSlowFd()) != -1) { + fde *F = &fd_table[fd]; + debug(5, 6) ("comm_select: slow FD %d selected for reading\n", fd); + hdl = F->read_handler; + F->read_handler = NULL; + hdl(fd, F->read_data); + Counter.select_fds++; + if (commCheckICPIncoming) + comm_poll_icp_incoming(); + if (commCheckHTTPIncoming) + comm_poll_http_incoming(); + } +#endif #if !ALARM_UPDATES_TIME getCurrentTime(); Counter.select_time += (current_dtime - start); @@ -535,6 +604,9 @@ { fd_set readfds; fd_set writefds; +#if DELAY_POOLS + fd_set slowfds; +#endif PF *hdl = NULL; int fd; int maxfd; @@ -569,6 +641,9 @@ howmany(maxfd, FD_MASK_BITS) * FD_MASK_BYTES); xmemcpy(&writefds, &global_writefds, howmany(maxfd, FD_MASK_BITS) * FD_MASK_BYTES); +#if DELAY_POOLS + FD_ZERO(&slowfds); +#endif /* remove stalled FDs */ maxindex = howmany(maxfd, FD_MASK_BITS); fdsp = (fd_mask *) & readfds; @@ -580,14 +655,33 @@ continue; /* Found a set bit */ fd = (j * FD_MASK_BITS) + k; +#if DELAY_POOLS + switch (commDeferRead(fd)) { + case 0: + break; + case 1: + FD_CLR(fd, &readfds); + break; + case -1: + FD_SET(fd, &slowfds); + break; + default: + assert(!"commDeferRead(fd) should return 0,1,-1"); + } +#else if (commDeferRead(fd)) FD_CLR(fd, &readfds); +#endif } } #if DEBUG_FDBITS for (i = 0; i < maxfd; i++) { /* Check each open socket for a handler. */ +#if DELAY_POOLS + if (fd_table[i].read_handler && commDeferRead(i) != 1) { +#else if (fd_table[i].read_handler && !commDeferRead(i)) { +#endif assert(FD_ISSET(i, &readfds)); } if (fd_table[i].write_handler) { @@ -651,12 +745,18 @@ #endif if (fdIsIcp(fd)) { callicp = 1; - continue; + goto out_r; } if (fdIsHttp(fd)) { callhttp = 1; - continue; + goto out_r; + } +#if DELAY_POOLS + if (FD_ISSET(fd, &slowfds)) { + commAddSlowFd(fd); + goto out_r; } +#endif F = &fd_table[fd]; debug(5, 6) ("comm_select: FD %d ready for reading\n", fd); if (F->read_handler) { @@ -670,6 +770,7 @@ comm_select_icp_incoming(); if (commCheckHTTPIncoming) comm_select_http_incoming(); + out_r: EBIT_CLR(tmask, k); /* this bit is done */ if (tmask == 0) break; /* and no more bits left */ @@ -690,11 +791,11 @@ #endif if (fdIsIcp(fd)) { callicp = 1; - continue; + goto out_w; } if (fdIsHttp(fd)) { callhttp = 1; - continue; + goto out_w; } F = &fd_table[fd]; debug(5, 5) ("comm_select: FD %d ready for writing\n", fd); @@ -709,6 +810,7 @@ comm_select_icp_incoming(); if (commCheckHTTPIncoming) comm_select_http_incoming(); + out_w: EBIT_CLR(tmask, k); /* this bit is done */ if (tmask == 0) break; /* and no more bits left */ @@ -718,6 +820,23 @@ comm_select_icp_incoming(); if (callhttp) comm_select_http_incoming(); +#if DELAY_POOLS + while((fd = commGetSlowFd()) != -1) { + F = &fd_table[fd]; + debug(5, 6) ("comm_select: slow FD %d selected for reading\n", fd); + if (F->read_handler) { + hdl = F->read_handler; + F->read_handler = NULL; + commUpdateReadBits(fd, NULL); + hdl(fd, F->read_data); + Counter.select_fds++; + } + if (commCheckICPIncoming) + comm_select_icp_incoming(); + if (commCheckHTTPIncoming) + comm_select_http_incoming(); + } +#endif return COMM_OK; } while (timeout > current_dtime); debug(5, 8) ("comm_select: time out: %d\n", (int) squid_curtime); diff -urN squid-2.2.STABLE4/src/dns.c squid-2.2.STABLE4.DJL3/src/dns.c --- squid-2.2.STABLE4/src/dns.c Mon Jan 18 03:46:28 1999 +++ squid-2.2.STABLE4.DJL3/src/dns.c Thu Jul 22 20:09:20 1999 @@ -68,8 +68,8 @@ cachemgrRegister("dns", "Dnsserver Statistics", dnsStats, 0, 1); + init++; } - init++; } void diff -urN squid-2.2.STABLE4/src/enums.h squid-2.2.STABLE4.DJL3/src/enums.h --- squid-2.2.STABLE4/src/enums.h Tue May 11 00:02:02 1999 +++ squid-2.2.STABLE4.DJL3/src/enums.h Thu Jul 22 20:09:20 1999 @@ -121,7 +121,10 @@ ACL_LOOKUP_NEEDED, ACL_LOOKUP_PENDING, ACL_LOOKUP_DONE, - ACL_PROXY_AUTH_NEEDED + ACL_PROXY_AUTH_NEEDED, + ACL_CHARGE_NEEDED, + ACL_CHARGE_DONE_OK, + ACL_CHARGE_DONE_FAIL } acl_lookup_state; enum { diff -urN squid-2.2.STABLE4/src/forward.c squid-2.2.STABLE4.DJL3/src/forward.c --- squid-2.2.STABLE4/src/forward.c Wed Jul 7 09:52:50 1999 +++ squid-2.2.STABLE4.DJL3/src/forward.c Thu Jul 22 20:10:43 1999 @@ -307,6 +307,10 @@ * is closed. */ assert(fwdState->server_fd > -1); + /* This is for requests which are failed as a no_charge peer request + * then re-tried from a parent. + */ + request->flags.charge |= request->flags.orig_charge; if (fwdState->servers && (p = fwdState->servers->peer)) { p->stats.fetches++; httpStart(fwdState); @@ -458,6 +462,12 @@ { StoreEntry *e = data; MemObject *mem = e->mem_obj; +#ifdef DELAY_POOLS + int i = 0; +#else +#define i 0 +#endif + if (mem == NULL) return 0; #if DELAY_POOLS @@ -465,14 +475,21 @@ (void) 0; else if (delayIsNoDelay(fd)) (void) 0; - else if (delayMostBytesWanted(mem, 1) == 0) - return 1; + else { + i = delayMostBytesWanted(mem, INT_MAX); + if (i == 0) + return 1; + i = -(i != INT_MAX); + } #endif if (EBIT_TEST(e->flags, ENTRY_FWD_HDR_WAIT)) - return 0; + return i; if (mem->inmem_hi - storeLowestMemReaderOffset(e) < READ_AHEAD_GAP) - return 0; + return i; return 1; +#ifndef DELAY_POOLS +#undef i +#endif } void diff -urN squid-2.2.STABLE4/src/http.c squid-2.2.STABLE4.DJL3/src/http.c --- squid-2.2.STABLE4/src/http.c Wed Apr 28 06:14:09 1999 +++ squid-2.2.STABLE4.DJL3/src/http.c Thu Jul 22 20:09:20 1999 @@ -894,6 +894,11 @@ if (httpState->peer->options.no_delay) delaySetNoDelay(fd); #endif + if (httpState->peer->options.no_charge && orig_req->flags.charge) { + orig_req->flags.charge = 0; + orig_req->flags.orig_charge = 1; + /* client_side.c & hence the logging never sees proxy_req */ + } } else { httpState->request = requestLink(orig_req); httpState->orig_request = requestLink(orig_req); diff -urN squid-2.2.STABLE4/src/main.c squid-2.2.STABLE4.DJL3/src/main.c --- squid-2.2.STABLE4/src/main.c Tue May 11 00:30:37 1999 +++ squid-2.2.STABLE4.DJL3/src/main.c Thu Jul 22 20:09:20 1999 @@ -323,6 +323,7 @@ dnsShutdown(); redirectShutdown(); authenticateShutdown(); + chargeShutdown(); storeDirCloseSwapLogs(); errorClean(); parseConfigFile(ConfigFile); @@ -333,6 +334,7 @@ dnsInit(); redirectInit(); authenticateInit(); + chargeInit(); serverConnectionsOpen(); if (theOutIcpConnection >= 0) { if (!Config2.Accel.on || Config.onoff.accel_with_proxy) @@ -437,6 +439,7 @@ dnsInit(); redirectInit(); authenticateInit(); + chargeInit(); useragentOpenLog(); httpHeaderInitModule(); /* must go before any header processing (e.g. the one in errorInitialize) */ httpReplyInitModule(); /* must go before accepting replies */ @@ -618,6 +621,7 @@ dnsShutdown(); redirectShutdown(); authenticateShutdown(); + chargeShutdown(); eventAdd("SquidShutdown", SquidShutdown, NULL, (double) (wait + 1), 1); } eventRun(); diff -urN squid-2.2.STABLE4/src/neighbors.c squid-2.2.STABLE4.DJL3/src/neighbors.c --- squid-2.2.STABLE4/src/neighbors.c Wed Jul 7 10:02:26 1999 +++ squid-2.2.STABLE4.DJL3/src/neighbors.c Thu Jul 22 20:09:20 1999 @@ -1162,6 +1162,8 @@ if (p->options.no_delay) storeAppendPrintf(sentry, " no-delay"); #endif + if (p->options.no_charge) + storeAppendPrintf(sentry, " no-charge"); if (p->login) storeAppendPrintf(sentry, " login=%s", p->login); if (p->mcast.ttl > 0) diff -urN squid-2.2.STABLE4/src/protos.h squid-2.2.STABLE4.DJL3/src/protos.h --- squid-2.2.STABLE4/src/protos.h Wed Jul 7 09:52:51 1999 +++ squid-2.2.STABLE4.DJL3/src/protos.h Thu Jul 22 20:09:20 1999 @@ -673,6 +673,11 @@ extern void authenticateInit(void); extern void authenticateShutdown(void); +extern void chargeStartCheck(const char *, RH *, void *); +extern void chargeStartCharge(const char *, long); +extern void chargeInit(void); +extern void chargeShutdown(void); + extern void refreshAddToList(const char *, int, time_t, int, time_t); extern int refreshIsCachable(const StoreEntry *); extern int refreshCheckHTTP(const StoreEntry *, request_t *); diff -urN squid-2.2.STABLE4/src/redirect.c squid-2.2.STABLE4.DJL3/src/redirect.c --- squid-2.2.STABLE4/src/redirect.c Sun Jan 24 10:22:59 1999 +++ squid-2.2.STABLE4.DJL3/src/redirect.c Thu Jul 22 20:09:20 1999 @@ -139,8 +139,8 @@ cachemgrRegister("redirector", "URL Redirector Stats", redirectStats, 0, 1); + init++; } - init++; } void diff -urN squid-2.2.STABLE4/src/squid.h squid-2.2.STABLE4.DJL3/src/squid.h --- squid-2.2.STABLE4/src/squid.h Tue Apr 13 06:58:20 1999 +++ squid-2.2.STABLE4.DJL3/src/squid.h Thu Jul 22 20:11:47 1999 @@ -175,6 +175,9 @@ #if HAVE_GETOPT_H #include #endif +#if HAVE_LIMITS_H +#include +#endif #if HAVE_DIRENT_H #include diff -urN squid-2.2.STABLE4/src/ssl.c squid-2.2.STABLE4.DJL3/src/ssl.c --- squid-2.2.STABLE4/src/ssl.c Wed Jul 7 09:52:53 1999 +++ squid-2.2.STABLE4.DJL3/src/ssl.c Thu Jul 22 20:10:43 1999 @@ -119,7 +119,14 @@ sslDeferServerRead(int fdnotused, void *data) { SslStateData *s = data; - return delayBytesWanted(s->delay_id, 0, 1) == 0; + int i; + + i = delayBytesWanted(s->delay_id, 0, INT_MAX); + if(i == INT_MAX) + return 0; + if(i == 0) + return 1; + return -1; } #endif @@ -534,6 +541,8 @@ sslState->delay_id = 0; } #endif + if (g && g->options.no_charge) + sslState->request->flags.charge = 0; hierarchyNote(&sslState->request->hier, fs->peer ? fs->code : DIRECT, sslState->host); diff -urN squid-2.2.STABLE4/src/structs.h squid-2.2.STABLE4.DJL3/src/structs.h --- squid-2.2.STABLE4/src/structs.h Sat Feb 20 06:35:36 1999 +++ squid-2.2.STABLE4.DJL3/src/structs.h Thu Jul 22 20:09:20 1999 @@ -284,12 +284,14 @@ char *dnsserver; char *redirect; wordlist *authenticate; + wordlist *charge; char *pinger; char *unlinkd; } Program; int dnsChildren; int redirectChildren; int authenticateChildren; + int chargeChildren; int authenticateTTL; struct { char *host; @@ -1029,6 +1031,7 @@ #if DELAY_POOLS unsigned int no_delay:1; #endif + unsigned int no_charge:1; } options; int weight; struct { @@ -1283,6 +1286,8 @@ #endif unsigned int accelerated:1; unsigned int internal:1; + unsigned int charge:1; + unsigned int orig_charge:1; }; struct _request_t {