/*
- * $Id: CacheDigest.cc,v 1.28 1998/11/25 09:00:17 wessels Exp $
+ * $Id: CacheDigest.cc,v 1.29 1998/12/05 00:54:08 wessels Exp $
*
* DEBUG: section 70 Cache Digest
* AUTHOR: Alex Rousskov
{
assert(cd);
cacheDigestClean(cd);
- memFree(MEM_CACHE_DIGEST, cd);
+ memFree(cd, MEM_CACHE_DIGEST);
}
CacheDigest *
storeAppendPrintf(sentry, "Digest guesses stats for %s:\n", label);
storeAppendPrintf(sentry, "guess\t hit\t\t miss\t\t total\t\t\n");
storeAppendPrintf(sentry, " \t #\t %%\t #\t %%\t #\t %%\t\n");
-
storeAppendPrintf(sentry, "true\t %d\t %.2f\t %d\t %.2f\t %d\t %.2f\n",
stats->true_hits, xpercent(stats->true_hits, tot_count),
stats->true_misses, xpercent(stats->true_misses, tot_count),
/*
- * $Id: HttpHdrCc.cc,v 1.15 1998/07/22 20:36:43 wessels Exp $
+ * $Id: HttpHdrCc.cc,v 1.16 1998/12/05 00:54:09 wessels Exp $
*
* DEBUG: section 65 HTTP Cache Control Header
* AUTHOR: Alex Rousskov
httpHdrCcDestroy(HttpHdrCc * cc)
{
assert(cc);
- memFree(MEM_HTTP_HDR_CC, cc);
+ memFree(cc, MEM_HTTP_HDR_CC);
}
HttpHdrCc *
/*
- * $Id: HttpHdrContRange.cc,v 1.9 1998/09/23 21:52:20 rousskov Exp $
+ * $Id: HttpHdrContRange.cc,v 1.10 1998/12/05 00:54:09 wessels Exp $
*
* DEBUG: section 68 HTTP Content-Range Header
* AUTHOR: Alex Rousskov
httpHdrContRangeDestroy(HttpHdrContRange * range)
{
assert(range);
- memFree(MEM_HTTP_HDR_CONTENT_RANGE, range);
+ memFree(range, MEM_HTTP_HDR_CONTENT_RANGE);
}
HttpHdrContRange *
/*
- * $Id: HttpHdrRange.cc,v 1.16 1998/11/12 06:27:49 wessels Exp $
+ * $Id: HttpHdrRange.cc,v 1.17 1998/12/05 00:54:10 wessels Exp $
*
* DEBUG: section 64 HTTP Range Header
* AUTHOR: Alex Rousskov
static void
httpHdrRangeSpecDestroy(HttpHdrRangeSpec * spec)
{
- memFree(MEM_HTTP_HDR_RANGE_SPEC, spec);
+ memFree(spec, MEM_HTTP_HDR_RANGE_SPEC);
}
while (range->specs.count)
httpHdrRangeSpecDestroy(stackPop(&range->specs));
stackClean(&range->specs);
- memFree(MEM_HTTP_HDR_RANGE, range);
+ memFree(range, MEM_HTTP_HDR_RANGE);
}
HttpHdrRange *
/*
- * $Id: HttpHeader.cc,v 1.58 1998/11/12 06:27:50 wessels Exp $
+ * $Id: HttpHeader.cc,v 1.59 1998/12/05 00:54:11 wessels Exp $
*
* DEBUG: section 55 HTTP Header
* AUTHOR: Alex Rousskov
assert(Headers[e->id].stat.aliveCount);
Headers[e->id].stat.aliveCount--;
e->id = -1;
- memFree(MEM_HTTP_HDR_ENTRY, e);
+ memFree(e, MEM_HTTP_HDR_ENTRY);
}
/* parses and inits header entry, returns new entry on success */
/*
- * $Id: HttpReply.cc,v 1.33 1998/11/12 06:27:51 wessels Exp $
+ * $Id: HttpReply.cc,v 1.34 1998/12/05 00:54:11 wessels Exp $
*
* DEBUG: section 58 HTTP Reply (Response)
* AUTHOR: Alex Rousskov
/* put a 0-terminator */
xstrncpy(headers, buf, 4096);
success = httpReplyParseStep(rep, headers, 0);
- memFree(MEM_4K_BUF, headers);
+ memFree(headers, MEM_4K_BUF);
return success == 1;
}
static void
httpReplyDoDestroy(HttpReply * rep)
{
- memFree(MEM_HTTP_REPLY, rep);
+ memFree(rep, MEM_HTTP_REPLY);
}
/* sync this routine when you update HttpReply struct */
/*
- * $Id: HttpRequest.cc,v 1.18 1998/08/14 09:22:31 wessels Exp $
+ * $Id: HttpRequest.cc,v 1.19 1998/12/05 00:54:12 wessels Exp $
*
* DEBUG: section 73 HTTP Request
* AUTHOR: Duane Wessels
httpHdrCcDestroy(req->cache_control);
if (req->range)
httpHdrRangeDestroy(req->range);
- memFree(MEM_REQUEST_T, req);
+ memFree(req, MEM_REQUEST_T);
}
request_t *
/*
- * $Id: acl.cc,v 1.190 1998/12/04 22:20:10 wessels Exp $
+ * $Id: acl.cc,v 1.191 1998/12/05 00:54:13 wessels Exp $
*
* DEBUG: section 28 Access Control
* AUTHOR: Duane Wessels
for (B = *head, T = head; B; T = &B->next, B = B->next);
*T = A;
/* We lock _acl_access structures in aclCheck() */
- cbdataAdd(A, MEM_ACL_ACCESS);
+ cbdataAdd(A, memFree, MEM_ACL_ACCESS);
}
/**************/
{
int i;
aclCheck_t *checklist = memAllocate(MEM_ACLCHECK_T);
- cbdataAdd(checklist, MEM_ACLCHECK_T);
+ cbdataAdd(checklist, memFree, MEM_ACLCHECK_T);
checklist->access_list = A;
/*
* aclCheck() makes sure checklist->access_list is a valid
acl_time_data *next = NULL;
for (; data; data = next) {
next = data->next;
- memFree(MEM_ACL_TIME_DATA, data);
+ memFree(data, MEM_ACL_TIME_DATA);
}
}
next = data->next;
regfree(&data->regex);
safe_free(data->pattern);
- memFree(MEM_RELIST, data);
+ memFree(data, MEM_RELIST);
}
}
acl_proxy_auth_user *u = data;
xfree(u->user);
xfree(u->passwd);
- memFree(MEM_ACL_PROXY_AUTH_USER, u);
+ memFree(u, MEM_ACL_PROXY_AUTH_USER);
}
static void
aclFreeIpData(void *p)
{
- memFree(MEM_ACL_IP_DATA, p);
+ memFree(p, MEM_ACL_IP_DATA);
}
void
break;
}
safe_free(a->cfgline);
- memFree(MEM_ACL, a);
+ memFree(a, MEM_ACL);
}
*head = NULL;
}
acl_list *next = NULL;
for (; list; list = next) {
next = list->next;
- memFree(MEM_ACL_LIST, list);
+ memFree(list, MEM_ACL_LIST);
}
}
/*
- * $Id: asn.cc,v 1.51 1998/11/12 06:27:55 wessels Exp $
+ * $Id: asn.cc,v 1.52 1998/12/05 00:54:14 wessels Exp $
*
* DEBUG: section 53 AS Number handling
* AUTHOR: Duane Wessels, Kostas Anagnostakis
StoreEntry *e;
request_t *req;
ASState *asState = xcalloc(1, sizeof(ASState));
- cbdataAdd(asState, MEM_NONE);
+ cbdataAdd(asState, cbdataXfree, 0);
debug(53, 3) ("asnCacheStart: AS %d\n", as);
snprintf(asres, 4096, "whois://%s/!gAS%d", Config.as_whois_server, as);
asState->as_number = as;
char *t;
debug(53, 3) ("asHandleReply: Called with size=%d\n", size);
if (e->store_status == STORE_ABORTED) {
- memFree(MEM_4K_BUF, buf);
+ memFree(buf, MEM_4K_BUF);
asStateFree(asState);
return;
}
if (size == 0 && e->mem_obj->inmem_hi > 0) {
- memFree(MEM_4K_BUF, buf);
+ memFree(buf, MEM_4K_BUF);
asStateFree(asState);
return;
} else if (size < 0) {
debug(53, 1) ("asHandleReply: Called with size=%d\n", size);
- memFree(MEM_4K_BUF, buf);
+ memFree(buf, MEM_4K_BUF);
asStateFree(asState);
return;
}
asState);
} else {
debug(53, 3) ("asHandleReply: Done: %s\n", storeUrl(e));
- memFree(MEM_4K_BUF, buf);
+ memFree(buf, MEM_4K_BUF);
asStateFree(asState);
}
}
/*
- * $Id: authenticate.cc,v 1.9 1998/11/12 06:27:56 wessels Exp $
+ * $Id: authenticate.cc,v 1.10 1998/12/05 00:54:15 wessels Exp $
*
* DEBUG: section 29 Authenticator
* AUTHOR: Duane Wessels
return;
}
r = xcalloc(1, sizeof(authenticateStateData));
- cbdataAdd(r, MEM_NONE);
+ cbdataAdd(r, cbdataXfree, 0);
r->handler = handler;
cbdataLock(data);
r->data = data;
/*
- * $Id: cache_cf.cc,v 1.312 1998/11/25 09:00:18 wessels Exp $
+ * $Id: cache_cf.cc,v 1.313 1998/12/05 00:54:16 wessels Exp $
*
* DEBUG: section 3 Configuration File Parsing
* AUTHOR: Harvest Derived
while ((w = *list) != NULL) {
*list = w->next;
safe_free(w->key);
- memFree(MEM_WORDLIST, w);
+ memFree(w, MEM_WORDLIST);
}
*list = NULL;
}
intlist *n = NULL;
for (w = *list; w; w = n) {
n = w->next;
- memFree(MEM_INTLIST, w);
+ memFree(w, MEM_INTLIST);
}
*list = NULL;
}
}
}
#endif
+ if (Config.Wais.relayHost) {
+ if (Config.Wais.peer)
+ cbdataFree(Config.Wais.peer);
+ Config.Wais.peer = memAllocate(MEM_PEER);
+ cbdataAdd(Config.Wais.peer, peerDestroy, MEM_PEER);
+ Config.Wais.peer->host = Config.Wais.relayHost;
+ Config.Wais.peer->http_port = Config.Wais.relayPort;
+ }
}
/* Parse a time specification from the config file. Store the
p->carp.hash += (p->carp.hash << 19) + *token;
}
#endif
- cbdataAdd(p, MEM_PEER); /* must preceed peerDigestCreate */
+ cbdataAdd(p, peerDestroy, MEM_PEER); /* must preceed peerDigestCreate */
#if USE_CACHE_DIGESTS
if (!p->options.no_digest) {
p->digest = peerDigestCreate(p);
peer *p;
while ((p = *P) != NULL) {
*P = p->next;
- peerDestroy(p);
+ cbdataUnlock(p);
}
Config.npeers = 0;
}
/*
- * $Id: cbdata.cc,v 1.26 1998/12/02 05:14:17 wessels Exp $
+ * $Id: cbdata.cc,v 1.27 1998/12/05 00:54:17 wessels Exp $
*
* DEBUG: section 45 Callback Data Registry
* AUTHOR: Duane Wessels
struct _cbdata *next;
int valid;
int locks;
- mem_type mem_type;
+ CBDUNL *unlock_func;
+ int id;
#if CBDATA_DEBUG
const char *file;
int line;
static HASHCMP cbdata_cmp;
static HASHHASH cbdata_hash;
static void cbdataReallyFree(cbdata * c);
+static OBJH cbdataDump;
static int
cbdata_cmp(const void *p1, const void *p2)
void
#if CBDATA_DEBUG
-cbdataAddDbg(const void *p, mem_type mtype, const char *file, int line)
+cbdataAddDbg(const void *p, CBDUNL * unlock_func, int id, const char *file, int line)
#else
-cbdataAdd(const void *p, mem_type mtype)
+cbdataAdd(const void *p, CBDUNL * unlock_func, int id)
#endif
{
cbdata *c;
c = xcalloc(1, sizeof(cbdata));
c->key = p;
c->valid = 1;
- c->mem_type = mtype;
+ c->unlock_func = unlock_func;
+ c->id = id;
#if CBDATA_DEBUG
c->file = file;
c->line = line;
static void
cbdataReallyFree(cbdata * c)
{
- mem_type mtype = c->mem_type;
+ CBDUNL *unlock_func = c->unlock_func;
void *p = (void *) c->key;
+ int id = c->id;
hash_remove_link(htable, (hash_link *) c);
cbdataCount--;
xfree(c);
- if (mtype == MEM_DONTFREE)
- return;
debug(45, 3) ("cbdataReallyFree: Freeing %p\n", p);
- if (mtype == MEM_NONE)
- xfree(p);
- else
- memFree(mtype, p);
+ if (unlock_func)
+ unlock_func(p, id);
}
void
return c->valid;
}
-
void
+cbdataXfree(void *p, int unused)
+{
+ xfree(p);
+}
+
+
+static void
cbdataDump(StoreEntry * sentry)
{
hash_link *hptr;
/*
- * $Id: client_db.cc,v 1.42 1998/10/13 23:33:32 wessels Exp $
+ * $Id: client_db.cc,v 1.43 1998/12/05 00:54:18 wessels Exp $
*
* DEBUG: section 0 Client Database
* AUTHOR: Duane Wessels
{
ClientInfo *c = data;
safe_free(c->key);
- memFree(MEM_CLIENT_INFO, c);
+ memFree(c, MEM_CLIENT_INFO);
}
void
/*
- * $Id: client_side.cc,v 1.423 1998/12/04 22:20:13 wessels Exp $
+ * $Id: client_side.cc,v 1.424 1998/12/05 00:54:18 wessels Exp $
*
* DEBUG: section 33 Client-side Routines
* AUTHOR: Duane Wessels
request_t *r = http->request;
debug(33, 3) ("clientCacheHit: %s, %d bytes\n", http->uri, (int) size);
if (http->entry == NULL) {
- memFree(MEM_CLIENT_SOCK_BUF, buf);
+ memFree(buf, MEM_CLIENT_SOCK_BUF);
debug(33, 3) ("clientCacheHit: request aborted\n");
return;
} else if (size < 0) {
/* swap in failure */
- memFree(MEM_CLIENT_SOCK_BUF, buf);
+ memFree(buf, MEM_CLIENT_SOCK_BUF);
debug(33, 3) ("clientCacheHit: swapin failure for %s\n", http->uri);
http->log_type = LOG_TCP_SWAPFAIL_MISS;
if ((e = http->entry)) {
* punt to clientProcessMiss.
*/
if (e->mem_status == IN_MEMORY || e->store_status == STORE_OK) {
- memFree(MEM_CLIENT_SOCK_BUF, buf);
+ memFree(buf, MEM_CLIENT_SOCK_BUF);
clientProcessMiss(http);
} else if (size == CLIENT_SOCK_SZ && http->out.offset == 0) {
- memFree(MEM_CLIENT_SOCK_BUF, buf);
+ memFree(buf, MEM_CLIENT_SOCK_BUF);
clientProcessMiss(http);
} else {
debug(33, 3) ("clientCacheHit: waiting for HTTP reply headers\n");
http->log_type = LOG_TCP_MISS;
clientProcessMiss(http);
}
- memFree(MEM_CLIENT_SOCK_BUF, buf);
+ memFree(buf, MEM_CLIENT_SOCK_BUF);
} else if (r->flags.ims) {
/*
* Handle If-Modified-Since requests from the client
if (mem->reply->sline.status != HTTP_OK) {
debug(33, 4) ("clientCacheHit: Reply code %d != 200\n",
mem->reply->sline.status);
- memFree(MEM_CLIENT_SOCK_BUF, buf);
+ memFree(buf, MEM_CLIENT_SOCK_BUF);
clientProcessMiss(http);
} else if (modifiedSince(e, http->request)) {
http->log_type = LOG_TCP_IMS_HIT;
} else {
MemBuf mb = httpPacked304Reply(e->mem_obj->reply);
http->log_type = LOG_TCP_IMS_HIT;
- memFree(MEM_CLIENT_SOCK_BUF, buf);
+ memFree(buf, MEM_CLIENT_SOCK_BUF);
storeUnregister(e, http);
storeUnlockObject(e);
e = clientCreateStoreEntry(http, http->request->method, null_request_flags);
if (conn->chr != http) {
/* there is another object in progress, defer this one */
debug(33, 1) ("clientSendMoreData: Deferring %s\n", storeUrl(entry));
- memFree(MEM_CLIENT_SOCK_BUF, buf);
+ memFree(buf, MEM_CLIENT_SOCK_BUF);
return;
} else if (entry && entry->store_status == STORE_ABORTED) {
/* call clientWriteComplete so the client socket gets closed */
clientWriteComplete(fd, NULL, 0, COMM_OK, http);
- memFree(MEM_CLIENT_SOCK_BUF, buf);
+ memFree(buf, MEM_CLIENT_SOCK_BUF);
return;
} else if (size < 0) {
/* call clientWriteComplete so the client socket gets closed */
clientWriteComplete(fd, NULL, 0, COMM_OK, http);
- memFree(MEM_CLIENT_SOCK_BUF, buf);
+ memFree(buf, MEM_CLIENT_SOCK_BUF);
return;
} else if (size == 0) {
/* call clientWriteComplete so the client socket gets closed */
clientWriteComplete(fd, NULL, 0, COMM_OK, http);
- memFree(MEM_CLIENT_SOCK_BUF, buf);
+ memFree(buf, MEM_CLIENT_SOCK_BUF);
return;
}
if (http->out.offset == 0) {
/* write */
comm_write_mbuf(fd, mb, clientWriteComplete, http);
/* if we don't do it, who will? */
- memFree(MEM_CLIENT_SOCK_BUF, buf);
+ memFree(buf, MEM_CLIENT_SOCK_BUF);
}
static void
parseHttpRequestAbort(ConnStateData * conn, const char *uri)
{
clientHttpRequest *http = xcalloc(1, sizeof(clientHttpRequest));
- cbdataAdd(http, MEM_NONE);
+ cbdataAdd(http, cbdataXfree, 0);
http->conn = conn;
http->start = current_time;
http->req_sz = conn->in.offset;
/* Ok, all headers are received */
http = xcalloc(1, sizeof(clientHttpRequest));
- cbdataAdd(http, MEM_NONE);
+ cbdataAdd(http, cbdataXfree, 0);
http->http_ver = http_ver;
http->conn = conn;
http->start = current_time;
connState->ident.fd = -1;
connState->in.size = REQUEST_BUF_SIZE;
connState->in.buf = xcalloc(connState->in.size, 1);
- cbdataAdd(connState, MEM_NONE);
+ cbdataAdd(connState, cbdataXfree, 0);
/* XXX account connState->in.buf */
comm_add_close_handler(fd, connStateFree, connState);
if (Config.onoff.log_fqdn)
/*
- * $Id: comm.cc,v 1.292 1998/11/20 23:58:50 wessels Exp $
+ * $Id: comm.cc,v 1.293 1998/12/05 00:54:20 wessels Exp $
*
* DEBUG: section 5 Socket Functions
* AUTHOR: Harvest Derived
{
ConnectStateData *cs = xcalloc(1, sizeof(ConnectStateData));
debug(5, 3) ("commConnectStart: FD %d, %s:%d\n", fd, host, (int) port);
- cbdataAdd(cs, MEM_NONE);
+ cbdataAdd(cs, cbdataXfree, 0);
cs->fd = fd;
cs->host = xstrdup(host);
cs->port = port;
/*
- * $Id: defines.h,v 1.69 1998/11/30 23:45:39 wessels Exp $
+ * $Id: defines.h,v 1.70 1998/12/05 00:54:21 wessels Exp $
*
*
* SQUID Internet Object Cache http://squid.nlanr.net/Squid/
#define ICP_VERSION_3 3
#define ICP_VERSION_CURRENT ICP_VERSION_2
-#define DIRECT_NO 0
-#define DIRECT_MAYBE 1
-#define DIRECT_YES 2
+#define DIRECT_UNKNOWN 0
+#define DIRECT_NO 1
+#define DIRECT_MAYBE 2
+#define DIRECT_YES 3
#define REDIRECT_AV_FACTOR 1000
/*
- * $Id: disk.cc,v 1.136 1998/09/29 01:32:58 wessels Exp $
+ * $Id: disk.cc,v 1.137 1998/12/05 00:54:21 wessels Exp $
*
* DEBUG: section 6 Disk I/O Routines
* AUTHOR: Harvest Derived
* the state data.
*/
if (fd < 0) {
- memFree(MEM_DREAD_CTRL, ctrl_dat);
+ memFree(ctrl_dat, MEM_DREAD_CTRL);
return;
}
#if USE_ASYNC_IO
errno = errcode;
if (len == -2 && errcode == -2) { /* Read cancelled - cleanup */
cbdataUnlock(ctrl_dat->client_data);
- memFree(MEM_DREAD_CTRL, ctrl_dat);
+ memFree(ctrl_dat, MEM_DREAD_CTRL);
return;
}
fd_bytes(fd, len, FD_READ);
F->flags.calling_io_handler = 0;
#endif /* OPTIMISTIC_IO */
cbdataUnlock(ctrl_dat->client_data);
- memFree(MEM_DREAD_CTRL, ctrl_dat);
+ memFree(ctrl_dat, MEM_DREAD_CTRL);
}
/*
- * $Id: enums.h,v 1.139 1998/11/25 08:58:10 wessels Exp $
+ * $Id: enums.h,v 1.140 1998/12/05 00:54:22 wessels Exp $
*
*
* SQUID Internet Object Cache http://squid.nlanr.net/Squid/
DEFAULT_PARENT,
SINGLE_PARENT,
FIRSTUP_PARENT,
- NO_PARENT_DIRECT,
FIRST_PARENT_MISS,
CLOSEST_PARENT_MISS,
CLOSEST_PARENT,
ENTRY_CACHABLE,
ENTRY_DISPATCHED,
KEY_PRIVATE,
-#ifndef PPNR_WIP
- ENTRY_UNUSED_08,
-#else
ENTRY_FWD_HDR_WAIT,
-#endif /* PPNR_WIP */
ENTRY_NEGCACHED,
ENTRY_VALIDATED,
ENTRY_BAD_LENGTH
/*
- * $Id: errorpage.cc,v 1.143 1998/11/12 06:28:05 wessels Exp $
+ * $Id: errorpage.cc,v 1.144 1998/12/05 00:54:23 wessels Exp $
*
* DEBUG: section 4 Error Generation
* AUTHOR: Duane Wessels
err->request->err_type = err->type;
/* moved in front of errorBuildBuf @?@ */
err->flags.flag_cbdata = 1;
- cbdataAdd(err, MEM_NONE);
+ cbdataAdd(err, cbdataXfree, 0);
rep = errorBuildReply(err);
comm_write_mbuf(fd, httpReplyPack(rep), errorSendComplete, err);
httpReplyDestroy(rep);
/*
- * $Id: forward.cc,v 1.32 1998/11/21 16:54:27 wessels Exp $
+ * $Id: forward.cc,v 1.33 1998/12/05 00:54:23 wessels Exp $
*
* DEBUG: section 17 Request Forwarding
* AUTHOR: Duane Wessels
#include "squid.h"
-static void fwdStartComplete(peer * p, void *data);
-static void fwdStartFail(peer * p, void *data);
+static PSC fwdStartComplete;
static void fwdDispatch(FwdState *);
static void fwdConnectStart(FwdState * fwdState);
static void fwdStateFree(FwdState * fwdState);
static PF fwdServerClosed;
static CNCB fwdConnectDone;
static int fwdCheckRetry(FwdState * fwdState);
+static int fwdReforward(FwdState *);
+static void fwdStartFail(FwdState *);
+
+static void
+fwdServerFree(FwdServer * fs)
+{
+ if (fs->peer)
+ cbdataUnlock(fs->peer);
+ memFree(fs, MEM_FWD_SERVER);
+}
+
+static void
+fwdServersFree(FwdServer ** FS)
+{
+ FwdServer *fs;
+ while ((fs = *FS)) {
+ *FS = fs->next;
+ fwdServerFree(fs);
+ }
+}
static void
fwdStateFree(FwdState * fwdState)
{
- FwdServer *s;
- FwdServer *n = fwdState->servers;
StoreEntry *e = fwdState->entry;
ErrorState *err;
int sfd;
storeAbort(e, 0);
}
}
- while ((s = n)) {
- n = s->next;
- xfree(s->host);
- memFree(MEM_FWD_SERVER, s);
- }
- fwdState->servers = NULL;
+ fwdServersFree(&fwdState->servers);
requestUnlink(fwdState->request);
fwdState->request = NULL;
storeUnregisterAbort(e);
fwdConnectDone(int server_fd, int status, void *data)
{
FwdState *fwdState = data;
+ FwdServer *fs = fwdState->servers;
ErrorState *err;
+ request_t *request = fwdState->request;
assert(fwdState->server_fd == server_fd);
if (status == COMM_ERR_DNS) {
debug(17, 4) ("fwdConnectDone: Unknown host: %s\n",
- fwdState->request->host);
+ request->host);
err = errorCon(ERR_DNS_FAIL, HTTP_SERVICE_UNAVAILABLE);
err->dnsserver_msg = xstrdup(dns_error_message);
- err->request = requestLink(fwdState->request);
+ err->request = requestLink(request);
errorAppendEntry(fwdState->entry, err);
comm_close(server_fd);
} else if (status != COMM_OK) {
+ assert(fs);
err = errorCon(ERR_CONNECT_FAIL, HTTP_SERVICE_UNAVAILABLE);
err->xerrno = errno;
- err->host = xstrdup(fwdState->servers->host);
- err->port = fwdState->servers->port;
- err->request = requestLink(fwdState->request);
+ if (fs->peer) {
+ err->host = xstrdup(fs->peer->host);
+ err->port = fs->peer->http_port;
+ } else {
+ err->host = xstrdup(request->host);
+ err->port = request->port;
+ }
+ err->request = requestLink(request);
errorAppendEntry(fwdState->entry, err);
- assert(fwdState->servers);
- if (fwdState->servers->peer)
- peerCheckConnectStart(fwdState->servers->peer);
+ if (fs->peer)
+ peerCheckConnectStart(fs->peer);
comm_close(server_fd);
} else {
fd_note(server_fd, storeUrl(fwdState->entry));
const char *url = storeUrl(fwdState->entry);
int fd;
ErrorState *err;
- FwdServer *srv = fwdState->servers;
- assert(srv);
+ FwdServer *fs = fwdState->servers;
+ const char *host;
+ unsigned short port;
+ assert(fs);
assert(fwdState->server_fd == -1);
debug(17, 3) ("fwdConnectStart: %s\n", url);
- if ((fd = pconnPop(srv->host, srv->port)) >= 0) {
+ if (fs->peer) {
+ host = fs->peer->host;
+ port = fs->peer->http_port;
+ } else {
+ host = fwdState->request->host;
+ port = fwdState->request->port;
+ }
+ if ((fd = pconnPop(host, port)) >= 0) {
debug(17, 3) ("fwdConnectStart: reusing pconn FD %d\n", fd);
fwdState->server_fd = fd;
comm_add_close_handler(fd, fwdServerClosed, fwdState);
Config.Timeout.connect,
fwdConnectTimeout,
fwdState);
- commConnectStart(fd,
- srv->host,
- srv->port,
- fwdConnectDone,
- fwdState);
+ commConnectStart(fd, host, port, fwdConnectDone, fwdState);
}
static void
-fwdStartComplete(peer * p, void *data)
+fwdStartComplete(FwdServer * servers, void *data)
{
FwdState *fwdState = data;
- FwdServer *s;
- s = memAllocate(MEM_FWD_SERVER);
- if (NULL != p) {
- s->host = xstrdup(p->host);
- s->port = p->http_port;
- s->peer = p;
- } else if (fwdState->request->protocol == PROTO_WAIS) {
- if (!Config.Wais.relayHost) {
- fwdStartFail(NULL, fwdState);
- return;
- } else {
- s->host = xstrdup(Config.Wais.relayHost);
- s->port = Config.Wais.relayPort;
- }
+ if (servers != NULL) {
+ fwdState->servers = servers;
+ fwdConnectStart(fwdState);
} else {
- s->host = xstrdup(fwdState->request->host);
- s->port = fwdState->request->port;
+ fwdStartFail(fwdState);
}
- fwdState->servers = s;
- fwdConnectStart(fwdState);
}
static void
-fwdStartFail(peer * peernotused, void *data)
+fwdStartFail(FwdState * fwdState)
{
- FwdState *fwdState = data;
ErrorState *err;
err = errorCon(ERR_CANNOT_FORWARD, HTTP_SERVICE_UNAVAILABLE);
err->request = requestLink(fwdState->request);
assert(fwdState->server_fd > -1);
if (fwdState->servers && (p = fwdState->servers->peer)) {
p->stats.fetches++;
- httpStart(fwdState, fwdState->server_fd);
+ httpStart(fwdState);
} else {
switch (request->protocol) {
case PROTO_HTTP:
- httpStart(fwdState, fwdState->server_fd);
+ httpStart(fwdState);
break;
case PROTO_GOPHER:
- gopherStart(entry, fwdState->server_fd);
+ gopherStart(fwdState);
break;
case PROTO_FTP:
- ftpStart(request, entry, fwdState->server_fd);
+ ftpStart(fwdState);
break;
case PROTO_WAIS:
- waisStart(request, entry, fwdState->server_fd);
+ waisStart(fwdState);
break;
case PROTO_CACHEOBJ:
case PROTO_INTERNAL:
fatal_dump("Should never get here");
break;
case PROTO_WHOIS:
- whoisStart(fwdState, fwdState->server_fd);
+ whoisStart(fwdState);
break;
default:
debug(17, 1) ("fwdDispatch: Cannot retrieve '%s'\n",
}
}
+static int
+fwdReforward(FwdState * fwdState)
+{
+ StoreEntry *e = fwdState->entry;
+ FwdServer *fs = fwdState->servers;
+ http_status s;
+ assert(e->store_status == STORE_PENDING);
+ assert(e->mem_obj);
+ if (fwdState->n_tries > 9)
+ return 0;
+ assert(fs);
+ fwdState->servers = fs->next;
+ fwdServerFree(fs);
+ if (fwdState->servers == NULL) {
+ debug(17, 3) ("fwdReforward: No forward-servers left\n");
+ return 0;
+ }
+ s = e->mem_obj->reply->sline.status;
+ debug(17, 3) ("fwdReforward: status %d\n", (int) s);
+ switch (s) {
+ case HTTP_FORBIDDEN:
+ case HTTP_INTERNAL_SERVER_ERROR:
+ case HTTP_NOT_IMPLEMENTED:
+ case HTTP_BAD_GATEWAY:
+ case HTTP_SERVICE_UNAVAILABLE:
+ case HTTP_GATEWAY_TIMEOUT:
+ return 1;
+ default:
+ return 0;
+ }
+ /* NOTREACHED */
+}
+
/* PUBLIC FUNCTIONS */
void
-fwdStart(int fd, StoreEntry * e, request_t * r, struct in_addr peer_addr)
+fwdStart(int fd, StoreEntry * e, request_t * r, struct in_addr client_addr)
{
FwdState *fwdState;
aclCheck_t ch;
int answer;
ErrorState *err;
/*
- * peer_addr == no_addr indicates this is an "internal" request
+ * client_addr == no_addr indicates this is an "internal" request
* from peer_digest.c, asn.c, netdb.c, etc and should always
* be allowed. yuck, I know.
*/
- if (peer_addr.s_addr != no_addr.s_addr) {
+ if (client_addr.s_addr != no_addr.s_addr) {
/*
* Check if this host is allowed to fetch MISSES from us (miss_access)
*/
memset(&ch, '\0', sizeof(aclCheck_t));
- ch.src_addr = peer_addr;
+ ch.src_addr = client_addr;
ch.request = r;
answer = aclCheckFast(Config.accessList.miss, &ch);
if (answer == 0) {
err = errorCon(ERR_FORWARDING_DENIED, HTTP_FORBIDDEN);
err->request = requestLink(r);
- err->src_addr = peer_addr;
+ err->src_addr = client_addr;
errorAppendEntry(e, err);
return;
}
break;
}
fwdState = memAllocate(MEM_FWD_STATE);
- cbdataAdd(fwdState, MEM_FWD_STATE);
+ cbdataAdd(fwdState, memFree, MEM_FWD_STATE);
fwdState->entry = e;
fwdState->client_fd = fd;
fwdState->server_fd = -1;
fwdState->start = squid_curtime;
storeLockObject(e);
storeRegisterAbort(e, fwdAbort, fwdState);
- peerSelect(r, e, fwdStartComplete, fwdStartFail, fwdState);
+ peerSelect(r, e, fwdStartComplete, fwdState);
}
int
void
fwdFail(FwdState * fwdState, int err_code, http_status http_code, int xerrno)
{
-#ifdef PPNR_WIP
assert(EBIT_TEST(fwdState->entry->flags, ENTRY_FWD_HDR_WAIT));
-#endif /* PPNR_WIP */
debug(17, 3) ("fwdFail: %s \"%s\"\n\t%s\n",
err_type_str[err_code],
httpStatusString(http_code),
fwdState->server_fd = -1;
fwdStateFree(fwdState);
}
+
+/*
+ * server-side modules call fwdComplete() when they are done
+ * downloading an object. Then, we either 1) re-forward the
+ * request somewhere else if needed, or 2) call storeComplete()
+ * to finish it off
+ */
+void
+fwdComplete(FwdState * fwdState)
+{
+ StoreEntry *e = fwdState->entry;
+ assert(e->store_status == STORE_PENDING);
+ debug(17, 3) ("fwdComplete: %s\n\tstatus %d", storeUrl(e),
+ e->mem_obj->reply->sline.status);
+ if (!EBIT_TEST(e->flags, ENTRY_FWD_HDR_WAIT)) {
+ debug(17, 3) ("ENTRY_FWD_HDR_WAIT not set, calling storeComplete\n");
+ storeComplete(e);
+ } else if (fwdReforward(fwdState)) {
+debug(0,0)("fwdComplete: re-forwarding %d %s\n",
+ e->mem_obj->reply->sline.status,
+ storeUrl(e));
+ assert(fwdState->server_fd > -1);
+ /* XXX this breaks pconn */
+ comm_remove_close_handler(fwdState->server_fd,
+ fwdServerClosed, fwdState);
+ fwdState->server_fd = -1;
+ storeEntryReset(e);
+ fwdStartComplete(fwdState->servers, fwdState);
+ } else {
+ EBIT_CLR(e->flags, ENTRY_FWD_HDR_WAIT);
+ storeComplete(e);
+ }
+}
/*
- * $Id: fqdncache.cc,v 1.125 1998/11/20 06:13:15 wessels Exp $
+ * $Id: fqdncache.cc,v 1.126 1998/12/05 00:54:24 wessels Exp $
*
* DEBUG: section 35 FQDN Cache
* AUTHOR: Harvest Derived
dlinkDelete(&f->lru, &lru_list);
safe_free(f->name);
safe_free(f->error_message);
- memFree(MEM_FQDNCACHE_ENTRY, f);
+ memFree(f, MEM_FQDNCACHE_ENTRY);
}
/* return match for given name */
p->handler((f->status == FQDN_CACHED) ? f->names[0] : NULL,
p->handlerData);
}
- memFree(MEM_FQDNCACHE_PENDING, p);
+ memFree(p, MEM_FQDNCACHE_PENDING);
}
f->pending_head = NULL; /* nuke list */
debug(35, 10) ("fqdncache_call_pending: Called %d handlers.\n", nhandler);
/* for HIT, PENDING, DISPATCHED we've returned. For MISS we submit */
c = xcalloc(1, sizeof(*c));
c->data = f;
- cbdataAdd(c, MEM_NONE);
+ cbdataAdd(c, cbdataXfree, 0);
f->status = FQDN_DISPATCHED;
fqdncacheLockEntry(f); /* lock while FQDN_DISPATCHED */
dnsSubmit(f->name, fqdncacheHandleReply, c);
int k;
while ((p = f->pending_head)) {
f->pending_head = p->next;
- memFree(MEM_FQDNCACHE_PENDING, p);
+ memFree(p, MEM_FQDNCACHE_PENDING);
}
for (k = 0; k < (int) f->name_count; k++)
safe_free(f->names[k]);
safe_free(f->name);
safe_free(f->error_message);
- memFree(MEM_FQDNCACHE_ENTRY, f);
+ memFree(f, MEM_FQDNCACHE_ENTRY);
}
void
/*
- * $Id: ftp.cc,v 1.256 1998/11/23 22:43:30 wessels Exp $
+ * $Id: ftp.cc,v 1.257 1998/12/05 00:54:25 wessels Exp $
*
* DEBUG: section 9 File Transfer Protocol (FTP)
* AUTHOR: Harvest Derived
u_short port;
} data;
struct _ftp_flags flags;
+ FwdState *fwd;
} FtpStateData;
typedef struct {
storeUnregisterAbort(ftpState->entry);
storeUnlockObject(ftpState->entry);
if (ftpState->reply_hdr) {
- memFree(MEM_8K_BUF, ftpState->reply_hdr);
+ memFree(ftpState->reply_hdr, MEM_8K_BUF);
ftpState->reply_hdr = NULL;
}
requestUnlink(ftpState->request);
xstrncpy(ftpState->data.buf, line, ftpState->data.size);
ftpState->data.offset = strlen(ftpState->data.buf);
}
- memFree(MEM_4K_BUF, line);
+ memFree(line, MEM_4K_BUF);
xfree(sbuf);
}
ftpListingFinish(ftpState);
if (!ftpState->flags.put) {
storeTimestampsSet(ftpState->entry);
- storeComplete(ftpState->entry);
+ fwdComplete(ftpState->fwd);
}
/* expect the "transfer complete" message on the control socket */
ftpScheduleReadControlReply(ftpState, 1);
}
void
-ftpStart(request_t * request, StoreEntry * entry, int fd)
+ftpStart(FwdState * fwd)
{
+ request_t *request = fwd->request;
+ StoreEntry *entry = fwd->entry;
+ int fd = fwd->server_fd;
LOCAL_ARRAY(char, realm, 8192);
const char *url = storeUrl(entry);
FtpStateData *ftpState = xcalloc(1, sizeof(FtpStateData));
HttpReply *reply;
StoreEntry *pe = NULL;
const cache_key *key = NULL;
- cbdataAdd(ftpState, MEM_NONE);
+ cbdataAdd(ftpState, cbdataXfree, 0);
debug(9, 3) ("ftpStart: '%s'\n", url);
Counter.server.all.requests++;
Counter.server.ftp.requests++;
ftpState->size = -1;
ftpState->flags.pasv_supported = 1;
ftpState->flags.rest_supported = 1;
+ ftpState->fwd = fwd;
if (ftpState->request->method == METHOD_PUT)
ftpState->flags.put = 1;
if (!ftpCheckAuth(ftpState, &request->header)) {
/* create appropriate reply */
ftpAuthRequired(reply, request, realm);
httpReplySwapOut(reply, entry);
- storeComplete(entry);
+ fwdComplete(ftpState->fwd);
ftpStateFree(-1, ftpState);
return;
}
/*
- * $Id: gopher.cc,v 1.140 1998/09/23 20:13:50 wessels Exp $
+ * $Id: gopher.cc,v 1.141 1998/12/05 00:54:26 wessels Exp $
*
* DEBUG: section 10 Gopher
* AUTHOR: Harvest Derived
int len;
char *buf; /* pts to a 4k page */
int fd;
+ FwdState *fwdState;
} GopherStateData;
static PF gopherStateFree;
if (gopherState->entry) {
storeUnlockObject(gopherState->entry);
}
- memFree(MEM_4K_BUF, gopherState->buf);
+ memFree(gopherState->buf, MEM_4K_BUF);
gopherState->buf = NULL;
cbdataFree(gopherState);
}
gopherEndHTML(data);
storeTimestampsSet(entry);
storeBufferFlush(entry);
- storeComplete(entry);
+ fwdComplete(gopherState->fwdState);
comm_close(fd);
} else {
if (gopherState->conversion != NORMAL) {
gopherReadReply,
data, 0);
}
- memFree(MEM_4K_BUF, buf);
+ memFree(buf, MEM_4K_BUF);
return;
}
errorAppendEntry(entry, err);
comm_close(fd);
if (buf)
- memFree(MEM_4K_BUF, buf); /* Allocated by gopherSendRequest. */
+ memFree(buf, MEM_4K_BUF); /* Allocated by gopherSendRequest. */
return;
}
/*
commSetSelect(fd, COMM_SELECT_READ, gopherReadReply, gopherState, 0);
commSetDefer(fd, fwdCheckDeferRead, entry);
if (buf)
- memFree(MEM_4K_BUF, buf); /* Allocated by gopherSendRequest. */
+ memFree(buf, MEM_4K_BUF); /* Allocated by gopherSendRequest. */
}
/* This will be called when connect completes. Write request. */
}
void
-gopherStart(StoreEntry * entry, int fd)
+gopherStart(FwdState * fwdState)
{
+ int fd = fwdState->server_fd;
+ StoreEntry *entry = fwdState->entry;
GopherStateData *gopherState = CreateGopherStateData();
storeLockObject(entry);
gopherState->entry = entry;
}
}
gopherToHTML(gopherState, (char *) NULL, 0);
- storeComplete(entry);
+ fwdComplete(gopherState->fwdState);
comm_close(fd);
return;
}
gopherState->fd = fd;
+ gopherState->fwdState = fwdState;
commSetSelect(fd, COMM_SELECT_WRITE, gopherSendRequest, gopherState, 0);
commSetTimeout(fd, Config.Timeout.read, gopherTimeout, gopherState);
}
CreateGopherStateData(void)
{
GopherStateData *gd = xcalloc(1, sizeof(GopherStateData));
- cbdataAdd(gd, MEM_NONE);
+ cbdataAdd(gd, cbdataXfree, 0);
gd->buf = memAllocate(MEM_4K_BUF);
return (gd);
}
}
hlp->n_running++;
srv = memAllocate(MEM_HELPER_SERVER);
- cbdataAdd(srv, MEM_HELPER_SERVER);
+ cbdataAdd(srv, memFree, MEM_HELPER_SERVER);
srv->flags.alive = 1;
srv->index = k;
srv->rfd = rfd;
helperCreate(const char *name)
{
helper *hlp = memAllocate(MEM_HELPER);
- cbdataAdd(hlp, MEM_HELPER);
+ cbdataAdd(hlp, memFree, MEM_HELPER);
hlp->id_name = name;
return hlp;
}
helper_request *r;
assert(srv->rfd == fd);
if (srv->buf) {
- memFree(MEM_8K_BUF, srv->buf);
+ memFree(srv->buf, MEM_8K_BUF);
srv->buf = NULL;
}
if ((r = srv->request)) {
if ((link = hlp->queue.head)) {
r = link->data;
dlinkDelete(link, &hlp->queue);
- memFree(MEM_DLINK_NODE, link);
+ memFree(link, MEM_DLINK_NODE);
hlp->stats.queue_size--;
}
return r;
{
cbdataUnlock(r->data);
xfree(r->buf);
- memFree(MEM_HELPER_REQUEST, r);
+ memFree(r, MEM_HELPER_REQUEST);
}
/*
- * $Id: http.cc,v 1.332 1998/11/12 06:28:10 wessels Exp $
+ * $Id: http.cc,v 1.333 1998/12/05 00:54:28 wessels Exp $
*
* DEBUG: section 11 Hypertext Transfer Protocol (HTTP)
* AUTHOR: Harvest Derived
return;
storeUnlockObject(httpState->entry);
if (httpState->reply_hdr) {
- memFree(MEM_8K_BUF, httpState->reply_hdr);
+ memFree(httpState->reply_hdr, MEM_8K_BUF);
httpState->reply_hdr = NULL;
}
requestUnlink(httpState->request);
debug(11, 4) ("httpTimeout: FD %d: '%s'\n", fd, storeUrl(entry));
assert(entry->store_status == STORE_PENDING);
if (entry->mem_obj->inmem_hi == 0) {
- fwdFail(httpState->fwdState, ERR_READ_TIMEOUT, HTTP_GATEWAY_TIMEOUT, 0);
+ fwdFail(httpState->fwd, ERR_READ_TIMEOUT, HTTP_GATEWAY_TIMEOUT, 0);
} else {
storeAbort(entry, 0);
}
if (ignoreErrno(errno)) {
commSetSelect(fd, COMM_SELECT_READ, httpReadReply, httpState, 0);
} else if (entry->mem_obj->inmem_hi == 0) {
- fwdFail(httpState->fwdState, ERR_READ_ERROR, HTTP_INTERNAL_SERVER_ERROR, errno);
+ fwdFail(httpState->fwd, ERR_READ_ERROR, HTTP_INTERNAL_SERVER_ERROR, errno);
comm_close(fd);
} else {
storeAbort(entry, 0);
comm_close(fd);
}
} else if (len == 0 && entry->mem_obj->inmem_hi == 0) {
- fwdFail(httpState->fwdState, ERR_ZERO_SIZE_OBJECT, HTTP_SERVICE_UNAVAILABLE, errno);
+ fwdFail(httpState->fwd, ERR_ZERO_SIZE_OBJECT, HTTP_SERVICE_UNAVAILABLE, errno);
httpState->eof = 1;
comm_close(fd);
} else if (len == 0) {
* we want to process the reply headers.
*/
httpProcessReplyHeader(httpState, buf, len);
-#ifdef PPNR_WIP
- storePPNR(entry);
-#endif /* PPNR_WIP */
- storeComplete(entry); /* deallocates mem_obj->request */
+ fwdComplete(httpState->fwd);
comm_close(fd);
} else {
-#ifndef PPNR_WIP
- if (httpState->reply_hdr_state < 2)
-#else
if (httpState->reply_hdr_state < 2) {
-#endif /* PPNR_WIP */
httpProcessReplyHeader(httpState, buf, len);
-#ifdef PPNR_WIP
- if (httpState->reply_hdr_state == 2)
- storePPNR(entry);
+ if (httpState->reply_hdr_state == 2) {
+ http_status s = entry->mem_obj->reply->sline.status;
+ /* If its "successful" reply, allow the client
+ * to get it
+ */
+ if (s >= 200 && s < 300)
+ EBIT_CLR(entry->flags, ENTRY_FWD_HDR_WAIT);
+ }
}
-#endif /* PPNR_WIP */
storeAppend(entry, buf, len);
#ifdef OPTIMISTIC_IO
if (entry->store_status == STORE_ABORTED) {
commSetTimeout(fd, -1, NULL, NULL);
commSetSelect(fd, COMM_SELECT_READ, NULL, NULL, 0);
comm_remove_close_handler(fd, httpStateFree, httpState);
- storeComplete(entry); /* deallocates mem_obj->request */
- /* call storeComplete BEFORE fwdUnregister or else fwdUnregister
+ fwdComplete(httpState->fwd);
+ /* call fwdComplete BEFORE fwdUnregister or else fwdUnregister
* will storeAbort */
- fwdUnregister(fd, httpState->fwdState);
+ fwdUnregister(fd, httpState->fwd);
pconnPush(fd, request->host, request->port);
httpState->fd = -1;
httpStateFree(-1, httpState);
* - we can actually parse client Range specs
* - the specs are expected to be simple enough (e.g. no out-of-order ranges)
* - reply will be cachable
- * (If the reply will be uncachable we have to though it away after
+ * (If the reply will be uncachable we have to throw it away after
* serving this request, so it is better to forward ranges to
* the server and fetch only the requested content)
*/
if (strLen(request->urlpath))
assert(strstr(url, strBuf(request->urlpath)));
}
+ if (flags.only_if_cached)
+ EBIT_SET(cc->mask, CC_ONLY_IF_CACHED);
httpHeaderPutCc(hdr_out, cc);
httpHdrCcDestroy(cc);
}
memBufAppend(mb, "\r\n", 2);
return mb->size - offset;
}
-
/* This will be called when connect completes. Write request. */
static void
httpSendRequest(int fd, void *data)
httpState->flags.keepalive = 1;
else if ((double) p->stats.n_keepalives_recv / (double) p->stats.n_keepalives_sent > 0.50)
httpState->flags.keepalive = 1;
+ if (httpState->peer)
+ if (neighborType(httpState->peer, httpState->request) == PEER_SIBLING)
+ httpState->flags.only_if_cached = 1;
memBufDefInit(&mb);
httpBuildRequestPrefix(req,
httpState->orig_request,
debug(11, 6) ("httpSendRequest: FD %d:\n%s\n", fd, mb.buf);
comm_write_mbuf(fd, mb, sendHeaderDone, httpState);
}
-
void
-httpStart(FwdState * fwdState, int fd)
+httpStart(FwdState * fwd)
{
+ int fd = fwd->server_fd;
HttpStateData *httpState = memAllocate(MEM_HTTP_STATE_DATA);
request_t *proxy_req;
- request_t *orig_req = fwdState->request;
+ request_t *orig_req = fwd->request;
debug(11, 3) ("httpStart: \"%s %s\"\n",
RequestMethodStr[orig_req->method],
- storeUrl(fwdState->entry));
- cbdataAdd(httpState, MEM_HTTP_STATE_DATA);
- storeLockObject(fwdState->entry);
- httpState->fwdState = fwdState;
- httpState->entry = fwdState->entry;
+ storeUrl(fwd->entry));
+ cbdataAdd(httpState, memFree, MEM_HTTP_STATE_DATA);
+ storeLockObject(fwd->entry);
+ httpState->fwd = fwd;
+ httpState->entry = fwd->entry;
httpState->fd = fd;
- if (fwdState->servers)
- httpState->peer = fwdState->servers->peer; /* might be NULL */
+ EBIT_SET(httpState->entry->flags, ENTRY_FWD_HDR_WAIT);
+ if (fwd->servers)
+ httpState->peer = fwd->servers->peer; /* might be NULL */
if (httpState->peer) {
proxy_req = requestCreate(orig_req->method,
PROTO_NONE, storeUrl(httpState->entry));
/*
- * $Id: icmp.cc,v 1.68 1998/11/25 09:00:22 wessels Exp $
+ * $Id: icmp.cc,v 1.69 1998/12/05 00:54:29 wessels Exp $
*
* DEBUG: section 37 ICMP Routines
* AUTHOR: Duane Wessels
strcpy(payload + len, url);
len += ulen + 1;
icmpSendEcho(to, S_ICMP_ICP, payload, len);
- memFree(MEM_8K_BUF, payload);
+ memFree(payload, MEM_8K_BUF);
#endif
}
#endif
/*
- * $Id: icp_v2.cc,v 1.55 1998/10/17 04:34:10 rousskov Exp $
+ * $Id: icp_v2.cc,v 1.56 1998/12/05 00:54:29 wessels Exp $
*
* DEBUG: section 12 Internet Cache Protocol
* AUTHOR: Duane Wessels
break;
case ICP_HIT:
+#if ALLOW_SOURCE_PING
case ICP_SECHO:
+#endif
case ICP_DECHO:
case ICP_MISS:
case ICP_DENIED:
/*
- * $Id: icp_v3.cc,v 1.26 1998/09/21 06:52:16 wessels Exp $
+ * $Id: icp_v3.cc,v 1.27 1998/12/05 00:54:30 wessels Exp $
*
* DEBUG: section 12 Internet Cache Protocol
* AUTHOR: Duane Wessels
break;
case ICP_HIT:
+#if ALLOW_SOURCE_PING
case ICP_SECHO:
+#endif
case ICP_DECHO:
case ICP_MISS:
case ICP_DENIED:
/*
- * $Id: ipcache.cc,v 1.209 1998/11/20 06:13:15 wessels Exp $
+ * $Id: ipcache.cc,v 1.210 1998/12/05 00:54:30 wessels Exp $
*
* DEBUG: section 14 IP Cache
* AUTHOR: Harvest Derived
}
safe_free(i->name);
safe_free(i->error_message);
- memFree(MEM_IPCACHE_ENTRY, i);
+ memFree(i, MEM_IPCACHE_ENTRY);
return;
}
}
cbdataUnlock(p->handlerData);
}
- memFree(MEM_IPCACHE_PENDING, p);
+ memFree(p, MEM_IPCACHE_PENDING);
}
i->pending_head = NULL; /* nuke list */
debug(14, 10) ("ipcache_call_pending: Called %d handlers.\n", nhandler);
/* for HIT, PENDING, DISPATCHED we've returned. For MISS we submit */
c = xcalloc(1, sizeof(*c));
c->data = i;
- cbdataAdd(c, MEM_NONE);
+ cbdataAdd(c, cbdataXfree, 0);
i->status = IP_DISPATCHED;
ipcacheLockEntry(i);
dnsSubmit(i->name, ipcacheHandleReply, c);
ip_pending *p;
while ((p = i->pending_head)) {
i->pending_head = p->next;
- memFree(MEM_IPCACHE_PENDING, p);
+ memFree(p, MEM_IPCACHE_PENDING);
}
safe_free(i->addrs.in_addrs);
safe_free(i->addrs.bad_mask);
safe_free(i->name);
safe_free(i->error_message);
- memFree(MEM_IPCACHE_ENTRY, i);
+ memFree(i, MEM_IPCACHE_ENTRY);
}
void
/*
- * $Id: mem.cc,v 1.37 1998/12/04 22:20:19 wessels Exp $
+ * $Id: mem.cc,v 1.38 1998/12/05 00:54:31 wessels Exp $
*
* DEBUG: section 13 High Level Memory Pool Management
* AUTHOR: Harvest Derived
return memPoolAlloc(MemPools[type]);
}
-/* find appropriate pool and use it */
+/* give memory back to the pool */
void
-memFree(mem_type type, void *p)
+memFree(void *p, int type)
{
memPoolFree(MemPools[type], p);
}
void
memFree2K(void *p)
{
- memFree(MEM_2K_BUF, p);
+ memFree(p, MEM_2K_BUF);
}
void
memFree4K(void *p)
{
- memFree(MEM_4K_BUF, p);
+ memFree(p, MEM_4K_BUF);
}
void
memFree8K(void *p)
{
- memFree(MEM_8K_BUF, p);
+ memFree(p, MEM_8K_BUF);
}
void
memFreeDISK(void *p)
{
- memFree(MEM_DISK_BUF, p);
+ memFree(p, MEM_DISK_BUF);
}
/*
- * $Id: mime.cc,v 1.83 1998/11/20 23:20:51 wessels Exp $
+ * $Id: mime.cc,v 1.84 1998/12/05 00:54:32 wessels Exp $
*
* DEBUG: section 25 MIME Parsing
* AUTHOR: Harvest Derived
EBIT_SET(e->flags, ENTRY_SPECIAL);
debug(25, 3) ("Loaded icon %s\n", url);
storeUnlockObject(e);
- memFree(MEM_4K_BUF, buf);
+ memFree(buf, MEM_4K_BUF);
}
/*
- * $Id: neighbors.cc,v 1.263 1998/12/02 05:03:30 wessels Exp $
+ * $Id: neighbors.cc,v 1.264 1998/12/05 00:54:33 wessels Exp $
*
* DEBUG: section 15 Neighbor Routines
* AUTHOR: Harvest Derived
}
if (p) {
*P = p->next;
- peerDestroy(p);
+ cbdataUnlock(p);
Config.npeers--;
}
first_ping = Config.peers;
return p;
}
+peer *
+peerFindByNameAndPort(const char *name, unsigned short port)
+{
+ peer *p = NULL;
+ for (p = Config.peers; p; p = p->next) {
+ if (strcasecmp(name, p->host))
+ continue;
+ if (port != p->http_port)
+ continue;
+ break;
+ }
+ return p;
+}
+
int
neighborUp(const peer * p)
{
}
void
-peerDestroy(peer * p)
+peerDestroy(void *data, int unused)
{
+ peer *p = data;
struct _domain_ping *l = NULL;
struct _domain_ping *nl = NULL;
if (p == NULL)
p->digest = NULL;
}
#endif
- cbdataFree(p);
+ xfree(p);
}
void
psstate->request = requestLink(urlParse(METHOD_GET, url));
psstate->entry = fake;
psstate->callback = NULL;
- psstate->fail_callback = NULL;
psstate->callback_data = p;
psstate->ping.start = current_time;
- cbdataAdd(psstate, MEM_NONE);
+ cbdataAdd(psstate, cbdataXfree, 0);
mem = fake->mem_obj;
mem->request = requestLink(psstate->request);
mem->start_ping = current_time;
/*
- * $Id: net_db.cc,v 1.133 1998/11/13 20:50:53 wessels Exp $
+ * $Id: net_db.cc,v 1.134 1998/12/05 00:54:34 wessels Exp $
*
* DEBUG: section 38 Network Measurement Database
* AUTHOR: Duane Wessels
}
hash_remove_link(host_table, (hash_link *) x);
xfree(x->name);
- memFree(MEM_NET_DB_NAME, (void *) x);
+ memFree((void *) x, MEM_NET_DB_NAME);
}
static netdbEntry *
n->n_peers_alloc = 0;
if (n->link_count == 0) {
netdbHashDelete(n->network);
- memFree(MEM_NETDBENTRY, n);
+ memFree(n, MEM_NETDBENTRY);
}
}
}
count++;
}
- memFree(MEM_4K_BUF, buf);
+ memFree(buf, MEM_4K_BUF);
fclose(fp);
getCurrentTime();
debug(38, 1) ("NETDB state reloaded; %d entries, %d msec\n",
{
netdbEntry *n = data;
safe_free(n->peers);
- memFree(MEM_NETDBENTRY, n);
+ memFree(n, MEM_NETDBENTRY);
}
static void
{
net_db_name *x = data;
xfree(x->name);
- memFree(MEM_NET_DB_NAME, x);
+ memFree(x, MEM_NET_DB_NAME);
}
static void
{
netdbExchangeState *ex = data;
debug(38, 3) ("netdbExchangeDone: %s\n", storeUrl(ex->e));
- memFree(MEM_4K_BUF, ex->buf);
+ memFree(ex->buf, MEM_4K_BUF);
requestUnlink(ex->r);
storeUnregister(ex->e, ex);
storeUnlockObject(ex->e);
if (n->next_ping_time > squid_curtime)
return;
h = xstrdup(hostname);
- cbdataAdd(h, MEM_NONE);
+ cbdataAdd(h, cbdataXfree, 0);
cbdataLock(h);
ipcache_nbgethostbyname(hostname, netdbSendPing, h);
#endif
}
assert(0 == i);
storeBufferFlush(s);
- memFree(MEM_4K_BUF, buf);
+ memFree(buf, MEM_4K_BUF);
#else
httpReplyReset(reply);
httpReplySetHeaders(reply, 1.0, HTTP_BAD_REQUEST, "Bad Request",
peer *p = data;
char *uri;
netdbExchangeState *ex = xcalloc(1, sizeof(*ex));
- cbdataAdd(ex, MEM_NONE);
+ cbdataAdd(ex, cbdataXfree, 0);
cbdataLock(p);
ex->p = p;
uri = internalRemoteUri(p->host, p->http_port, "/squid-internal-dynamic/", "netdb");
/*
- * $Id: peer_digest.cc,v 1.62 1998/12/05 00:00:44 wessels Exp $
+ * $Id: peer_digest.cc,v 1.63 1998/12/05 00:54:35 wessels Exp $
*
* DEBUG: section 72 Peer Digest Routines
* AUTHOR: Alex Rousskov
/* cannot check cbdataValid(p) because p may not be locked yet */
pd = memAllocate(MEM_PEER_DIGEST);
- cbdataAdd(pd, MEM_PEER_DIGEST);
+ cbdataAdd(pd, memFree, MEM_PEER_DIGEST);
peerDigestInit(pd, p);
cbdataLock(pd->peer); /* we will use the peer */
/* create fetch state structure */
fetch = memAllocate(MEM_DIGEST_FETCH_STATE);
- cbdataAdd(fetch, MEM_DIGEST_FETCH_STATE);
+ cbdataAdd(fetch, memFree, MEM_DIGEST_FETCH_STATE);
fetch->request = requestLink(req);
fetch->pd = pd;
fetch->offset = 0;
/* XXX: soon we will have variable header size */
fetch->offset += StoreDigestCBlockSize;
/* switch to CD buffer and fetch digest guts */
- memFree(MEM_4K_BUF, buf);
+ memFree(buf, MEM_4K_BUF);
buf = NULL;
assert(pd->cd->mask);
storeClientCopy(fetch->entry,
if (fcb_valid)
peerDigestFetchFinish(fetch, err);
if (buf)
- memFree(MEM_4K_BUF, buf);
+ memFree(buf, MEM_4K_BUF);
}
/*
- * $Id: peer_select.cc,v 1.91 1998/11/25 08:58:11 wessels Exp $
+ * $Id: peer_select.cc,v 1.92 1998/12/05 00:54:35 wessels Exp $
*
* DEBUG: section 44 Peer Selection Algorithm
* AUTHOR: Duane Wessels
"DEFAULT_PARENT",
"SINGLE_PARENT",
"FIRST_UP_PARENT",
- "NO_PARENT_DIRECT",
"FIRST_PARENT_MISS",
"CLOSEST_PARENT_MISS",
"CLOSEST_PARENT",
static char *DirectStr[] =
{
+ "DIRECT_UNKNOWN",
"DIRECT_NO",
"DIRECT_MAYBE",
"DIRECT_YES"
static void peerSelectFoo(ps_state *);
static void peerPingTimeout(void *data);
-static void peerSelectCallbackFail(ps_state * psstate);
+static void peerSelectCallback(ps_state * psstate);
static IRCB peerHandlePingReply;
static void peerSelectStateFree(ps_state * psstate);
static void peerIcpParentMiss(peer *, icp_common_t *, ps_state *);
static void peerHandleHtcpReply(peer *, peer_t, htcpReplyData *, void *);
#endif
static int peerCheckNetdbDirect(ps_state * psstate);
+static void peerGetSomeNeighbor(ps_state *);
+static void peerGetSomeNeighborReplies(ps_state *);
+static void peerGetSomeDirect(ps_state *);
+static void peerGetSomeParent(ps_state *);
+static void psstateFigureDirect(ps_state *);
+static void peerAddFwdServer(FwdServer **, peer *, hier_code);
static void
peerSelectStateFree(ps_state * psstate)
peerSelectIcpPing(request_t * request, int direct, StoreEntry * entry)
{
int n;
- if (entry == NULL)
- return 0;
- debug(44, 3) ("peerSelectIcpPing: %s\n", storeUrl(entry));
- if (entry->ping_status != PING_NONE)
- return 0;
+ assert(entry);
+ assert(entry->ping_status == PING_NONE);
assert(direct != DIRECT_YES);
+ debug(44, 3) ("peerSelectIcpPing: %s\n", storeUrl(entry));
if (!request->flags.hierarchical && direct != DIRECT_NO)
return 0;
if (EBIT_TEST(entry->flags, KEY_PRIVATE) && !neighbors_do_private_keys)
}
-peer *
-peerGetSomeParent(request_t * request, hier_code * code)
-{
- peer *p;
- debug(44, 3) ("peerGetSomeParent: %s %s\n",
- RequestMethodStr[request->method],
- request->host);
- if ((p = getDefaultParent(request))) {
- *code = DEFAULT_PARENT;
- return p;
- }
- if ((p = getRoundRobinParent(request))) {
- *code = ROUNDROBIN_PARENT;
- return p;
- }
- if ((p = getFirstUpParent(request))) {
- *code = FIRSTUP_PARENT;
- return p;
- }
- if ((p = getAnyParent(request))) {
- *code = ANY_OLD_PARENT;
- return p;
- }
- return NULL;
-}
-
void
peerSelect(request_t * request,
StoreEntry * entry,
PSC * callback,
- PSC * fail_callback,
void *callback_data)
{
ps_state *psstate = xcalloc(1, sizeof(ps_state));
debug(44, 3) ("peerSelect: %s\n", storeUrl(entry));
else
debug(44, 3) ("peerSelect: %s\n", RequestMethodStr[request->method]);
- cbdataAdd(psstate, MEM_NONE);
+ cbdataAdd(psstate, cbdataXfree, 0);
psstate->request = requestLink(request);
psstate->entry = entry;
psstate->callback = callback;
- psstate->fail_callback = fail_callback;
psstate->callback_data = callback_data;
+ psstate->direct = DIRECT_UNKNOWN;
#if USE_CACHE_DIGESTS
request->hier.peer_select_start = current_time;
#endif
}
static void
-peerSelectCallback(ps_state * psstate, peer * p)
+peerSelectCallback(ps_state * psstate)
{
StoreEntry *entry = psstate->entry;
+ FwdServer *fs = psstate->servers;
void *data = psstate->callback_data;
if (entry) {
debug(44, 3) ("peerSelectCallback: %s\n", storeUrl(entry));
eventDelete(peerPingTimeout, psstate);
entry->ping_status = PING_DONE;
}
+ if (fs == NULL) {
+ debug(44, 1) ("Failed to select source for '%s'\n", storeUrl(entry));
+ debug(44, 1) (" always_direct = %d\n", psstate->always_direct);
+ debug(44, 1) (" never_direct = %d\n", psstate->never_direct);
+ debug(44, 1) (" timedout = %d\n", psstate->ping.timedout);
+ }
psstate->ping.stop = current_time;
- if (cbdataValid(data))
- psstate->callback(p, data);
- cbdataUnlock(data);
- peerSelectStateFree(psstate);
-}
-
-static void
-peerSelectCallbackFail(ps_state * psstate)
-{
- request_t *request = psstate->request;
- void *data = psstate->callback_data;
- const char *url = psstate->entry ? storeUrl(psstate->entry) : urlCanonical(request);
- if (psstate->entry)
- psstate->entry->ping_status = PING_DONE;
- debug(44, 1) ("Failed to select source for '%s'\n", url);
- debug(44, 1) (" always_direct = %d\n", psstate->always_direct);
- debug(44, 1) (" never_direct = %d\n", psstate->never_direct);
- debug(44, 1) (" timedout = %d\n", psstate->ping.timedout);
- if (cbdataValid(data))
- psstate->fail_callback(NULL, data);
+ if (cbdataValid(data)) {
+ psstate->servers = NULL;
+ psstate->callback(fs, data);
+ }
cbdataUnlock(data);
peerSelectStateFree(psstate);
}
static void
peerSelectFoo(ps_state * psstate)
{
- peer *p;
- hier_code code;
StoreEntry *entry = psstate->entry;
request_t *request = psstate->request;
- int direct;
debug(44, 3) ("peerSelectFoo: '%s %s'\n",
RequestMethodStr[request->method],
request->host);
+ if (psstate->direct == DIRECT_UNKNOWN) {
+ psstateFigureDirect(psstate);
+ if (psstate->direct == DIRECT_UNKNOWN)
+ return;
+ }
+ if (entry->ping_status == PING_NONE) {
+ peerGetSomeNeighbor(psstate);
+ if (entry->ping_status == PING_WAITING)
+ return;
+ } else if (entry->ping_status == PING_WAITING) {
+ peerGetSomeNeighborReplies(psstate);
+ entry->ping_status = PING_DONE;
+ }
+ if (Config.onoff.prefer_direct)
+ peerGetSomeDirect(psstate);
+ peerGetSomeParent(psstate);
+ if (!Config.onoff.prefer_direct)
+ peerGetSomeDirect(psstate);
+ peerSelectCallback(psstate);
+}
+
+static void
+psstateFigureDirect(ps_state * psstate)
+{
+ request_t *request = psstate->request;
if (psstate->always_direct == 0 && Config.accessList.AlwaysDirect) {
psstate->acl_checklist = aclChecklistCreate(
Config.accessList.AlwaysDirect,
psstate);
return;
} else if (psstate->always_direct > 0) {
- direct = DIRECT_YES;
+ psstate->direct = DIRECT_YES;
} else if (psstate->never_direct == 0 && Config.accessList.NeverDirect) {
psstate->acl_checklist = aclChecklistCreate(
Config.accessList.NeverDirect,
psstate);
return;
} else if (psstate->never_direct > 0) {
- direct = DIRECT_NO;
+ psstate->direct = DIRECT_NO;
} else if (request->flags.loopdetect) {
- direct = DIRECT_YES;
+ psstate->direct = DIRECT_YES;
} else {
- direct = DIRECT_MAYBE;
- }
- debug(44, 3) ("peerSelectFoo: direct = %s\n", DirectStr[direct]);
- if (direct == DIRECT_YES) {
- debug(44, 3) ("peerSelectFoo: DIRECT\n");
- hierarchyNote(&request->hier, DIRECT, &psstate->ping, request->host);
- peerSelectCallback(psstate, NULL);
- return;
+ psstate->direct = DIRECT_MAYBE;
}
- if ((p = getSingleParent(request))) {
- code = SINGLE_PARENT;
- debug(44, 3) ("peerSelectFoo: %s/%s\n", hier_strings[code], p->host);
- hierarchyNote(&request->hier, code, &psstate->ping, p->host);
- peerSelectCallback(psstate, p);
- return;
- }
- if (!request->flags.hierarchical && direct != DIRECT_NO) {
- debug(44, 3) ("peerSelectFoo: DIRECT for non-hierarchical request\n");
- hierarchyNote(&request->hier, DIRECT, &psstate->ping, request->host);
- peerSelectCallback(psstate, NULL);
+ debug(44, 3) ("psstateFigureDirect: direct = %s\n",
+ DirectStr[psstate->direct]);
+}
+
+/*
+ * peerGetSomeNeighbor
+ *
+ * Selects a neighbor (parent or sibling) based on one of the
+ * following methods:
+ * Cache Digests
+ * CARP
+ * Netdb RTT estimates
+ * ICP/HTCP queries
+ */
+static void
+peerGetSomeNeighbor(ps_state * ps)
+{
+ StoreEntry *entry = ps->entry;
+ request_t *request = ps->request;
+ peer *p;
+ hier_code code = HIER_NONE;
+ assert(entry->ping_status == PING_NONE);
+ if (ps->direct == DIRECT_YES) {
+ entry->ping_status = PING_DONE;
return;
}
#if USE_CACHE_DIGESTS
- else if ((p = neighborsDigestSelect(request, entry))) {
- debug(44, 2) ("peerSelect: Using Cache Digest\n");
- request->hier.alg = PEER_SA_DIGEST;
+ if ((p = neighborsDigestSelect(request, entry))) {
code = CACHE_DIGEST_HIT;
- debug(44, 2) ("peerSelect: %s/%s\n", hier_strings[code], p->host);
- hierarchyNote(&request->hier, code, &psstate->ping, p->host);
- peerSelectCallback(psstate, p);
- return;
- }
+ } else
#endif
#if USE_CARP
- else if ((p = carpSelectParent(request))) {
- hierarchyNote(&request->hier, CARP, &psstate->ping, p->host);
- peerSelectCallback(psstate, p);
- return;
- }
+ if ((p = carpSelectParent(request))) {
+ code = CARP;
+ } else
#endif
- else if ((p = netdbClosestParent(request))) {
- request->hier.alg = PEER_SA_NETDB;
+ if ((p = netdbClosestParent(request))) {
code = CLOSEST_PARENT;
- debug(44, 2) ("peerSelect: %s/%s\n", hier_strings[code], p->host);
- hierarchyNote(&request->hier, code, &psstate->ping, p->host);
- peerSelectCallback(psstate, p);
- return;
- } else if (peerSelectIcpPing(request, direct, entry)) {
- assert(entry->ping_status == PING_NONE);
- request->hier.alg = PEER_SA_ICP;
+ } else if (peerSelectIcpPing(request, ps->direct, entry)) {
debug(44, 3) ("peerSelect: Doing ICP pings\n");
- psstate->ping.start = current_time;
- psstate->ping.n_sent = neighborsUdpPing(request,
+ ps->ping.start = current_time;
+ ps->ping.n_sent = neighborsUdpPing(request,
entry,
peerHandlePingReply,
- psstate,
- &psstate->ping.n_replies_expected,
- &psstate->ping.timeout);
- if (psstate->ping.n_sent == 0)
+ ps,
+ &ps->ping.n_replies_expected,
+ &ps->ping.timeout);
+ if (ps->ping.n_sent == 0)
debug(44, 0) ("WARNING: neighborsUdpPing returned 0\n");
- debug(44, 3) ("peerSelectFoo: %d ICP replies expected, RTT %d msec\n",
- psstate->ping.n_replies_expected, psstate->ping.timeout);
- if (psstate->ping.n_replies_expected > 0) {
+ debug(44, 3) ("peerSelect: %d ICP replies expected, RTT %d msec\n",
+ ps->ping.n_replies_expected, ps->ping.timeout);
+ if (ps->ping.n_replies_expected > 0) {
entry->ping_status = PING_WAITING;
eventAdd("peerPingTimeout",
peerPingTimeout,
- psstate,
- 0.001 * psstate->ping.timeout,
+ ps,
+ 0.001 * ps->ping.timeout,
0);
return;
}
}
- debug(44, 3) ("peerSelectFoo: After peerSelectIcpPing.\n");
- if (peerCheckNetdbDirect(psstate)) {
+ if (code != HIER_NONE) {
+ assert(p);
+ debug(44, 3) ("peerSelect: %s/%s\n", hier_strings[code], p->host);
+ peerAddFwdServer(&ps->servers, p, code);
+ }
+ entry->ping_status = PING_DONE;
+}
+
+/*
+ * peerGetSomeNeighborReplies
+ *
+ * Selects a neighbor (parent or sibling) based on ICP/HTCP replies.
+ */
+static void
+peerGetSomeNeighborReplies(ps_state * ps)
+{
+ StoreEntry *entry = ps->entry;
+ request_t *request = ps->request;
+ peer *p = NULL;
+ hier_code code = HIER_NONE;
+ assert(entry->ping_status == PING_WAITING);
+ assert(ps->direct != DIRECT_YES);
+ if (peerCheckNetdbDirect(ps)) {
code = CLOSEST_DIRECT;
debug(44, 3) ("peerSelect: %s/%s\n", hier_strings[code], request->host);
- hierarchyNote(&request->hier, code, &psstate->ping, request->host);
- peerSelectCallback(psstate, NULL);
- } else if ((p = whichPeer(&psstate->closest_parent_miss))) {
+ peerAddFwdServer(&ps->servers, NULL, code);
+ return;
+ }
+ if ((p = ps->hit)) {
+ code = ps->hit_type == PEER_PARENT ? PARENT_HIT : SIBLING_HIT;
+ } else
+#if ALLOW_SOURCE_PING
+ if ((p = ps->secho)) {
+ code = SOURCE_FASTEST;
+ } else
+#endif
+ if (ps->closest_parent_miss.sin_addr.s_addr != any_addr.s_addr) {
+ p = whichPeer(&ps->closest_parent_miss);
code = CLOSEST_PARENT_MISS;
- debug(44, 3) ("peerSelect: %s/%s\n", hier_strings[code], p->host);
- hierarchyNote(&request->hier, code, &psstate->ping, p->host);
- peerSelectCallback(psstate, p);
- } else if ((p = whichPeer(&psstate->first_parent_miss))) {
+ } else if (ps->first_parent_miss.sin_addr.s_addr != any_addr.s_addr) {
+ p = whichPeer(&ps->first_parent_miss);
code = FIRST_PARENT_MISS;
+ }
+ if (p && code != HIER_NONE) {
debug(44, 3) ("peerSelect: %s/%s\n", hier_strings[code], p->host);
- hierarchyNote(&request->hier, code, &psstate->ping, p->host);
- peerSelectCallback(psstate, p);
- } else if (Config.onoff.prefer_direct && direct != DIRECT_NO) {
- code = DIRECT;
- debug(44, 3) ("peerSelect: %s/%s\n", hier_strings[code], request->host);
- hierarchyNote(&request->hier, code, &psstate->ping, request->host);
- peerSelectCallback(psstate, NULL);
- } else if ((p = peerGetSomeParent(request, &code))) {
+ peerAddFwdServer(&ps->servers, p, code);
+ }
+}
+
+
+/*
+ * peerGetSomeDirect
+ *
+ * Simply adds a 'direct' entry to the FwdServers list if this
+ * request can be forwarded directly to the origin server
+ */
+static void
+peerGetSomeDirect(ps_state * ps)
+{
+ if (ps->direct == DIRECT_NO)
+ return;
+ if (ps->request->protocol == PROTO_WAIS)
+ /* Its not really DIRECT, now is it? */
+ peerAddFwdServer(&ps->servers, Config.Wais.peer, DIRECT);
+ else
+ peerAddFwdServer(&ps->servers, NULL, DIRECT);
+}
+
+static void
+peerGetSomeParent(ps_state * ps)
+{
+ peer *p;
+ request_t *request = ps->request;
+ hier_code code = HIER_NONE;
+ debug(44, 3) ("peerGetSomeParent: %s %s\n",
+ RequestMethodStr[request->method],
+ request->host);
+ if ((p = getDefaultParent(request))) {
+ code = DEFAULT_PARENT;
+ } else if ((p = getRoundRobinParent(request))) {
+ code = ROUNDROBIN_PARENT;
+ } else if ((p = getFirstUpParent(request))) {
+ code = FIRSTUP_PARENT;
+ } else if ((p = getAnyParent(request))) {
+ code = ANY_OLD_PARENT;
+ }
+ if (code != HIER_NONE) {
debug(44, 3) ("peerSelect: %s/%s\n", hier_strings[code], p->host);
- hierarchyNote(&request->hier, code, &psstate->ping, p->host);
- peerSelectCallback(psstate, p);
- } else if (direct != DIRECT_NO) {
- code = DIRECT;
- debug(44, 3) ("peerSelect: %s/%s\n", hier_strings[code], request->host);
- hierarchyNote(&request->hier, code, &psstate->ping, request->host);
- peerSelectCallback(psstate, NULL);
- } else {
- code = NO_DIRECT_FAIL;
- hierarchyNote(&request->hier, code, &psstate->ping, NULL);
- peerSelectCallbackFail(psstate);
+ peerAddFwdServer(&ps->servers, p, code);
}
}
{
ps_state *psstate = data;
icp_opcode op = header->opcode;
- request_t *request = psstate->request;
debug(44, 3) ("peerHandleIcpReply: %s %s\n",
icp_opcode_str[op],
storeUrl(psstate->entry));
if (type == PEER_PARENT)
peerIcpParentMiss(p, header, psstate);
} else if (op == ICP_HIT) {
- hierarchyNote(&request->hier,
- type == PEER_PARENT ? PARENT_HIT : SIBLING_HIT,
- &psstate->ping,
- p->host);
- peerSelectCallback(psstate, p);
+ psstate->hit = p;
+ psstate->hit_type = type;
+ peerSelectFoo(psstate);
return;
- } else if (op == ICP_SECHO) {
- hierarchyNote(&request->hier,
- SOURCE_FASTEST,
- &psstate->ping,
- request->host);
- peerSelectCallback(psstate, NULL);
+ }
+#if ALLOW_SOURCE_PING
+ else if (op == ICP_SECHO) {
+ psstate->secho = p;
+ peerSelectFoo(psstate);
return;
}
+#endif
if (psstate->ping.n_recv < psstate->ping.n_replies_expected)
return;
peerSelectFoo(psstate);
storeUrl(psstate->entry));
psstate->ping.n_recv++;
if (htcp->hit) {
- hierarchyNote(&request->hier,
- type == PEER_PARENT ? PARENT_HIT : SIBLING_HIT,
- &psstate->ping,
- p->host);
- peerSelectCallback(psstate, p);
+ psstate->hit = p;
+ psstate->hit_type = type;
+ peerSelectFoo(psstate);
return;
}
if (type == PEER_PARENT)
else
debug(44, 1) ("peerHandlePingReply: unknown protocol_t %d\n", (int) proto);
}
+
+static void
+peerAddFwdServer(FwdServer ** FS, peer * p, hier_code code)
+{
+ FwdServer *fs = memAllocate(MEM_FWD_SERVER);
+ debug(44, 5) ("peerAddFwdServer: adding %s %s\n",
+ p ? p->host : "DIRECT",
+ hier_strings[code]);
+ fs->peer = p;
+ fs->code = code;
+ cbdataLock(fs->peer);
+ while (*FS)
+ FS = &(*FS)->next;
+ *FS = fs;
+}
/*
- * $Id: protos.h,v 1.293 1998/12/02 05:03:29 wessels Exp $
+ * $Id: protos.h,v 1.294 1998/12/05 00:54:36 wessels Exp $
*
*
* SQUID Internet Object Cache http://squid.nlanr.net/Squid/
extern void cbdataInit(void);
#if CBDATA_DEBUG
-extern void cbdataAddDbg(const void *p, mem_type, const char *, int);
+extern void cbdataAddDbg(const void *p, CBDUNL *, int, const char *, int);
#else
-extern void cbdataAdd(const void *p, mem_type);
+extern void cbdataAdd(const void *p, CBDUNL *, int);
#endif
extern void cbdataFree(void *p);
extern void cbdataLock(const void *p);
extern void cbdataUnlock(const void *p);
extern int cbdataValid(const void *p);
-extern void cbdataDump(StoreEntry *);
+extern CBDUNL cbdataXfree;
extern void clientdbInit(void);
extern void clientdbUpdate(struct in_addr, log_type, protocol_t, size_t);
extern void fqdncache_restart(void);
extern EVH fqdncache_purgelru;
-extern void ftpStart(request_t * req, StoreEntry * entry, int);
+extern void ftpStart(FwdState *);
extern char *ftpUrlWith2f(const request_t *);
-extern void gopherStart(StoreEntry *, int fd);
+extern void gopherStart(FwdState *);
extern int gopherCachable(const char *);
-extern void whoisStart(FwdState *, int fd);
+extern void whoisStart(FwdState *);
extern int httpCachable(method_t);
-extern void httpStart(FwdState *, int fd);
+extern void httpStart(FwdState *);
extern void httpParseReplyHeaders(const char *, http_reply *);
extern void httpProcessReplyHeader(HttpStateData *, const char *, int);
extern size_t httpBuildRequestPrefix(request_t * request,
extern void neighborAdd(const char *, const char *, int, int, int, int, int);
extern void neighbors_open(int);
extern peer *peerFindByName(const char *);
+extern peer *peerFindByNameAndPort(const char *, unsigned short);
extern peer *getDefaultParent(request_t * request);
extern peer *getRoundRobinParent(request_t * request);
extern peer *getAnyParent(request_t * request);
extern void peerNoteDigestLookup(request_t * request, peer * p, lookup_t lookup);
extern void peerNoteDigestGone(peer * p);
extern int neighborUp(const peer * e);
-extern void peerDestroy(peer * e);
+extern CBDUNL peerDestroy;
extern char *neighborTypeStr(const peer * e);
extern peer_t neighborType(const peer *, const request_t *);
extern void peerCheckConnectStart(peer *);
extern void cachemgrRegister(const char *, const char *, OBJH *, int, int);
extern void cachemgrInit(void);
-extern void peerSelect(request_t *, StoreEntry *, PSC *, PSC *, void *data);
-extern peer *peerGetSomeParent(request_t *, hier_code *);
+extern void peerSelect(request_t *, StoreEntry *, PSC *, void *data);
extern void peerSelectInit(void);
/* peer_digest.c */
extern void fwdFail(FwdState *, int, http_status, int);
extern STABH fwdAbort;
extern void fwdUnregister(int fd, FwdState *);
+extern void fwdComplete(FwdState * fwdState);
+
extern void urnStart(request_t *, StoreEntry *);
extern void start_announce(void *unused);
extern void sslStart(int fd, const char *, request_t *, size_t * sz);
-extern void waisStart(request_t *, StoreEntry *, int fd);
-extern void passStart(int, const char *, request_t *, size_t *);
+extern void waisStart(FwdState *);
extern void identStart(int, ConnStateData *, IDCB * callback, void *);
extern void statInit(void);
extern void memConfigure();
extern void *memAllocate(mem_type);
extern void *memAllocBuf(size_t net_size, size_t * gross_size);
-extern void memFree(mem_type, void *);
+extern CBDUNL memFree;
extern void memFreeBuf(size_t size, void *);
extern void memFree2K(void *);
extern void memFree4K(void *);
extern StoreEntry *storeCreateEntry(const char *, const char *, request_flags, method_t);
extern void storeSetPublicKey(StoreEntry *);
extern void storeComplete(StoreEntry *);
-#ifdef PPNR_WIP
-extern void storePPNR(StoreEntry *);
-#endif /* PPNR_WIP */
extern void storeInit(void);
extern int storeClientWaiting(const StoreEntry *);
extern void storeAbort(StoreEntry *, int);
extern int contentLen(const StoreEntry * e);
extern HttpReply *storeEntryReply(StoreEntry *);
extern int storeTooManyDiskFilesOpen(void);
+extern void storeEntryReset(StoreEntry *);
/*
* store_log.c
/*
- * $Id: redirect.cc,v 1.76 1998/11/12 06:28:22 wessels Exp $
+ * $Id: redirect.cc,v 1.77 1998/12/05 00:54:38 wessels Exp $
*
* DEBUG: section 29 Redirector
* AUTHOR: Duane Wessels
return;
}
r = xcalloc(1, sizeof(redirectStateData));
- cbdataAdd(r, MEM_NONE);
+ cbdataAdd(r, cbdataXfree, 0);
r->orig_url = xstrdup(http->uri);
r->client_addr = conn->log_addr;
if (conn->ident.ident == NULL || *conn->ident.ident == '\0') {
/*
- * $Id: send-announce.cc,v 1.54 1998/08/05 16:42:25 wessels Exp $
+ * $Id: send-announce.cc,v 1.55 1998/12/05 00:54:38 wessels Exp $
*
* DEBUG: section 27 Cache Announcer
* AUTHOR: Duane Wessels
return;
if (theOutIcpConnection < 0)
return;
- cbdataAdd(junk = xmalloc(1), MEM_NONE);
+ cbdataAdd(junk = xmalloc(1), cbdataXfree, 0);
ipcache_nbgethostbyname(Config.Announce.host, send_announce, junk);
eventAdd("send_announce", start_announce, NULL, (double) Config.Announce.period, 1);
}
-
-
/*
- * $Id: squid.h,v 1.179 1998/11/12 23:07:38 wessels Exp $
+ * $Id: squid.h,v 1.180 1998/12/05 00:54:39 wessels Exp $
*
* AUTHOR: Duane Wessels
*
/*
- * $Id: ssl.cc,v 1.90 1998/09/14 22:40:11 wessels Exp $
+ * $Id: ssl.cc,v 1.91 1998/12/05 00:54:40 wessels Exp $
*
* DEBUG: section 26 Secure Sockets Layer Proxy
* AUTHOR: Duane Wessels
static PF sslWriteClient;
static PF sslWriteServer;
static PSC sslPeerSelectComplete;
-static PSC sslPeerSelectFail;
static void sslStateFree(SslStateData * sslState);
static void sslConnected(int fd, void *);
static void sslProxyConnected(int fd, void *);
return;
}
sslState = xcalloc(1, sizeof(SslStateData));
- cbdataAdd(sslState, MEM_NONE);
+ cbdataAdd(sslState, cbdataXfree, 0);
sslState->url = xstrdup(url);
sslState->request = requestLink(request);
sslState->size_ptr = size_ptr;
peerSelect(request,
NULL,
sslPeerSelectComplete,
- sslPeerSelectFail,
sslState);
/*
* Disable the client read handler until peer selection is complete
}
static void
-sslPeerSelectComplete(peer * p, void *data)
+sslPeerSelectComplete(FwdServer * fs, void *data)
{
SslStateData *sslState = data;
request_t *request = sslState->request;
peer *g = NULL;
- sslState->proxying = p ? 1 : 0;
- sslState->host = p ? p->host : request->host;
- if (p == NULL) {
+
+ if (fs == NULL) {
+ ErrorState *err;
+ err = errorCon(ERR_CANNOT_FORWARD, HTTP_SERVICE_UNAVAILABLE);
+ err->request = requestLink(sslState->request);
+ err->callback = sslErrorComplete;
+ err->callback_data = sslState;
+ errorSend(sslState->client.fd, err);
+ return;
+ }
+ sslState->proxying = fs->peer ? 1 : 0;
+ sslState->host = fs->peer ? fs->peer->host : request->host;
+ if (fs->peer == NULL) {
sslState->port = request->port;
- } else if (p->http_port != 0) {
- sslState->port = p->http_port;
- } else if ((g = peerFindByName(p->host))) {
+ } else if (fs->peer->http_port != 0) {
+ sslState->port = fs->peer->http_port;
+ } else if ((g = peerFindByName(fs->peer->host))) {
sslState->port = g->http_port;
} else {
sslState->port = CACHE_HTTP_PORT;
sslConnectDone,
sslState);
}
-
-static void
-sslPeerSelectFail(peer * peernotused, void *data)
-{
- SslStateData *sslState = data;
- ErrorState *err;
- err = errorCon(ERR_CANNOT_FORWARD, HTTP_SERVICE_UNAVAILABLE);
- err->request = requestLink(sslState->request);
- err->callback = sslErrorComplete;
- err->callback_data = sslState;
- errorSend(sslState->client.fd, err);
-
-}
/*
- * $Id: stat.cc,v 1.300 1998/11/18 00:16:40 glenn Exp $
+ * $Id: stat.cc,v 1.301 1998/12/05 00:54:41 wessels Exp $
*
* DEBUG: section 18 Cache Manager Statistics
* AUTHOR: Harvest Derived
state->sentry = sentry;
state->filter = filter;
storeLockObject(sentry);
- cbdataAdd(state, MEM_NONE);
+ cbdataAdd(state, cbdataXfree, 0);
eventAdd("statObjects", statObjects, state, 0.0, 1);
}
/*
- * $Id: stmem.cc,v 1.63 1998/07/22 20:37:54 wessels Exp $
+ * $Id: stmem.cc,v 1.64 1998/12/05 00:54:42 wessels Exp $
*
* DEBUG: section 19 Store Memory Primitives
* AUTHOR: Harvest Derived
mem_node *p;
while ((p = mem->head)) {
mem->head = p->next;
- memFree(MEM_STMEM_BUF, p->data);
+ memFree(p->data, MEM_STMEM_BUF);
store_mem_size -= SM_PAGE_SIZE;
safe_free(p);
}
lastp = p;
p = p->next;
current_offset += lastp->len;
- memFree(MEM_STMEM_BUF, lastp->data);
+ memFree(lastp->data, MEM_STMEM_BUF);
store_mem_size -= SM_PAGE_SIZE;
safe_free(lastp);
}
/*
- * $Id: store.cc,v 1.474 1998/12/04 22:20:24 wessels Exp $
+ * $Id: store.cc,v 1.475 1998/12/05 00:54:43 wessels Exp $
*
* DEBUG: section 20 Storage Manager
* AUTHOR: Harvest Derived
ctx_exit(ctx); /* must exit before we free mem->url */
safe_free(mem->url);
safe_free(mem->log_url);
- memFree(MEM_MEMOBJECT, mem);
+ memFree(mem, MEM_MEMOBJECT);
}
static void
destroy_MemObject(e);
storeHashDelete(e);
assert(e->key == NULL);
- memFree(MEM_STOREENTRY, e);
+ memFree(e, MEM_STOREENTRY);
}
/* ----- INTERFACE BETWEEN STORAGE MANAGER AND HASH TABLE FUNCTIONS --------- */
e->timestamp = 0; /* set in storeTimestampsSet() */
e->ping_status = PING_NONE;
EBIT_SET(e->flags, ENTRY_VALIDATED);
-#ifdef PPNR_WIP
- EBIT_SET(e->flags, ENTRY_FWD_HDR_WAIT);
-#endif /* PPNR_WIP */
return e;
}
storeCheckSwapOut(e);
}
-#ifdef PPNR_WIP
-void
-storePPNR(StoreEntry * e)
-{
- assert(EBIT_TEST(e->flags, ENTRY_FWD_HDR_WAIT));
- EBIT_CLR(e->flags, ENTRY_FWD_HDR_WAIT);
-}
-
-#endif /* PPNR_WIP */
-
/*
* Someone wants to abort this transfer. Set the reason in the
* request structure, call the server-side callback and mark the
return NULL;
return e->mem_obj->reply;
}
+
+void
+storeEntryReset(StoreEntry * e)
+{
+ MemObject *mem = e->mem_obj;
+ debug(20, 3) ("storeEntryReset: %s\n", storeUrl(e));
+ assert(mem->swapout.fd == -1);
+ stmemFree(&mem->data_hdr);
+ mem->inmem_hi = mem->inmem_lo = 0;
+ httpReplyDestroy(mem->reply);
+ mem->reply = httpReplyCreate();
+}
/*
- * $Id: store_client.cc,v 1.48 1998/10/13 20:38:42 wessels Exp $
+ * $Id: store_client.cc,v 1.49 1998/12/05 00:54:44 wessels Exp $
*
* DEBUG: section 20 Storage Manager Client-Side Interface
* AUTHOR: Duane Wessels
return;
mem->nclients++;
sc = memAllocate(MEM_STORE_CLIENT);
- cbdataAdd(sc, MEM_STORE_CLIENT); /* sc is callback_data for file_read */
+ cbdataAdd(sc, memFree, MEM_STORE_CLIENT); /* sc is callback_data for file_read */
sc->callback_data = data;
sc->seen_offset = 0;
sc->copy_offset = 0;
size_t sz;
if (sc->flags.copy_event_pending)
return;
-#ifdef PPNR_WIP
- if (EBIT_TEST(e->flags, ENTRY_FWD_HDR_WAIT))
+ if (EBIT_TEST(e->flags, ENTRY_FWD_HDR_WAIT)) {
+ debug(20, 5) ("storeClientCopy2: returning because ENTRY_FWD_HDR_WAIT set\n");
return;
-#endif /* PPNR_WIP */
+ }
if (sc->flags.store_copying) {
sc->flags.copy_event_pending = 1;
debug(20, 3) ("storeClientCopy2: Queueing storeClientCopyEvent()\n");
/*
- * $Id: store_digest.cc,v 1.33 1998/11/25 09:00:26 wessels Exp $
+ * $Id: store_digest.cc,v 1.34 1998/12/05 00:54:44 wessels Exp $
*
* DEBUG: section 71 Store Digest Manager
* AUTHOR: Alex Rousskov
flags.cachable = 1;
sd_state.rewrite_lock = e = storeCreateEntry(url, url, flags, METHOD_GET);
assert(sd_state.rewrite_lock);
- cbdataAdd(sd_state.rewrite_lock, MEM_DONTFREE);
+ cbdataAdd(sd_state.rewrite_lock, NULL, 0);
debug(71, 3) ("storeDigestRewrite: url: %s key: %s\n", url, storeKeyText(e->key));
e->mem_obj->request = requestLink(urlParse(METHOD_GET, url));
/* wait for rebuild (if any) to finish */
/*
- * $Id: store_key_md5.cc,v 1.18 1998/11/13 20:50:58 wessels Exp $
+ * $Id: store_key_md5.cc,v 1.19 1998/12/05 00:54:45 wessels Exp $
*
* DEBUG: section 20 Storage Manager MD5 Cache Keys
* AUTHOR: Duane Wessels
void
storeKeyFree(const cache_key * key)
{
- memFree(MEM_MD5_DIGEST, (void *) key);
+ memFree((void *) key, MEM_MD5_DIGEST);
}
int
/*
- * $Id: store_swapout.cc,v 1.37 1998/11/25 08:57:53 wessels Exp $
+ * $Id: store_swapout.cc,v 1.38 1998/12/05 00:54:45 wessels Exp $
*
* DEBUG: section 20 Storage Manager Swapout Functions
* AUTHOR: Duane Wessels
{
swapout_ctrl_t *ctrlp = xmalloc(sizeof(swapout_ctrl_t));
assert(e->mem_obj);
- cbdataAdd(ctrlp, MEM_NONE);
+ cbdataAdd(ctrlp, cbdataXfree, 0);
storeLockObject(e);
e->swap_file_number = storeDirMapAllocate();
ctrlp->swapfilename = xstrdup(storeSwapFullPath(e->swap_file_number, NULL));
storeDirMapBitReset(e->swap_file_number);
e->swap_file_number = -1;
e->swap_status = SWAPOUT_NONE;
- memFree(MEM_DISK_BUF, swap_buf);
+ memFree(swap_buf, MEM_DISK_BUF);
storeReleaseRequest(e);
storeSwapOutFileClose(e);
return;
+
/*
- * $Id: structs.h,v 1.250 1998/11/21 16:54:29 wessels Exp $
+ * $Id: structs.h,v 1.251 1998/12/05 00:54:46 wessels Exp $
*
*
* SQUID Internet Object Cache http://squid.nlanr.net/Squid/
struct {
char *relayHost;
u_short relayPort;
+ peer *peer;
} Wais;
struct {
size_t min;
struct _http_state_flags {
unsigned int proxying:1;
unsigned int keepalive:1;
+ unsigned int only_if_cached:1;
};
struct _HttpStateData {
request_t *orig_request;
int fd;
http_state_flags flags;
- FwdState *fwdState;
+ FwdState *fwd;
};
struct _icpUdpData {
StoreEntry *entry;
int always_direct;
int never_direct;
+ int direct;
PSC *callback;
- PSC *fail_callback;
void *callback_data;
+ FwdServer *servers;
/*
* Why are these struct sockaddr_in instead of peer *? Because a
* peer structure can become invalid during the peer selection
*/
struct sockaddr_in first_parent_miss;
struct sockaddr_in closest_parent_miss;
+ /*
+ * ->hit and ->secho can be peer* because they should only be
+ * accessed during the thread when they are set
+ */
+ peer *hit;
+ peer_t hit_type;
+#if ALLOW_SOURCE_PING
+ peer *secho;
+#endif
ping_data ping;
aclCheck_t *acl_checklist;
};
int del_count; /* number of deletions performed so far */
};
+struct _FwdServer {
+ peer *peer; /* NULL --> origin server */
+ hier_code code;
+ FwdServer *next;
+};
+
struct _FwdState {
int client_fd;
StoreEntry *entry;
int n_tries;
};
-struct _FwdServer {
- char *host;
- u_short port;
- peer *peer;
- struct _FwdServer *next;
-};
-
#if USE_HTCP
struct _htcpReplyData {
int hit;
/*
- * $Id: tunnel.cc,v 1.90 1998/09/14 22:40:11 wessels Exp $
+ * $Id: tunnel.cc,v 1.91 1998/12/05 00:54:40 wessels Exp $
*
* DEBUG: section 26 Secure Sockets Layer Proxy
* AUTHOR: Duane Wessels
static PF sslWriteClient;
static PF sslWriteServer;
static PSC sslPeerSelectComplete;
-static PSC sslPeerSelectFail;
static void sslStateFree(SslStateData * sslState);
static void sslConnected(int fd, void *);
static void sslProxyConnected(int fd, void *);
return;
}
sslState = xcalloc(1, sizeof(SslStateData));
- cbdataAdd(sslState, MEM_NONE);
+ cbdataAdd(sslState, cbdataXfree, 0);
sslState->url = xstrdup(url);
sslState->request = requestLink(request);
sslState->size_ptr = size_ptr;
peerSelect(request,
NULL,
sslPeerSelectComplete,
- sslPeerSelectFail,
sslState);
/*
* Disable the client read handler until peer selection is complete
}
static void
-sslPeerSelectComplete(peer * p, void *data)
+sslPeerSelectComplete(FwdServer * fs, void *data)
{
SslStateData *sslState = data;
request_t *request = sslState->request;
peer *g = NULL;
- sslState->proxying = p ? 1 : 0;
- sslState->host = p ? p->host : request->host;
- if (p == NULL) {
+
+ if (fs == NULL) {
+ ErrorState *err;
+ err = errorCon(ERR_CANNOT_FORWARD, HTTP_SERVICE_UNAVAILABLE);
+ err->request = requestLink(sslState->request);
+ err->callback = sslErrorComplete;
+ err->callback_data = sslState;
+ errorSend(sslState->client.fd, err);
+ return;
+ }
+ sslState->proxying = fs->peer ? 1 : 0;
+ sslState->host = fs->peer ? fs->peer->host : request->host;
+ if (fs->peer == NULL) {
sslState->port = request->port;
- } else if (p->http_port != 0) {
- sslState->port = p->http_port;
- } else if ((g = peerFindByName(p->host))) {
+ } else if (fs->peer->http_port != 0) {
+ sslState->port = fs->peer->http_port;
+ } else if ((g = peerFindByName(fs->peer->host))) {
sslState->port = g->http_port;
} else {
sslState->port = CACHE_HTTP_PORT;
sslConnectDone,
sslState);
}
-
-static void
-sslPeerSelectFail(peer * peernotused, void *data)
-{
- SslStateData *sslState = data;
- ErrorState *err;
- err = errorCon(ERR_CANNOT_FORWARD, HTTP_SERVICE_UNAVAILABLE);
- err->request = requestLink(sslState->request);
- err->callback = sslErrorComplete;
- err->callback_data = sslState;
- errorSend(sslState->client.fd, err);
-
-}
/*
- * $Id: typedefs.h,v 1.82 1998/11/12 06:28:30 wessels Exp $
+ * $Id: typedefs.h,v 1.83 1998/12/05 00:54:47 wessels Exp $
*
*
* SQUID Internet Object Cache http://squid.nlanr.net/Squid/
typedef void CNCB(int fd, int status, void *);
typedef void FREE(void *);
+typedef void CBDUNL(void *, int);
typedef void FOCB(void *, int fd, int errcode);
typedef void EVH(void *);
typedef void PF(int, void *);
typedef void IDCB(void *);
typedef void IPH(const ipcache_addrs *, void *);
typedef void IRCB(peer *, peer_t, protocol_t, void *, void *data);
-typedef void PSC(peer *, void *);
+typedef void PSC(FwdServer *, void *);
typedef void RH(void *data, char *);
typedef void UH(void *data, wordlist *);
typedef int DEFER(int fd, void *data);
/*
*
- * $Id: urn.cc,v 1.48 1998/09/29 16:32:50 wessels Exp $
+ * $Id: urn.cc,v 1.49 1998/12/05 00:54:48 wessels Exp $
*
* DEBUG: section 52 URN Parsing
* AUTHOR: Kostas Anagnostakis
urnState = xcalloc(1, sizeof(UrnState));
urnState->entry = e;
urnState->request = requestLink(r);
- cbdataAdd(urnState, MEM_NONE);
+ cbdataAdd(urnState, cbdataXfree, 0);
storeLockObject(urnState->entry);
if (strncasecmp(strBuf(r->urlpath), "menu.", 5) == 0) {
char *new_path = xstrdup(strBuf(r->urlpath) + 5);
debug(52, 3) ("urnHandleReply: Called with size=%d.\n", size);
if (urlres_e->store_status == STORE_ABORTED) {
- memFree(MEM_4K_BUF, buf);
+ memFree(buf, MEM_4K_BUF);
return;
}
if (size == 0) {
- memFree(MEM_4K_BUF, buf);
+ memFree(buf, MEM_4K_BUF);
return;
} else if (size < 0) {
- memFree(MEM_4K_BUF, buf);
+ memFree(buf, MEM_4K_BUF);
return;
}
if (urlres_e->store_status == STORE_PENDING && size < SM_PAGE_SIZE) {
httpBodySet(&rep->body, &mb);
httpReplySwapOut(rep, e);
storeComplete(e);
- memFree(MEM_4K_BUF, buf);
+ memFree(buf, MEM_4K_BUF);
for (i = 0; i < urlcnt; i++) {
safe_free(urls[i].url);
safe_free(urls[i].host);
/*
- * $Id: wais.cc,v 1.123 1998/11/21 16:54:30 wessels Exp $
+ * $Id: wais.cc,v 1.124 1998/12/05 00:54:48 wessels Exp $
*
* DEBUG: section 24 WAIS Relay
* AUTHOR: Harvest Derived
const HttpHeader *request_hdr;
char url[MAX_URL];
request_t *request;
+ FwdState *fwd;
} WaisStateData;
static PF waisStateFree;
} else if (len == 0) {
/* Connection closed; retrieval done. */
entry->expires = squid_curtime;
- storeComplete(entry);
+ fwdComplete(waisState->fwd);
comm_close(fd);
} else {
storeAppend(entry, buf, len);
}
void
-waisStart(request_t * request, StoreEntry * entry, int fd)
+waisStart(FwdState * fwd)
{
WaisStateData *waisState = NULL;
+ request_t *request = fwd->request;
+ StoreEntry *entry = fwd->entry;
+ int fd = fwd->server_fd;
const char *url = storeUrl(entry);
method_t method = request->method;
debug(24, 3) ("waisStart: \"%s %s\"\n", RequestMethodStr[method], url);
Counter.server.all.requests++;
Counter.server.other.requests++;
waisState = xcalloc(1, sizeof(WaisStateData));
- cbdataAdd(waisState, MEM_NONE);
+ cbdataAdd(waisState, cbdataXfree, 0);
waisState->method = method;
waisState->request_hdr = &request->header;
waisState->fd = fd;
waisState->entry = entry;
xstrncpy(waisState->url, url, MAX_URL);
waisState->request = requestLink(request);
+ waisState->fwd = fwd;
comm_add_close_handler(waisState->fd, waisStateFree, waisState);
storeLockObject(entry);
commSetSelect(fd, COMM_SELECT_WRITE, waisSendRequest, waisState, 0);
/*
- * $Id: whois.cc,v 1.6 1998/09/04 23:05:07 wessels Exp $
+ * $Id: whois.cc,v 1.7 1998/12/05 00:54:49 wessels Exp $
*
* DEBUG: section 75 WHOIS protocol
* AUTHOR: Duane Wessels, Kostas Anagnostakis
typedef struct {
StoreEntry *entry;
request_t *request;
- FwdState *fwdState;
+ FwdState *fwd;
} WhoisState;
static PF whoisClose;
/* PUBLIC */
void
-whoisStart(FwdState * fwdState, int fd)
+whoisStart(FwdState * fwd)
{
WhoisState *p = xcalloc(1, sizeof(*p));
+ int fd = fwd->server_fd;
char *buf;
size_t l;
- p->request = fwdState->request;
- p->entry = fwdState->entry;
- p->fwdState = fwdState;
- cbdataAdd(p, MEM_NONE);
+ p->request = fwd->request;
+ p->entry = fwd->entry;
+ p->fwd = fwd;
+ cbdataAdd(p, cbdataXfree, 0);
storeLockObject(p->entry);
comm_add_close_handler(fd, whoisClose, p);
l = strLen(p->request->urlpath) + 3;
if (ignoreErrno(errno)) {
commSetSelect(fd, COMM_SELECT_READ, whoisReadReply, p, Config.Timeout.read);
} else if (entry->mem_obj->inmem_hi == 0) {
- fwdFail(p->fwdState, ERR_READ_ERROR, HTTP_INTERNAL_SERVER_ERROR, errno);
+ fwdFail(p->fwd, ERR_READ_ERROR, HTTP_INTERNAL_SERVER_ERROR, errno);
comm_close(fd);
} else {
storeAbort(entry, 0);
comm_close(fd);
}
} else {
- storeComplete(entry);
+ fwdComplete(p->fwd);
debug(75, 3) ("whoisReadReply: Done: %s\n", storeUrl(entry));
comm_close(fd);
}
- memFree(MEM_4K_BUF, buf);
+ memFree(buf, MEM_4K_BUF);
}
static void