コード例 #1
0
ファイル: store_rebuild.c プロジェクト: KimTaehee/HappyStream
static void
storeCleanup(void *datanotused)
{
    static int bucketnum = -1;
    static int validnum = 0;
    static int store_errors = 0;
    int validnum_start;
    StoreEntry *e;
    hash_link *link_ptr = NULL;
    hash_link *link_next = NULL;
    int limit = opt_foreground_rebuild ? 1 << 30 : 500;
    validnum_start = validnum;

    while (validnum - validnum_start < limit) {
	if (++bucketnum >= store_hash_buckets) {
	    debug(20, 1) ("  Completed Validation Procedure\n");
	    debug(20, 1) ("  Validated %d Entries\n", validnum);
	    debug(20, 1) ("  store_swap_size = %dk\n", store_swap_size);
	    store_dirs_rebuilding--;
	    assert(0 == store_dirs_rebuilding);
	    if (opt_store_doublecheck)
		assert(store_errors == 0);
	    if (store_digest)
		storeDigestNoteStoreReady();
	    return;
	}
	link_next = hash_get_bucket(store_table, bucketnum);
	while (NULL != (link_ptr = link_next)) {
	    link_next = link_ptr->next;
	    e = (StoreEntry *) link_ptr;
	    if (EBIT_TEST(e->flags, ENTRY_VALIDATED))
		continue;
	    /*
	     * Calling storeRelease() has no effect because we're
	     * still in 'store_rebuilding' state
	     */
	    if (e->swap_filen < 0)
		continue;
	    if (opt_store_doublecheck)
		if (storeCleanupDoubleCheck(e))
		    store_errors++;
	    EBIT_SET(e->flags, ENTRY_VALIDATED);
	    /*
	     * Only set the file bit if we know its a valid entry
	     * otherwise, set it in the validation procedure
	     */
	    storeDirUpdateSwapSize(&Config.cacheSwap.swapDirs[e->swap_dirn], e->swap_file_sz, 1);
	    /* Get rid of private objects. Not useful */
	    if (EBIT_TEST(e->flags, KEY_PRIVATE))
		storeRelease(e);
	    if ((++validnum & 0x3FFFF) == 0)
		debug(20, 1) ("  %7d Entries Validated so far.\n", validnum);
	}
    }
    eventAdd("storeCleanup", storeCleanup, NULL, 0.0, 1);
}
コード例 #2
0
ファイル: store_digest.c プロジェクト: KimTaehee/HappyStream
/* should we digest this entry? used by storeDigestAdd() */
static int
storeDigestAddable(const StoreEntry * e)
{
    /* add some stats! XXX */

    debug(71, 6) ("storeDigestAddable: checking entry, key: %s\n",
	storeKeyText(e->hash.key));

    /* check various entry flags (mimics storeCheckCachable XXX) */
    if (!EBIT_TEST(e->flags, ENTRY_CACHABLE)) {
	debug(71, 6) ("storeDigestAddable: NO: not cachable\n");
	return 0;
    }
    if (EBIT_TEST(e->flags, KEY_PRIVATE)) {
	debug(71, 6) ("storeDigestAddable: NO: private key\n");
	return 0;
    }
    if (EBIT_TEST(e->flags, ENTRY_NEGCACHED)) {
	debug(71, 6) ("storeDigestAddable: NO: negative cached\n");
	return 0;
    }
    if (EBIT_TEST(e->flags, RELEASE_REQUEST)) {
	debug(71, 6) ("storeDigestAddable: NO: release requested\n");
	return 0;
    }
    if (e->store_status == STORE_OK && EBIT_TEST(e->flags, ENTRY_BAD_LENGTH)) {
	debug(71, 6) ("storeDigestAddable: NO: wrong content-length\n");
	return 0;
    }
    /* do not digest huge objects */
    if (e->swap_file_sz > Config.Store.maxObjectSize) {
	debug(71, 6) ("storeDigestAddable: NO: too big\n");
	return 0;
    }
    /* still here? check staleness */
    /* Note: We should use the time of the next rebuild, not (cur_time+period) */
    if (refreshCheckDigest(e, Config.digest.rebuild_period)) {
	debug(71, 6) ("storeDigestAddable: entry expires within %d secs, ignoring\n",
	    (int) Config.digest.rebuild_period);
	return 0;
    }
    /*
     * idea: how about also skipping very fresh (thus, potentially
     * unstable) entries? Should be configurable through
     * cd_refresh_pattern, of course.
     */
    /*
     * idea: skip objects that are going to be purged before the next
     * update.
     */
#if OLD_UNUSED_CODE		/* This code isn't applicable anymore, we can't fix it atm either :( */
    if ((squid_curtime + Config.digest.rebuild_period) - e->lastref > storeExpiredReferenceAge())
	return 0;
#endif
    return 1;
}
コード例 #3
0
/* copy bytes requested by the client */
void
storeClientCopy(StoreEntry * e,
    off_t seen_offset,
    off_t copy_offset,
    size_t size,
    char *buf,
    STCB * callback,
    void *data)
{
    store_client *sc;
    assert(!EBIT_TEST(e->flags, ENTRY_ABORTED));
    debug(20, 3) ("storeClientCopy: %s, seen %d, want %d, size %d, cb %p, cbdata %p\n",
	storeKeyText(e->key),
	(int) seen_offset,
	(int) copy_offset,
	(int) size,
	callback,
	data);
    sc = storeClientListSearch(e->mem_obj, data);
    assert(sc != NULL);
    assert(sc->callback == NULL);
    sc->copy_offset = copy_offset;
    sc->seen_offset = seen_offset;
    sc->callback = callback;
    sc->copy_buf = buf;
    sc->copy_size = size;
    sc->copy_offset = copy_offset;
    storeClientCopy2(e, sc);
}
コード例 #4
0
ファイル: store_client.c プロジェクト: carriercomm/myboxfs
/* copy bytes requested by the client */
void
storeClientCopy(store_client * sc,
    StoreEntry * e,
    squid_off_t seen_offset,
    squid_off_t copy_offset,
    size_t size,
    char *buf,
    STCB * callback,
    void *data)
{
    assert(!EBIT_TEST(e->flags, ENTRY_ABORTED));
    debug(20, 3) ("storeClientCopy: %s, seen %" PRINTF_OFF_T ", want %" PRINTF_OFF_T ", size %d, cb %p, cbdata %p\n",
	storeKeyText(e->hash.key),
	seen_offset,
	copy_offset,
	(int) size,
	callback,
	data);
    assert(sc != NULL);
#if STORE_CLIENT_LIST_DEBUG
    assert(sc == storeClientListSearch(e->mem_obj, data));
#endif
    assert(sc->callback == NULL);
    assert(sc->entry == e);
    sc->seen_offset = seen_offset;
    sc->callback = callback;
    sc->copy_buf = buf;
    sc->copy_size = size;
    sc->copy_offset = copy_offset;
    storeClientCopy2(e, sc);
}
コード例 #5
0
ファイル: peer_monitor.c プロジェクト: KimTaehee/HappyStream
static void
peerMonitorFetchReplyHeaders(void *data, char *buf, ssize_t size)
{
    PeerMonitor *pm = data;
    HttpReply *reply;
    http_status status;

    if (EBIT_TEST(pm->running.e->flags, ENTRY_ABORTED))
	goto completed;
    if (size <= 0)
	goto completed;
    if (!cbdataValid(pm->peer))
	goto completed;

    reply = pm->running.e->mem_obj->reply;
    assert(reply);
    status = reply->sline.status;
    pm->running.status = status;
    if (status != HTTP_OK)
	goto completed;
    if (size > reply->hdr_sz) {
	pm->running.size = size - reply->hdr_sz;
	pm->running.offset = size;
    } else {
	pm->running.size = 0;
	pm->running.offset = reply->hdr_sz;
    }
    storeClientCopy(pm->running.sc, pm->running.e, pm->running.offset, pm->running.offset, 4096, buf, peerMonitorFetchReply, pm);
    return;

  completed:
    /* We are fully done with this monitoring request. Clean up */
    peerMonitorCompleted(pm);
    return;
}
コード例 #6
0
ファイル: errormap.c プロジェクト: cristdai/squid2
static void
errorMapFetchHeaders(void *data, mem_node_ref nr, ssize_t size)
{
    ErrorMapState *state = data;
    HttpReply *reply;
    http_status status;

    if (EBIT_TEST(state->e->flags, ENTRY_ABORTED))
	goto abort;
    if (size == 0)
	goto abort;
    if (!cbdataValid(state->callback_data))
	goto abort;

    reply = state->e->mem_obj->reply;

    status = reply->sline.status;
    if (status != HTTP_OK)
	goto abort;
    /* Send object to caller (cbdataValid verified above) */
    state->callback(state->e, reply->hdr_sz, httpHeaderGetSize(&reply->header, HDR_CONTENT_LENGTH), state->callback_data);
    errorMapFetchComplete(state);
    stmemNodeUnref(&nr);
    return;

  abort:
    errorMapFetchAbort(state);
    stmemNodeUnref(&nr);
    return;
}
コード例 #7
0
ファイル: store_swapin.c プロジェクト: UTSASRG/DoubleTake
void
storeSwapInStart(store_client * sc)
{
    StoreEntry *e = sc->entry;
    assert(e->mem_status == NOT_IN_MEMORY);
    if (!EBIT_TEST(e->flags, ENTRY_VALIDATED)) {
	/* We're still reloading and haven't validated this entry yet */
	return;
    }
    debug(20, 3) ("storeSwapInStart: called for %08X %s \n",
	e->swap_file_number, storeKeyText(e->key));
    if (e->swap_status != SWAPOUT_WRITING && e->swap_status != SWAPOUT_DONE) {
	debug(20, 1) ("storeSwapInStart: bad swap_status (%s)\n",
	    swapStatusStr[e->swap_status]);
	return;
    }
    if (e->swap_file_number < 0) {
	debug(20, 1) ("storeSwapInStart: swap_file_number < 0\n");
	return;
    }
    assert(e->mem_obj != NULL);
    debug(20, 3) ("storeSwapInStart: Opening fileno %08X\n",
	e->swap_file_number);
    sc->swapin_sio = storeOpen(e->swap_file_number,
	O_RDONLY,
	storeSwapInFileClosed,
	sc);
    cbdataLock(sc->swapin_sio);
}
コード例 #8
0
static void
storeClientCopy2(StoreEntry * e, store_client * sc)
{
    if (sc->flags.copy_event_pending)
	return;
    if (EBIT_TEST(e->flags, ENTRY_FWD_HDR_WAIT)) {
	debug(20, 5) ("storeClientCopy2: returning because ENTRY_FWD_HDR_WAIT set\n");
	return;
    }
    if (sc->flags.store_copying) {
	sc->flags.copy_event_pending = 1;
	debug(20, 3) ("storeClientCopy2: Queueing storeClientCopyEvent()\n");
	eventAdd("storeClientCopyEvent", storeClientCopyEvent, sc, 0.0, 0);
	return;
    }
    cbdataLock(sc);		/* ick, prevent sc from getting freed */
    sc->flags.store_copying = 1;
    debug(20, 3) ("storeClientCopy2: %s\n", storeKeyText(e->hash.key));
    assert(sc->callback != NULL);
    /*
     * We used to check for ENTRY_ABORTED here.  But there were some
     * problems.  For example, we might have a slow client (or two) and
     * the server-side is reading far ahead and swapping to disk.  Even
     * if the server-side aborts, we want to give the client(s)
     * everything we got before the abort condition occurred.
     */
    storeClientCopy3(e, sc);
    sc->flags.store_copying = 0;
    cbdataUnlock(sc);		/* ick, allow sc to be freed */
}
コード例 #9
0
void
storeLog(int tag, const StoreEntry * e)
{
    MemBuf mb;
    MemObject *mem = e->mem_obj;
    HttpReply *reply;
    if (storelog_fd < 0)
        return;
    if (mem == NULL)
        return;
    if (EBIT_TEST(e->flags, ENTRY_DONT_LOG))
        return;
    if (mem->log_url == NULL) {
        debug(20, 1) ("storeLog: NULL log_url for %s\n", mem->url);
        storeMemObjectDump(mem);
        mem->log_url = xstrdup(mem->url);
    }
    memBufDefInit(&mb);
    reply = mem->reply;
    memBufPrintf(&mb, "%9d.%03d %-7s %08X %4d %9d %9d %9d %s %d/%d %s %s\n",
                 (int) current_time.tv_sec,
                 (int) current_time.tv_usec / 1000,
                 storeLogTags[tag],
                 e->swap_file_number,
                 reply->sline.status,
                 (int) reply->date,
                 (int) reply->last_modified,
                 (int) reply->expires,
                 strLen(reply->content_type) ? strBuf(reply->content_type) : "unknown",
                 reply->content_length,
                 (int) (mem->inmem_hi - mem->reply->hdr_sz),
                 RequestMethodStr[mem->method],
                 mem->log_url);
    file_write_mbuf(storelog_fd, -1, mb, NULL, NULL);
}
コード例 #10
0
/* create MIME Header for Gopher Data */
static void
gopherMimeCreate(GopherStateData * gopherState)
{
    StoreEntry *e = gopherState->entry;
    HttpReply *reply = e->mem_obj->reply;
    http_version_t version;
    const char *mime_type = NULL;
    const char *mime_enc = NULL;

    switch (gopherState->type_id) {
    case GOPHER_DIRECTORY:
    case GOPHER_INDEX:
    case GOPHER_HTML:
    case GOPHER_WWW:
    case GOPHER_CSO:
	mime_type = "text/html";
	break;
    case GOPHER_GIF:
    case GOPHER_IMAGE:
    case GOPHER_PLUS_IMAGE:
	mime_type = "image/gif";
	break;
    case GOPHER_SOUND:
    case GOPHER_PLUS_SOUND:
	mime_type = "audio/basic";
	break;
    case GOPHER_PLUS_MOVIE:
	mime_type = "video/mpeg";
	break;
    case GOPHER_MACBINHEX:
	mime_type = "application/macbinary";
	break;
    case GOPHER_DOSBIN:
    case GOPHER_UUENCODED:
    case GOPHER_BIN:
    case GOPHER_FILE:
    default:
	/* Rightnow We have no idea what it is. */
	mime_type = mimeGetContentType(gopherState->request);
	mime_enc = mimeGetContentEncoding(gopherState->request);
	break;
    }

    storeBuffer(e);
    httpReplyReset(reply);
    EBIT_CLR(gopherState->entry->flags, ENTRY_FWD_HDR_WAIT);
    httpBuildVersion(&version, 1, 0);
    httpReplySetHeaders(reply, version, HTTP_OK, "Gatewaying", mime_type, -1, -1, -1);
    if (mime_enc)
	httpHeaderPutStr(&reply->header, HDR_CONTENT_ENCODING, mime_enc);
    httpReplySwapOut(reply, e);
    reply->hdr_sz = e->mem_obj->inmem_hi;
    storeTimestampsSet(e);
    if (EBIT_TEST(e->flags, ENTRY_CACHABLE)) {
	storeSetPublicKey(e);
    } else {
	storeRelease(e);
    }
}
コード例 #11
0
ファイル: neighbors.c プロジェクト: CoolerVoid/squid
void
neighborsHtcpReply(const cache_key * key, htcpReplyData * htcp, const struct sockaddr_in *from)
{
    StoreEntry *e = storeGet(key);
    MemObject *mem = NULL;
    peer *p;
    peer_t ntype = PEER_NONE;
    debug(15, 6) ("neighborsHtcpReply: %s %s\n",
	htcp->hit ? "HIT" : "MISS", storeKeyText(key));
    if (NULL != (e = storeGet(key)))
	mem = e->mem_obj;
    if ((p = whichPeer(from)))
	neighborAliveHtcp(p, mem, htcp);
    /* Does the entry exist? */
    if (NULL == e) {
	debug(12, 3) ("neighborsHtcpReply: Cache key '%s' not found\n",
	    storeKeyText(key));
	neighborCountIgnored(p);
	return;
    }
    /* check if someone is already fetching it */
    if (EBIT_TEST(e->flags, ENTRY_DISPATCHED)) {
	debug(15, 3) ("neighborsHtcpReply: '%s' already being fetched.\n",
	    storeKeyText(key));
	neighborCountIgnored(p);
	return;
    }
    if (mem == NULL) {
	debug(15, 2) ("Ignoring reply for missing mem_obj: %s\n",
	    storeKeyText(key));
	neighborCountIgnored(p);
	return;
    }
    if (e->ping_status != PING_WAITING) {
	debug(15, 2) ("neighborsHtcpReply: Entry %s is not PING_WAITING\n",
	    storeKeyText(key));
	neighborCountIgnored(p);
	return;
    }
    if (e->lock_count == 0) {
	debug(12, 1) ("neighborsHtcpReply: '%s' has no locks\n",
	    storeKeyText(key));
	neighborCountIgnored(p);
	return;
    }
    if (p) {
	ntype = neighborType(p, mem->request);
	neighborUpdateRtt(p, mem);
    }
    if (ignoreMulticastReply(p, mem)) {
	neighborCountIgnored(p);
	return;
    }
    debug(15, 3) ("neighborsHtcpReply: e = %p\n", e);
    mem->ping_reply_callback(p, ntype, PROTO_HTCP, htcp, mem->ircb_data);
}
コード例 #12
0
ファイル: icap_respmod.c プロジェクト: OPSF/uClinux
/*
 * copied from httpReadReply()
 *
 * by the time this is called, the ICAP headers have already
 * been read.
 */
void
icapReadReply(int fd, void *data)
{
    IcapStateData *icap = data;
    StoreEntry *entry = icap->respmod.entry;
    const request_t *request = icap->request;
    int len;
    debug(81, 5) ("icapReadReply: FD %d: icap %p.\n", fd, data);
    if (icap->flags.no_content && !icap->flags.http_server_eof) {	//AI

	return;
    }
    if (EBIT_TEST(entry->flags, ENTRY_ABORTED)) {
	comm_close(fd);
	return;
    }
    errno = 0;
    statCounter.syscalls.sock.reads++;
    len = memBufRead(fd, &icap->chunk_buf);
    debug(81, 5) ("icapReadReply: FD %d: len %d.\n", fd, len);
    if (len > 0) {
	fd_bytes(fd, len, FD_READ);
	kb_incr(&statCounter.icap.all.kbytes_in, len);
	commSetTimeout(fd, Config.Timeout.read, icapReadTimeout, icap);
	if (icap->chunk_buf.size < icap->chunk_buf.capacity) {
	    *(icap->chunk_buf.buf + icap->chunk_buf.size) = '\0';
	    debug(81, 9) ("{%s}\n", icap->chunk_buf.buf);
	}
    }
    if (len <= 0) {
	debug(81, 2) ("icapReadReply: FD %d: read failure: %s.\n",
	    fd, xstrerror());
	if (ignoreErrno(errno)) {
	    debug(81, 2) ("icapReadReply: FD %d: ignored errno\n", fd);
	    commSetSelect(fd, COMM_SELECT_READ, icapReadReply, icap, 0);
	} else if (entry->mem_obj->inmem_hi == 0) {
	    ErrorState *err;
	    debug(81, 2) ("icapReadReply: FD %d: generating error page\n", fd);
	    err = errorCon(ERR_ICAP_FAILURE, HTTP_INTERNAL_SERVER_ERROR);
	    err->request = requestLink((request_t *) request);
	    err->xerrno = errno;
	    errorAppendEntry(entry, err);
	    comm_close(fd);
	} else {
	    debug(81, 2) ("icapReadReply: FD %d: just calling comm_close()\n",
		fd);
	    comm_close(fd);
	}
	return;
    }
    if (icapReadReply2(icap) < 0)
	comm_close(fd);
}
コード例 #13
0
ファイル: store_dir.c プロジェクト: UTSASRG/DoubleTake
/*
 * An entry written to the swap log MUST have the following
 * properties.
 *   1.  It MUST be a public key.  It does no good to log
 *       a public ADD, change the key, then log a private
 *       DEL.  So we need to log a DEL before we change a
 *       key from public to private.
 *   2.  It MUST have a valid (> -1) swap_file_number.
 */
void
storeDirSwapLog(const StoreEntry * e, int op)
{
    int dirn = e->swap_file_number >> SWAP_DIR_SHIFT;
    SwapDir *sd;
    assert(dirn < Config.cacheSwap.n_configured);
    assert(!EBIT_TEST(e->flags, KEY_PRIVATE));
    assert(e->swap_file_number >= 0);
    /*
     * icons and such; don't write them to the swap log
     */
    if (EBIT_TEST(e->flags, ENTRY_SPECIAL))
	return;
    assert(op > SWAP_LOG_NOP && op < SWAP_LOG_MAX);
    debug(20, 3) ("storeDirSwapLog: %s %s %08X\n",
	swap_log_op_str[op],
	storeKeyText(e->key),
	e->swap_file_number);
    sd = &Config.cacheSwap.swapDirs[dirn];
    sd->log.write(sd, e, op);
}
コード例 #14
0
static void
whoisReadReply(int fd, void *data)
{
    WhoisState *p = data;
    StoreEntry *entry = p->entry;
    char *buf = memAllocate(MEM_4K_BUF);
    MemObject *mem = entry->mem_obj;
    int len;
    statCounter.syscalls.sock.reads++;
    len = FD_READ_METHOD(fd, buf, 4095);
    buf[len] = '\0';
    debug(75, 3) ("whoisReadReply: FD %d read %d bytes\n", fd, len);
    debug(75, 5) ("{%s}\n", buf);
    if (len > 0) {
	if (0 == mem->inmem_hi) {
	    http_reply *reply = mem->reply;
	    http_version_t version;
	    storeBuffer(entry);
	    httpBuildVersion(&version, 1, 0);
	    httpReplySetHeaders(reply, version, HTTP_OK, "Gatewaying", "text/plain", -1, -1, -2);
	    httpReplySwapOut(reply, entry);
	}
	fd_bytes(fd, len, FD_READ);
	kb_incr(&statCounter.server.all.kbytes_in, len);
	kb_incr(&statCounter.server.http.kbytes_in, len);
	storeAppend(entry, buf, len);
	storeBufferFlush(entry);
	commSetSelect(fd, COMM_SELECT_READ, whoisReadReply, p, Config.Timeout.read);
    } else if (len < 0) {
	debug(50, 2) ("whoisReadReply: FD %d: read failure: %s.\n",
	    fd, xstrerror());
	if (ignoreErrno(errno)) {
	    commSetSelect(fd, COMM_SELECT_READ, whoisReadReply, p, Config.Timeout.read);
	} else {
	    ErrorState *err;
	    err = errorCon(ERR_READ_ERROR, HTTP_INTERNAL_SERVER_ERROR, p->fwd->request);
	    err->xerrno = errno;
	    fwdFail(p->fwd, err);
	    comm_close(fd);
	}
    } else {
	storeTimestampsSet(entry);
	storeBufferFlush(entry);
	if (!EBIT_TEST(entry->flags, RELEASE_REQUEST))
	    storeSetPublicKey(entry);
	fwdComplete(p->fwd);
	debug(75, 3) ("whoisReadReply: Done: %s\n", storeUrl(entry));
	comm_close(fd);
    }
    memFree(buf, MEM_4K_BUF);
}
コード例 #15
0
/* return 1 if the request should be aborted */
static int
CheckQuickAbort2(StoreEntry * entry)
{
    squid_off_t curlen;
    squid_off_t minlen;
    squid_off_t expectlen;
    MemObject *mem = entry->mem_obj;
    assert(mem);
    debug(20, 3) ("CheckQuickAbort2: entry=%p, mem=%p\n", entry, mem);
    if (mem->request && !mem->request->flags.cachable) {
	debug(20, 3) ("CheckQuickAbort2: YES !mem->request->flags.cachable\n");
	return 1;
    }
    expectlen = httpReplyBodySize(mem->method, mem->reply) + mem->reply->hdr_sz;
    curlen = mem->inmem_hi;
    if (expectlen == curlen) {
	debug(20, 3) ("CheckQuickAbort2: NO already finished\n");
	return 0;
    }
    if (EBIT_TEST(entry->flags, KEY_PRIVATE)) {
	debug(20, 3) ("CheckQuickAbort2: YES KEY_PRIVATE\n");
	return 1;
    }
    minlen = Config.quickAbort.min << 10;
    if (minlen < 0) {
	debug(20, 3) ("CheckQuickAbort2: NO disabled\n");
	return 0;
    }
    if (curlen > expectlen) {
	debug(20, 3) ("CheckQuickAbort2: YES bad content length\n");
	return 1;
    }
    if ((expectlen - curlen) < minlen) {
	debug(20, 3) ("CheckQuickAbort2: NO only little more left\n");
	return 0;
    }
    if ((expectlen - curlen) > (Config.quickAbort.max << 10)) {
	debug(20, 3) ("CheckQuickAbort2: YES too much left to go\n");
	return 1;
    }
    if (expectlen < 100) {
	debug(20, 3) ("CheckQuickAbort2: NO avoid FPE\n");
	return 0;
    }
    if ((curlen / (expectlen / 100)) > Config.quickAbort.pct) {
	debug(20, 3) ("CheckQuickAbort2: NO past point of no return\n");
	return 0;
    }
    debug(20, 3) ("CheckQuickAbort2: YES default, returning 1\n");
    return 1;
}
コード例 #16
0
ファイル: mod_select_disk.c プロジェクト: selecli/squid
static int 
hookSwdaeSwapRegiestMemPd(HttpStateData *hs, char *buf, ssize_t len)
{
    StoreEntry *e = hs ? hs->entry : NULL;
    if (0 == g_CheckReply_Flags && e->mem_obj && e && EBIT_TEST(e->flags, ENTRY_CACHABLE))
    {
        SD_MemPd_t *ssPd = cc_get_mod_private_data(MEMOBJECT_PRIVATE_DATA, e->mem_obj , mod);
        if (NULL == ssPd) ssPd = p_Mod_AllocMemPd();
        ssPd->fd = hs->fd;
        cc_register_mod_private_data(MEMOBJECT_PRIVATE_DATA, e->mem_obj, ssPd, p_Mod_FreeMemPd, mod);
        debug(172,5)("%s %s %s %s\n", PMOD_NAME,__func__, ssPd ? "cache":"no-cache", storeUrl(e));
    }
    return 0;
}
コード例 #17
0
ファイル: store_repl_heap.c プロジェクト: cristdai/squid2
static void
heap_add(RemovalPolicy * policy, StoreEntry * entry, RemovalPolicyNode * node)
{
    HeapPolicyData *heap = policy->_data;
    assert(!node->data);
    if (EBIT_TEST(entry->flags, ENTRY_SPECIAL))
	return;			/* We won't manage these.. they messes things up */
    node->data = heap_insert(heap->heap, entry);
    heap->count += 1;
    if (!heap->type)
	heap->type = heap_guessType(entry, node);
    /* Add a little more variance to the aging factor */
    heap->heap->age += heap->heap->age / 100000000;
}
コード例 #18
0
void
storeLog(int tag, const StoreEntry * e)
{
    MemObject *mem = e->mem_obj;
    HttpReply *reply;
    if (NULL == storelog)
	return;
#if UNUSED_CODE
    if (EBIT_TEST(e->flags, ENTRY_DONT_LOG))
	return;
#endif
    if (mem != NULL) {
	if (mem->log_url == NULL) {
	    debug(20, 1) ("storeLog: NULL log_url for %s\n", mem->url);
	    storeMemObjectDump(mem);
	    mem->log_url = xstrdup(mem->url);
	}
	reply = mem->reply;
	/*
	 * XXX Ok, where should we print the dir number here?
	 * Because if we print it before the swap file number, it'll break
	 * the existing log format.
	 */
	logfilePrintf(storelog, "%9d.%03d %-7s %02d %08X %s %4d %9d %9d %9d %s %d/%d %s %s\n",
	    (int) current_time.tv_sec,
	    (int) current_time.tv_usec / 1000,
	    storeLogTags[tag],
	    e->swap_dirn,
	    e->swap_filen,
	    storeKeyText(e->hash.key),
	    reply->sline.status,
	    (int) reply->date,
	    (int) reply->last_modified,
	    (int) reply->expires,
	    strLen(reply->content_type) ? strBuf(reply->content_type) : "unknown",
	    reply->content_length,
	    (int) (mem->inmem_hi - mem->reply->hdr_sz),
	    RequestMethodStr[mem->method],
	    mem->log_url);
    } else {
	/* no mem object. Most RELEASE cases */
	logfilePrintf(storelog, "%9d.%03d %-7s %02d %08X %s   ?         ?         ?         ? ?/? ?/? ? ?\n",
	    (int) current_time.tv_sec,
	    (int) current_time.tv_usec / 1000,
	    storeLogTags[tag],
	    e->swap_dirn,
	    e->swap_filen,
	    storeKeyText(e->hash.key));
    }
}
コード例 #19
0
ファイル: store_log.c プロジェクト: KimTaehee/HappyStream
void
storeLog(int tag, const StoreEntry * e)
{
    MemObject *mem = e->mem_obj;
    HttpReply *reply;
    if (NULL == storelog)
	return;
#if UNUSED_CODE
    if (EBIT_TEST(e->flags, ENTRY_DONT_LOG))
	return;
#endif
    if (mem != NULL) {
	reply = mem->reply;
	/*
	 * XXX Ok, where should we print the dir number here?
	 * Because if we print it before the swap file number, it'll break
	 * the existing log format.
	 */
	logfileLineStart(storelog);
	logfilePrintf(storelog, "%9ld.%03d %-7s %02d %08X %s %4d %9ld %9ld %9ld %s %" PRINTF_OFF_T "/%" PRINTF_OFF_T " %s %s\n",
	    (long int) current_time.tv_sec,
	    (int) current_time.tv_usec / 1000,
	    storeLogTags[tag],
	    e->swap_dirn,
	    e->swap_filen,
	    storeKeyText(e->hash.key),
	    reply->sline.status,
	    (long int) reply->date,
	    (long int) reply->last_modified,
	    (long int) reply->expires,
	    strLen(reply->content_type) ? strBuf(reply->content_type) : "unknown",
	    reply->content_length,
	    mem->inmem_hi - mem->reply->hdr_sz,
	    RequestMethods[mem->method].str,
	    rfc1738_escape_unescaped(mem->url));
	logfileLineEnd(storelog);
    } else {
	/* no mem object. Most RELEASE cases */
	logfileLineStart(storelog);
	logfilePrintf(storelog, "%9ld.%03d %-7s %02d %08X %s   ?         ?         ?         ? ?/? ?/? ? ?\n",
	    (long int) current_time.tv_sec,
	    (int) current_time.tv_usec / 1000,
	    storeLogTags[tag],
	    e->swap_dirn,
	    e->swap_filen,
	    storeKeyText(e->hash.key));
	logfileLineEnd(storelog);
    }
}
コード例 #20
0
ファイル: store_update.c プロジェクト: KimTaehee/HappyStream
static void
storeUpdateCopy(void *data, char *buf, ssize_t size)
{
    StoreUpdateState *state = data;

    if (EBIT_TEST(state->newentry->flags, ENTRY_ABORTED)) {
	debug(20, 1) ("storeUpdateCopy: Aborted at %d (%d)\n", (int) state->offset, (int) size);
	/* the abort callback deals with the needed cleanup */
	return;
    }
    if (EBIT_TEST(state->newentry->flags, KEY_PRIVATE) && state->newentry->mem_obj->nclients == 0) {
	debug(20, 2) ("storeUpdateCopy: Gone stale with no clients, skip copying of the rest\n");
	storeUpdateDone(state);
	return;
    }
    if (size < 0) {
	debug(20, 1) ("storeUpdateCopy: Error at %d (%d)\n", (int) state->offset, (int) size);
	storeUpdateDone(state);
	return;
    }
    if (size > 0) {
	storeAppend(state->newentry, buf, size);
	if (EBIT_TEST(state->newentry->flags, ENTRY_ABORTED)) {
	    debug(20, 1) ("storeUpdateCopy: Aborted on write at %d (%d)\n", (int) state->offset, (int) size);
	    return;
	}
	state->offset += size;
	storeClientCopy(state->sc, state->oldentry, state->offset, state->offset, sizeof(state->buf), state->buf, storeUpdateCopy, state);
	return;
    } else {
	storeComplete(state->newentry);
	storeUnlockObject(state->newentry);
	state->newentry = NULL;
	storeUpdateDone(state);
    }
}
コード例 #21
0
static void
CheckQuickAbort(StoreEntry * entry)
{
    if (entry == NULL)
	return;
    if (storePendingNClients(entry) > 0)
	return;
    if (entry->store_status != STORE_PENDING)
	return;
    if (EBIT_TEST(entry->flags, ENTRY_SPECIAL))
	return;
    if (CheckQuickAbort2(entry) == 0)
	return;
    statCounter.aborted_requests++;
    storeAbort(entry);
}
コード例 #22
0
ファイル: peer_select.c プロジェクト: selecli/squid
static int
peerSelectIcpPing(request_t * request, int direct, StoreEntry * entry)
{
	int n;
	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)
		if (direct != DIRECT_NO)
			return 0;
	n = neighborsCount(request);
	debug(44, 3) ("peerSelectIcpPing: counted %d neighbors\n", n);
	return n;
}
コード例 #23
0
ファイル: errorpage.c プロジェクト: carriercomm/myboxfs
/*
 * Function:  errorAppendEntry
 *
 * Arguments: err - This object is destroyed after use in this function.
 *
 * Abstract:  This function generates a error page from the info contained
 *            by 'err' and then stores the text in the specified store
 *            entry.  This function should only be called by ``server
 *            side routines'' which need to communicate errors to the
 *            client side.  It should also be called from client_side.c
 *            because we now support persistent connections, and
 *            cannot assume that we can immediately write to the socket
 *            for an error.
 */
void
errorAppendEntry(StoreEntry * entry, ErrorState * err)
{
    HttpReply *rep;
    MemObject *mem = entry->mem_obj;
    assert(mem != NULL);
    assert(mem->inmem_hi == 0);
    if (entry->store_status != STORE_PENDING) {
	/*
	 * If the entry is not STORE_PENDING, then no clients
	 * care about it, and we don't need to generate an
	 * error message
	 */
	assert(EBIT_TEST(entry->flags, ENTRY_ABORTED));
	assert(mem->nclients == 0);
	errorStateFree(err);
	return;
    }
    if (err->page_id == TCP_RESET) {
	if (err->request) {
	    debug(4, 2) ("RSTing this reply\n");
	    err->request->flags.reset_tcp = 1;
	}
    }
    storeLockObject(entry);
    storeBuffer(entry);
    rep = errorBuildReply(err);
    /* Add authentication header */
    /* TODO: alter errorstate to be accel on|off aware. The 0 on the next line
     * depends on authenticate behaviour: all schemes to date send no extra data
     * on 407/401 responses, and do not check the accel state on 401/407 responses 
     */
    authenticateFixHeader(rep, err->auth_user_request, err->request, 0, 1);
    httpReplySwapOut(rep, entry);
    httpReplyAbsorb(mem->reply, rep);
    EBIT_CLR(entry->flags, ENTRY_FWD_HDR_WAIT);
    storeBufferFlush(entry);
    storeComplete(entry);
    storeNegativeCache(entry);
    storeReleaseRequest(entry);
    storeUnlockObject(entry);
    errorStateFree(err);
}
コード例 #24
0
ファイル: gopher.c プロジェクト: carriercomm/myboxfs
/* This will be called when data is ready to be read from fd.  Read until
 * error or connection closed. */
static void
gopherReadReply(int fd, void *data)
{
    GopherStateData *gopherState = data;
    StoreEntry *entry = gopherState->entry;
    char *buf = NULL;
    int len;
    int clen;
    int bin;
    size_t read_sz;
#if DELAY_POOLS
    delay_id delay_id;
#endif
    if (EBIT_TEST(entry->flags, ENTRY_ABORTED)) {
	comm_close(fd);
	return;
    }
    errno = 0;
    buf = memAllocate(MEM_4K_BUF);
    read_sz = 4096 - 1;		/* leave room for termination */
#if DELAY_POOLS
    delay_id = delayMostBytesAllowed(entry->mem_obj, &read_sz);
#endif
    /* leave one space for \0 in gopherToHTML */
    statCounter.syscalls.sock.reads++;
    len = FD_READ_METHOD(fd, buf, read_sz);
    if (len > 0) {
	fd_bytes(fd, len, FD_READ);
#if DELAY_POOLS
	delayBytesIn(delay_id, len);
#endif
	kb_incr(&statCounter.server.all.kbytes_in, len);
	kb_incr(&statCounter.server.other.kbytes_in, len);
    }
    debug(10, 5) ("gopherReadReply: FD %d read len=%d\n", fd, len);
    if (len > 0) {
	commSetTimeout(fd, Config.Timeout.read, NULL, NULL);
	IOStats.Gopher.reads++;
	for (clen = len - 1, bin = 0; clen; bin++)
	    clen >>= 1;
	IOStats.Gopher.read_hist[bin]++;
    }
コード例 #25
0
ファイル: peer_monitor.c プロジェクト: CoolerVoid/squid
static void
peerMonitorFetchReplyHeaders(void *data, mem_node_ref nr, ssize_t size)
{
    PeerMonitor *pm = data;
    const char *buf = NULL;
    http_status status;
    HttpReply *reply;

    if (EBIT_TEST(pm->running.e->flags, ENTRY_ABORTED))
	goto completed;
    if (size <= 0)
	goto completed;
    if (!cbdataValid(pm->peer))
	goto completed;

    buf = nr.node->data + nr.offset;

    reply = pm->running.e->mem_obj->reply;
    assert(reply);
    status = reply->sline.status;
    pm->running.status = status;
    if (status != HTTP_OK)
	goto completed;
    if (size > reply->hdr_sz) {
	pm->running.size = size - reply->hdr_sz;
	pm->running.offset = size;
    } else {
	pm->running.size = 0;
	pm->running.offset = reply->hdr_sz;
    }
    storeClientRef(pm->running.sc, pm->running.e, pm->running.offset, pm->running.offset, SM_PAGE_SIZE, peerMonitorFetchReply, pm);
    stmemNodeUnref(&nr);
    return;

  completed:
    /* We are fully done with this monitoring request. Clean up */
    stmemNodeUnref(&nr);
    peerMonitorCompleted(pm);
    return;
}
コード例 #26
0
/* This will be called when data is ready to be read from fd.  Read until
 * error or connection closed. */
static void
waisReadReply(int fd, void *data)
{
    WaisStateData *waisState = data;
    LOCAL_ARRAY(char, buf, 4096);
    StoreEntry *entry = waisState->entry;
    int len;
    int clen;
    int bin;
    size_t read_sz;
#if DELAY_POOLS
    delay_id delay_id;
#endif
    if (EBIT_TEST(entry->flags, ENTRY_ABORTED)) {
	comm_close(fd);
	return;
    }
    errno = 0;
    read_sz = 4096;
#if DELAY_POOLS
    delay_id = delayMostBytesAllowed(entry->mem_obj, &read_sz);
#endif
    statCounter.syscalls.sock.reads++;
    len = FD_READ_METHOD(fd, buf, read_sz);
    if (len > 0) {
	fd_bytes(fd, len, FD_READ);
#if DELAY_POOLS
	delayBytesIn(delay_id, len);
#endif
	kb_incr(&statCounter.server.all.kbytes_in, len);
	kb_incr(&statCounter.server.other.kbytes_in, len);
    }
    debug(24, 5) ("waisReadReply: FD %d read len:%d\n", fd, len);
    if (len > 0) {
	commSetTimeout(fd, Config.Timeout.read, NULL, NULL);
	IOStats.Wais.reads++;
	for (clen = len - 1, bin = 0; clen; bin++)
	    clen >>= 1;
	IOStats.Wais.read_hist[bin]++;
    }
コード例 #27
0
ファイル: icap_respmod.c プロジェクト: OPSF/uClinux
static void
icapReadReply3(IcapStateData * icap)
{
    StoreEntry *entry = icap->respmod.entry;
    int fd = icap->icap_fd;
    debug(81, 3) ("icapReadReply3\n");
    if (EBIT_TEST(entry->flags, ENTRY_ABORTED)) {
	debug(81, 3) ("icapReadReply3: Entry Aborded\n");
	comm_close(fd);
    } else if (icapPconnTransferDone(fd, icap)) {
	storeComplete(entry);
	icapRespModKeepAliveOrClose(icap);
    } else if (!icap->flags.no_content) {
	/* Wait for EOF condition */
	commSetSelect(fd, COMM_SELECT_READ, icapReadReply, icap, 0);
	debug(81,
	    3)
	    ("icapReadReply3: Going to read mode data throught icapReadReply\n");
    } else {
	debug(81, 3) ("icapReadReply3: Nothing\n");
    }
}
コード例 #28
0
static store_client_t
storeClientType(StoreEntry * e)
{
    MemObject *mem = e->mem_obj;
    if (mem->inmem_lo)
	return STORE_DISK_CLIENT;
    if (EBIT_TEST(e->flags, ENTRY_ABORTED)) {
	/* I don't think we should be adding clients to aborted entries */
	debug(20, 1) ("storeClientType: adding to ENTRY_ABORTED entry\n");
	return STORE_MEM_CLIENT;
    }
    if (e->store_status == STORE_OK) {
	if (mem->inmem_lo == 0 && mem->inmem_hi > 0)
	    return STORE_MEM_CLIENT;
	else
	    return STORE_DISK_CLIENT;
    }
    /* here and past, entry is STORE_PENDING */
    /*
     * If this is the first client, let it be the mem client
     */
    else if (mem->nclients == 1)
	return STORE_MEM_CLIENT;
    /*
     * If there is no disk file to open yet, we must make this a
     * mem client.  If we can't open the swapin file before writing
     * to the client, there is no guarantee that we will be able
     * to open it later when we really need it.
     */
    else if (e->swap_status == SWAPOUT_NONE)
	return STORE_MEM_CLIENT;
    /*
     * otherwise, make subsequent clients read from disk so they
     * can not delay the first, and vice-versa.
     */
    else
	return STORE_DISK_CLIENT;
}
コード例 #29
0
/* copy bytes requested by the client */
void
storeClientCopy(store_client * sc,
    StoreEntry * e,
    squid_off_t seen_offset,
    squid_off_t copy_offset,
    size_t size,
    char *buf,
    STCB * callback,
    void *data)
{
    debug(20, 3) ("storeClientCopy: %s, seen %" PRINTF_OFF_T ", want %" PRINTF_OFF_T ", size %d, cb %p, cbdata %p\n",
	storeKeyText(e->hash.key),
	seen_offset,
	copy_offset,
	(int) size,
	callback,
	data);
    assert(sc != NULL);
#if STORE_CLIENT_LIST_DEBUG
    assert(sc == storeClientListSearch(e->mem_obj, data));
#endif
    assert(sc->callback == NULL);
    assert(sc->entry == e);
    sc->seen_offset = seen_offset;
    sc->callback = callback;
    sc->callback_data = data;
    cbdataLock(sc->callback_data);
    sc->copy_buf = buf;
    sc->copy_size = size;
    sc->copy_offset = copy_offset;
    /* If the read is being deferred, run swapout in case this client has the 
     * lowest seen_offset. storeSwapOut() frees the memory and clears the 
     * ENTRY_DEFER_READ bit if necessary */
    if (EBIT_TEST(e->flags, ENTRY_DEFER_READ)) {
	storeSwapOut(e);
    }
    storeClientCopy2(e, sc);
}
コード例 #30
0
ファイル: store_digest.c プロジェクト: KimTaehee/HappyStream
void
storeDigestDel(const StoreEntry * entry)
{
#if USE_CACHE_DIGESTS
    if (!Config.onoff.digest_generation) {
	return;
    }
    assert(entry && store_digest);
    debug(71, 6) ("storeDigestDel: checking entry, key: %s\n",
	storeKeyText(entry->hash.key));
    if (!EBIT_TEST(entry->flags, KEY_PRIVATE)) {
	if (!cacheDigestTest(store_digest, entry->hash.key)) {
	    sd_stats.del_lost_count++;
	    debug(71, 6) ("storeDigestDel: lost entry, key: %s url: %s\n",
		storeKeyText(entry->hash.key), storeUrl(entry));
	} else {
	    sd_stats.del_count++;
	    cacheDigestDel(store_digest, entry->hash.key);
	    debug(71, 6) ("storeDigestDel: deled entry, key: %s\n",
		storeKeyText(entry->hash.key));
	}
    }
#endif
}