- Fixed WAIS forwarding.
- Fixed dnsserver coredump bug caused by using both -D and
-s options.
+ * Changes below have been made to SQUID_2_1_PATCH2
+ - Fixed EBIT macro bugs when the bitmask is a 64-bit long.
+ - Fixed proxy auth NULL password bug.
+ - Fixed queueing of multiple peerRefreshDNS events.
+ - Added a stack of StoreEntry objects to be released after
+ store rebuild completes.
+ - Fixed NULL pointer bugs with too-large requests (found by
+ Martin Lathoud).
+ - Fixed reading replies from buggy ident servers. Replies
+ might not have terminating CR or LF (Henrik Nordstrom).
Changes to Squid-2.0 (October 2, 1998):
/*
- * $Id: acl.cc,v 1.189 1998/11/26 01:15:49 glenn Exp $
+ * $Id: acl.cc,v 1.190 1998/12/04 22:20:10 wessels Exp $
*
* DEBUG: section 28 Access Control
* AUTHOR: Duane Wessels
*user = buf;
if ((*password = strchr(*user, ':')) != NULL)
*(*password)++ = '\0';
- if (password == NULL) {
+ if (*password == NULL) {
debug(28, 1) ("aclDecodeProxyAuth: no password in proxy authorization header\n");
return 0;
}
char *user, *password;
int ok;
acl_proxy_auth_user *auth_user;
-
assert(!checklist->auth_user);
-
if (!checklist->request->flags.accelerated) {
/* Proxy auth on proxy requests */
proxy_auth = httpHeaderGetStr(&checklist->request->header,
}
ok = aclDecodeProxyAuth(proxy_auth, &user, &password, login_buf,
sizeof(login_buf));
- assert(ok); /* We should never get here unless the above succeeds in aclMatchProxyAuth */
-
+ /*
+ * if aclDecodeProxyAuth() fails, the same call should have failed
+ * in aclMatchProxyAuth, and we should never get this far.
+ */
+ assert(ok);
debug(28, 4) ("aclLookupProxyAuthStart: going to ask authenticator on %s\n", user);
/* we must still check this user's password */
auth_user = memAllocate(MEM_ACL_PROXY_AUTH_USER);
auth_user->passwd_ok = -1;
auth_user->expiretime = -1;
checklist->auth_user = auth_user;
-
authenticateStart(checklist->auth_user, aclLookupProxyAuthDone,
checklist);
}
/*
- * $Id: client_side.cc,v 1.422 1998/11/12 06:28:00 wessels Exp $
+ * $Id: client_side.cc,v 1.423 1998/12/04 22:20:13 wessels Exp $
*
* DEBUG: section 33 Client-side Routines
* AUTHOR: Duane Wessels
/* check: reply was parsed and range iterator was initialized */
assert(i->prefix_size > 0);
/* filter out data according to range specs */
- /* note: order of loop conditions is significant! */
while (clientCanPackMoreRanges(http, i, size)) {
off_t start; /* offset of still missing data */
assert(i->spec);
httpReplyDestroy(rep);
rep = NULL;
} else {
- /* leave space for growth incase we do ranges */
+ /* leave space for growth in case we do ranges */
memBufInit(&mb, CLIENT_SOCK_SZ, 2 * CLIENT_SOCK_SZ);
}
/* append body if any */
- if (body_buf && body_size) {
- if (http->request->range) {
- /* Only GET requests should have ranges */
- assert(http->request->method == METHOD_GET);
- /* clientPackMoreRanges() updates http->out.offset */
- /* force the end of the transfer if we are done */
- if (!clientPackMoreRanges(http, body_buf, body_size, &mb))
- http->flags.done_copying = 1;
- } else {
- http->out.offset += body_size;
- check_size += body_size;
- memBufAppend(&mb, body_buf, body_size);
- }
+ if (http->request->range) {
+ /* Only GET requests should have ranges */
+ assert(http->request->method == METHOD_GET);
+ /* clientPackMoreRanges() updates http->out.offset */
+ /* force the end of the transfer if we are done */
+ if (!clientPackMoreRanges(http, body_buf, body_size, &mb))
+ http->flags.done_copying = 1;
+ } else if (body_buf && body_size) {
+ http->out.offset += body_size;
+ check_size += body_size;
+ memBufAppend(&mb, body_buf, body_size);
}
if (!http->request->range && http->request->method == METHOD_GET)
assert(check_size == size);
debug(33, 0) ("This request = %d bytes.\n",
(int) conn->in.offset);
err = errorCon(ERR_INVALID_REQ, HTTP_REQUEST_ENTITY_TOO_LARGE);
- http->entry = clientCreateStoreEntry(http, request->method, null_request_flags);
+ http = parseHttpRequestAbort(conn, "error:request-too-large");
+ /* add to the client request queue */
+ for (H = &conn->chr; *H; H = &(*H)->next);
+ *H = http;
+ http->entry = clientCreateStoreEntry(http, METHOD_NONE, null_request_flags);
errorAppendEntry(http->entry, err);
return;
}
/*
- * $Id: comm_select.cc,v 1.22 1998/11/12 06:28:01 wessels Exp $
+ * $Id: comm_select.cc,v 1.23 1998/12/04 22:20:15 wessels Exp $
*
* DEBUG: section 5 Socket Functions
*
#ifndef NBBY
#define NBBY 8
#endif
+#define FD_MASK_BYTES sizeof(fd_mask)
+#define FD_MASK_BITS (FD_MASK_BYTES*NBBY)
+
/* STATIC */
#if !HAVE_POLL
comm_select_http_incoming();
callicp = callhttp = 0;
maxfd = Biggest_FD + 1;
- /* copy whole integers. XXX breaks if fd_mask is a long */
- xmemcpy(&readfds, &global_readfds, ((maxfd + 31) / 32) * 4);
- xmemcpy(&writefds, &global_writefds, ((maxfd + 31) / 32) * 4);
+ xmemcpy(&readfds, &global_readfds,
+ howmany(maxfd, FD_MASK_BITS) * FD_MASK_BYTES);
+ xmemcpy(&writefds, &global_writefds,
+ howmany(maxfd, FD_MASK_BITS) * FD_MASK_BYTES);
/* remove stalled FDs */
- maxindex = howmany(maxfd, (sizeof(*fdsp) * NBBY));
+ maxindex = howmany(maxfd, FD_MASK_BITS);
fdsp = (fd_mask *) & readfds;
for (j = 0; j < maxindex; j++) {
if ((tmask = fdsp[j]) == 0)
continue; /* no bits here */
- for (k = 0; k < (sizeof(*fdsp) * NBBY); k++) {
+ for (k = 0; k < FD_MASK_BITS; k++) {
if (!EBIT_TEST(tmask, k))
continue;
/* Found a set bit */
- fd = (j * (sizeof(*fdsp) * NBBY)) + k;
+ fd = (j * FD_MASK_BITS) + k;
if (commDeferRead(fd))
FD_CLR(fd, &readfds);
}
continue;
/* Scan return fd masks for ready descriptors */
fdsp = (fd_mask *) & readfds;
- maxindex = howmany(maxfd, (sizeof(*fdsp) * NBBY));
+ maxindex = howmany(maxfd, FD_MASK_BITS);
for (j = 0; j < maxindex; j++) {
if ((tmask = fdsp[j]) == 0)
continue; /* no bits here */
- for (k = 0; k < (sizeof(*fdsp) * NBBY); k++) {
+ for (k = 0; k < FD_MASK_BITS; k++) {
if (!EBIT_TEST(tmask, k))
continue;
/* Found a set bit */
- fd = (j * (sizeof(*fdsp) * NBBY)) + k;
+ fd = (j * FD_MASK_BITS) + k;
#if DEBUG_FDBITS
debug(5, 9) ("FD %d bit set for reading\n", fd);
assert(FD_ISSET(fd, &readfds));
for (j = 0; j < maxindex; j++) {
if ((tmask = fdsp[j]) == 0)
continue; /* no bits here */
- for (k = 0; k < (sizeof(*fdsp) * NBBY); k++) {
+ for (k = 0; k < FD_MASK_BITS; k++) {
if (!EBIT_TEST(tmask, k))
continue;
/* Found a set bit */
- fd = (j * (sizeof(*fdsp) * NBBY)) + k;
+ fd = (j * FD_MASK_BITS) + k;
#if DEBUG_FDBITS
debug(5, 9) ("FD %d bit set for writing\n", fd);
assert(FD_ISSET(fd, &writefds));
/*
- * $Id: ident.cc,v 1.45 1998/09/04 23:04:53 wessels Exp $
+ * $Id: ident.cc,v 1.46 1998/12/04 22:20:17 wessels Exp $
*
* DEBUG: section 30 Ident (RFC 931)
* AUTHOR: Duane Wessels
buf[0] = '\0';
Counter.syscalls.sock.reads++;
- len = read(fd, buf, BUFSIZ);
+ len = read(fd, buf, BUFSIZ - 1);
fd_bytes(fd, len, FD_READ);
if (len > 0) {
+ buf[len] = '\0';
if ((t = strchr(buf, '\r')))
*t = '\0';
if ((t = strchr(buf, '\n')))
/*
- * $Id: mem.cc,v 1.36 1998/11/13 21:02:05 rousskov Exp $
+ * $Id: mem.cc,v 1.37 1998/12/04 22:20:19 wessels Exp $
*
* DEBUG: section 13 High Level Memory Pool Management
* AUTHOR: Harvest Derived
memDataInit(MEM_PEER, "peer", sizeof(peer), 0);
#if USE_CACHE_DIGESTS
memDataInit(MEM_PEER_DIGEST, "PeerDigest", sizeof(PeerDigest), 0);
+ memDataInit(MEM_DIGEST_FETCH_STATE, "DigestFetchState", sizeof(DigestFetchState), 0);
#endif
memDataInit(MEM_PINGERECHODATA, "pingerEchoData",
sizeof(pingerEchoData), 0);
/*
- * $Id: store.cc,v 1.473 1998/11/21 02:13:30 wessels Exp $
+ * $Id: store.cc,v 1.474 1998/12/04 22:20:24 wessels Exp $
*
* DEBUG: section 20 Storage Manager
* AUTHOR: Harvest Derived
static int getKeyCounter(void);
static int storeKeepInMemory(const StoreEntry *);
static OBJH storeCheckCachableStats;
+static EVH storeLateRelease;
/*
* local variables
static int store_swap_low = 0;
static int store_swap_mid = 0;
static int store_maintain_rate;
+static Stack LateReleaseStack;
static MemObject *
new_MemObject(const char *url, const char *log_url)
storeReleaseRequest(e);
return;
}
- if (store_rebuilding) {
- debug(20, 2) ("storeRelease: Delaying release until store is rebuilt: '%s'\n",
- storeUrl(e));
- storeExpireNow(e);
- storeReleaseRequest(e);
- return;
- }
#if USE_ASYNC_IO
/*
* Make sure all forgotten async ops are cancelled
*/
aioCancel(-1, e);
#endif
+ if (store_rebuilding) {
+ storeSetPrivateKey(e);
+ if (e->mem_obj) {
+ storeSetMemStatus(e, NOT_IN_MEMORY);
+ destroy_MemObject(e);
+ }
+ /*
+ * Fake a call to storeLockObject(). When rebuilding is done,
+ * we'll just call storeUnlockObject() on these.
+ */
+ e->lock_count++;
+ stackPush(&LateReleaseStack, e);
+ return;
+ }
storeLog(STORE_LOG_RELEASE, e);
if (e->swap_file_number > -1) {
storeUnlinkFileno(e->swap_file_number);
destroy_StoreEntry(e);
}
+static void
+storeLateRelease(void *unused)
+{
+ StoreEntry *e;
+ int i;
+ static int n = 0;
+ if (store_rebuilding) {
+ eventAdd("storeLateRelease", storeLateRelease, NULL, 1.0, 1);
+ return;
+ }
+ for (i = 0; i < 10; i++) {
+ e = stackPop(&LateReleaseStack);
+ if (e == NULL) {
+ /* done! */
+ debug(20, 0) ("storeLateRelease: released %d objects\n", n);
+ return;
+ }
+ storeUnlockObject(e);
+ n++;
+ }
+ eventAdd("storeLateRelease", storeLateRelease, NULL, 0.0, 1);
+}
+
/* return 1 if a store entry is locked */
static int
storeEntryLocked(const StoreEntry * e)
storeDirOpenSwapLogs();
store_list.head = store_list.tail = NULL;
inmem_list.head = inmem_list.tail = NULL;
+ stackInit(&LateReleaseStack);
+ eventAdd("storeLateRelease", storeLateRelease, NULL, 1.0, 1);
storeRebuildStart();
cachemgrRegister("storedir",
"Store Directory Stats",