예제 #1
0
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);
}
예제 #2
0
/* ask store for a digest */
static void
peerDigestRequest(PeerDigest * pd)
{
    peer *p = pd->peer;
    StoreEntry *e, *old_e;
    char *url;
    const cache_key *key;
    request_t *req;
    DigestFetchState *fetch = NULL;

    pd->req_result = NULL;
    pd->flags.requested = 1;

    /* compute future request components */
    if (p->digest_url)
	url = xstrdup(p->digest_url);
    else
	url = internalRemoteUri(p->host, p->http_port,
	    "/squid-internal-periodic/", StoreDigestFileName);

    key = storeKeyPublic(url, METHOD_GET);
    debug(72, 2) ("peerDigestRequest: %s key: %s\n", url, storeKeyText(key));
    req = urlParse(METHOD_GET, url);
    assert(req);

    /* add custom headers */
    assert(!req->header.len);
    httpHeaderPutStr(&req->header, HDR_ACCEPT, StoreDigestMimeStr);
    httpHeaderPutStr(&req->header, HDR_ACCEPT, "text/html");
    if (p->login)
	xstrncpy(req->login, p->login, MAX_LOGIN_SZ);
    /* create fetch state structure */
    fetch = memAllocate(MEM_DIGEST_FETCH_STATE);
    cbdataAdd(fetch, memFree, MEM_DIGEST_FETCH_STATE);
    fetch->request = requestLink(req);
    fetch->pd = pd;
    fetch->offset = 0;

    /* update timestamps */
    fetch->start_time = squid_curtime;
    pd->times.requested = squid_curtime;
    pd_last_req_time = squid_curtime;

    req->flags.cachable = 1;
    /* the rest is based on clientProcessExpired() */
    req->flags.refresh = 1;
    old_e = fetch->old_entry = storeGet(key);
    if (old_e) {
	debug(72, 5) ("peerDigestRequest: found old entry\n");
	storeLockObject(old_e);
	storeCreateMemObject(old_e, url, url);
	storeClientListAdd(old_e, fetch);
    }
    e = fetch->entry = storeCreateEntry(url, url, req->flags, req->method);
    assert(EBIT_TEST(e->flags, KEY_PRIVATE));
    storeClientListAdd(e, fetch);
    /* set lastmod to trigger IMS request if possible */
    if (old_e)
	e->lastmod = old_e->lastmod;

    /* push towards peer cache */
    debug(72, 3) ("peerDigestRequest: forwarding to fwdStart...\n");
    fwdStart(-1, e, req);
    cbdataLock(fetch);
    cbdataLock(fetch->pd);
    storeClientCopy(e, 0, 0, 4096, memAllocate(MEM_4K_BUF),
	peerDigestFetchReply, fetch);
}
예제 #3
0
/* I should attach these records to the entry.  We take the first
 * hit we get our wait until everyone misses.  The timeout handler
 * call needs to nip this shopping list or call one of the misses.
 * 
 * If a hit process is already started, then sobeit
 */
void
neighborsUdpAck(const cache_key * key, icp_common_t * header, const struct sockaddr_in *from)
{
    peer *p = NULL;
    StoreEntry *entry;
    MemObject *mem = NULL;
    peer_t ntype = PEER_NONE;
    const char *opcode_d;
    icp_opcode opcode = (icp_opcode) header->opcode;

    debug(15, 6) ("neighborsUdpAck: opcode %d '%s'\n",
	(int) opcode, storeKeyText(key));
    if (NULL != (entry = storeGet(key)))
	mem = entry->mem_obj;
    if ((p = whichPeer(from)))
	neighborAlive(p, mem, header);
    if (opcode > ICP_END)
	return;
    opcode_d = icp_opcode_str[opcode];
    if (p)
	neighborUpdateRtt(p, mem);
    /* Does the entry exist? */
    if (NULL == entry) {
	debug(12, 3) ("neighborsUdpAck: Cache key '%s' not found\n",
	    storeKeyText(key));
	neighborCountIgnored(p);
	return;
    }
    /* check if someone is already fetching it */
    if (EBIT_TEST(entry->flags, ENTRY_DISPATCHED)) {
	debug(15, 3) ("neighborsUdpAck: '%s' already being fetched.\n",
	    storeKeyText(key));
	neighborCountIgnored(p);
	return;
    }
    if (mem == NULL) {
	debug(15, 2) ("Ignoring %s for missing mem_obj: %s\n",
	    opcode_d, storeKeyText(key));
	neighborCountIgnored(p);
	return;
    }
    if (entry->ping_status != PING_WAITING) {
	debug(15, 2) ("neighborsUdpAck: Late %s for %s\n",
	    opcode_d, storeKeyText(key));
	neighborCountIgnored(p);
	return;
    }
    if (entry->lock_count == 0) {
	debug(12, 1) ("neighborsUdpAck: '%s' has no locks\n",
	    storeKeyText(key));
	neighborCountIgnored(p);
	return;
    }
    debug(15, 3) ("neighborsUdpAck: %s for '%s' from %s \n",
	opcode_d, storeKeyText(key), p ? p->name : "source");
    if (p) {
	ntype = neighborType(p, mem->request);
    }
    if (ignoreMulticastReply(p, mem)) {
	neighborCountIgnored(p);
    } else if (opcode == ICP_MISS) {
	if (p == NULL) {
	    neighborIgnoreNonPeer(from, opcode);
	} else {
	    mem->ping_reply_callback(p, ntype, PROTO_ICP, header, mem->ircb_data);
	}
    } else if (opcode == ICP_HIT) {
	if (p == NULL) {
	    neighborIgnoreNonPeer(from, opcode);
	} else {
	    header->opcode = ICP_HIT;
	    mem->ping_reply_callback(p, ntype, PROTO_ICP, header, mem->ircb_data);
	}
    } else if (opcode == ICP_DECHO) {
	if (p == NULL) {
	    neighborIgnoreNonPeer(from, opcode);
	} else if (ntype == PEER_SIBLING) {
	    debug_trap("neighborsUdpAck: Found non-ICP cache as SIBLING\n");
	    debug_trap("neighborsUdpAck: non-ICP neighbors must be a PARENT\n");
	} else {
	    mem->ping_reply_callback(p, ntype, PROTO_ICP, header, mem->ircb_data);
	}
    } else if (opcode == ICP_SECHO) {
	if (p) {
	    debug(15, 1) ("Ignoring SECHO from neighbor %s\n", p->name);
	    neighborCountIgnored(p);
#if ALLOW_SOURCE_PING
	} else if (Config.onoff.source_ping) {
	    mem->ping_reply_callback(NULL, ntype, PROTO_ICP, header, mem->ircb_data);
#endif
	} else {
	    debug(15, 1) ("Unsolicited SECHO from %s\n", inet_ntoa(from->sin_addr));
	}
    } else if (opcode == ICP_DENIED) {
	if (p == NULL) {
	    neighborIgnoreNonPeer(from, opcode);
	} else if (p->stats.pings_acked > 100) {
	    if (100 * p->icp.counts[ICP_DENIED] / p->stats.pings_acked > 95) {
		debug(15, 0) ("95%% of replies from '%s' are UDP_DENIED\n", p->name);
		debug(15, 0) ("Disabling '%s', please check your configuration.\n", p->name);
		neighborRemove(p);
		p = NULL;
	    } else {
		neighborCountIgnored(p);
	    }
	}
    } else if (opcode == ICP_MISS_NOFETCH) {
	mem->ping_reply_callback(p, ntype, PROTO_ICP, header, mem->ircb_data);
    } else {
	debug(15, 0) ("neighborsUdpAck: Unexpected ICP reply: %s\n", opcode_d);
    }
}