コード例 #1
0
ファイル: peer_select.c プロジェクト: selecli/squid
static int
peerCheckNetdbDirect(ps_state * psstate)
{
	peer *p;
	int myrtt;
	int myhops;
	if (psstate->direct == DIRECT_NO)
		return 0;
	myrtt = netdbHostRtt(psstate->request->host);
	debug(44, 3) ("peerCheckNetdbDirect: MY RTT = %d msec\n", myrtt);
	debug(44, 3) ("peerCheckNetdbDirect: minimum_direct_rtt = %d msec\n",
				  Config.minDirectRtt);
	if (myrtt && myrtt <= Config.minDirectRtt)
		return 1;
	myhops = netdbHostHops(psstate->request->host);
	debug(44, 3) ("peerCheckNetdbDirect: MY hops = %d\n", myhops);
	debug(44, 3) ("peerCheckNetdbDirect: minimum_direct_hops = %d\n",
				  Config.minDirectHops);
	if (myhops && myhops <= Config.minDirectHops)
		return 1;
	p = whichPeer(&psstate->closest_parent_miss);
	if (p == NULL)
		return 0;
	debug(44, 3) ("peerCheckNetdbDirect: closest_parent_miss RTT = %d msec\n",
				  psstate->ping.p_rtt);
	if (myrtt && myrtt <= psstate->ping.p_rtt)
		return 1;
	return 0;
}
コード例 #2
0
ファイル: neighbors.c プロジェクト: CoolerVoid/squid
/* select best peer based on cache digests */
peer *
neighborsDigestSelect(request_t * request)
{
    peer *best_p = NULL;
#if USE_CACHE_DIGESTS
    const cache_key *key;
    int best_rtt = 0;
    int choice_count = 0;
    int ichoice_count = 0;
    peer *p;
    int p_rtt;
    int i;
    if (!request->flags.hierarchical)
	return NULL;
    key = storeKeyPublicByRequest(request);
    for (i = 0, p = first_ping; i++ < Config.npeers; p = p->next) {
	lookup_t lookup;
	if (!p)
	    p = Config.peers;
	if (i == 1)
	    first_ping = p;
	lookup = peerDigestLookup(p, request);
	if (lookup == LOOKUP_NONE)
	    continue;
	choice_count++;
	if (lookup == LOOKUP_MISS)
	    continue;
	p_rtt = netdbHostRtt(p->host);
	debug(15, 5) ("neighborsDigestSelect: peer %s rtt: %d\n",
	    p->name, p_rtt);
	/* is this peer better than others in terms of rtt ? */
	if (!best_p || (p_rtt && p_rtt < best_rtt)) {
	    best_p = p;
	    best_rtt = p_rtt;
	    if (p_rtt)		/* informative choice (aka educated guess) */
		ichoice_count++;
	    debug(15, 4) ("neighborsDigestSelect: peer %s leads with rtt %d\n",
		p->name, best_rtt);
	}
    }
    debug(15, 4) ("neighborsDigestSelect: choices: %d (%d)\n",
	choice_count, ichoice_count);
    peerNoteDigestLookup(request, best_p,
	best_p ? LOOKUP_HIT : (choice_count ? LOOKUP_MISS : LOOKUP_NONE));
    request->hier.n_choices = choice_count;
    request->hier.n_ichoices = ichoice_count;
#endif
    return best_p;
}
コード例 #3
0
ファイル: urn.c プロジェクト: miettal/armadillo420_standard
static url_entry *
urnParseReply(const char *inbuf, method_t m)
{
    char *buf = xstrdup(inbuf);
    char *token;
    char *url;
    char *host;
    int rtt;
    url_entry *list;
    url_entry *old;
    int n = 32;
    int i = 0;
    debug(52, 3) ("urnParseReply\n");
    list = xcalloc(n + 1, sizeof(*list));
    for (token = strtok(buf, crlf); token; token = strtok(NULL, crlf)) {
	debug(52, 3) ("urnParseReply: got '%s'\n", token);
	if (i == n) {
	    old = list;
	    n <<= 2;
	    list = xcalloc(n + 1, sizeof(*list));
	    xmemcpy(list, old, i * sizeof(*list));
	    safe_free(old);
	}
	url = xstrdup(token);
	host = urlHostname(url);
	if (NULL == host)
	    continue;
	rtt = netdbHostRtt(host);
	if (0 == rtt) {
	    debug(52, 3) ("urnParseReply: Pinging %s\n", host);
	    netdbPingSite(host);
	}
	list[i].url = url;
	list[i].host = xstrdup(host);
	list[i].rtt = rtt;
	list[i].flags.cached = storeGetPublic(url, m) ? 1 : 0;
	i++;
    }
    debug(52, 3) ("urnParseReply: Found %d URLs\n", i);
    return list;
}
コード例 #4
0
static void
icpHandleIcpV2(int fd, struct sockaddr_in from, char *buf, int len)
{
    icp_common_t header;
    StoreEntry *entry = NULL;
    char *url = NULL;
    const cache_key *key;
    request_t *icp_request = NULL;
    int allow = 0;
    aclCheck_t checklist;
    icp_common_t *reply;
    int src_rtt = 0;
    u_num32 flags = 0;
    int rtt = 0;
    int hops = 0;
    xmemcpy(&header, buf, sizeof(icp_common_t));
    /*
     * Only these fields need to be converted
     */
    header.length = ntohs(header.length);
    header.reqnum = ntohl(header.reqnum);
    header.flags = ntohl(header.flags);
    header.pad = ntohl(header.pad);
    /*
     * Length field should match the number of bytes read
     */
    if (len != header.length) {
	debug(12, 3) ("icpHandleIcpV2: ICP message is too small\n");
	return;
    }
    switch (header.opcode) {
    case ICP_QUERY:
	/* We have a valid packet */
	url = buf + sizeof(icp_common_t) + sizeof(u_num32);
	if (strpbrk(url, w_space)) {
	    url = rfc1738_escape(url);
	    reply = icpCreateMessage(ICP_ERR, 0, url, header.reqnum, 0);
	    icpUdpSend(fd, &from, reply, LOG_UDP_INVALID, 0);
	    break;
	}
	if ((icp_request = urlParse(METHOD_GET, url)) == NULL) {
	    reply = icpCreateMessage(ICP_ERR, 0, url, header.reqnum, 0);
	    icpUdpSend(fd, &from, reply, LOG_UDP_INVALID, 0);
	    break;
	}
	memset(&checklist, '\0', sizeof(checklist));
	checklist.src_addr = from.sin_addr;
	checklist.my_addr = no_addr;
	checklist.request = icp_request;
	allow = aclCheckFast(Config.accessList.icp, &checklist);
	if (!allow) {
	    debug(12, 2) ("icpHandleIcpV2: Access Denied for %s by %s.\n",
		inet_ntoa(from.sin_addr), AclMatchedName);
	    if (clientdbCutoffDenied(from.sin_addr)) {
		/*
		 * count this DENIED query in the clientdb, even though
		 * we're not sending an ICP reply...
		 */
		clientdbUpdate(from.sin_addr, LOG_UDP_DENIED, PROTO_ICP, 0);
	    } else {
		reply = icpCreateMessage(ICP_DENIED, 0, url, header.reqnum, 0);
		icpUdpSend(fd, &from, reply, LOG_UDP_DENIED, 0);
	    }
	    break;
	}
	if (header.flags & ICP_FLAG_SRC_RTT) {
	    rtt = netdbHostRtt(icp_request->host);
	    hops = netdbHostHops(icp_request->host);
	    src_rtt = ((hops & 0xFFFF) << 16) | (rtt & 0xFFFF);
	    if (rtt)
		flags |= ICP_FLAG_SRC_RTT;
	}
	/* The peer is allowed to use this cache */
	entry = storeGetPublic(url, METHOD_GET);
	debug(12, 5) ("icpHandleIcpV2: OPCODE %s\n", icp_opcode_str[header.opcode]);
	if (icpCheckUdpHit(entry, icp_request)) {
	    reply = icpCreateMessage(ICP_HIT, flags, url, header.reqnum, src_rtt);
	    icpUdpSend(fd, &from, reply, LOG_UDP_HIT, 0);
	    break;
	}
	if (Config.onoff.test_reachability && rtt == 0) {
	    if ((rtt = netdbHostRtt(icp_request->host)) == 0)
		netdbPingSite(icp_request->host);
	}
	/* if store is rebuilding, return a UDP_HIT, but not a MISS */
	if (store_dirs_rebuilding && opt_reload_hit_only) {
	    reply = icpCreateMessage(ICP_MISS_NOFETCH, flags, url, header.reqnum, src_rtt);
	    icpUdpSend(fd, &from, reply, LOG_UDP_MISS_NOFETCH, 0);
	} else if (hit_only_mode_until > squid_curtime) {
	    reply = icpCreateMessage(ICP_MISS_NOFETCH, flags, url, header.reqnum, src_rtt);
	    icpUdpSend(fd, &from, reply, LOG_UDP_MISS_NOFETCH, 0);
	} else if (Config.onoff.test_reachability && rtt == 0) {
	    reply = icpCreateMessage(ICP_MISS_NOFETCH, flags, url, header.reqnum, src_rtt);
	    icpUdpSend(fd, &from, reply, LOG_UDP_MISS_NOFETCH, 0);
	} else {
	    reply = icpCreateMessage(ICP_MISS, flags, url, header.reqnum, src_rtt);
	    icpUdpSend(fd, &from, reply, LOG_UDP_MISS, 0);
	}
	break;

    case ICP_HIT:
#if ALLOW_SOURCE_PING
    case ICP_SECHO:
#endif
    case ICP_DECHO:
    case ICP_MISS:
    case ICP_DENIED:
    case ICP_MISS_NOFETCH:
	if (neighbors_do_private_keys && header.reqnum == 0) {
	    debug(12, 0) ("icpHandleIcpV2: Neighbor %s returned reqnum = 0\n",
		inet_ntoa(from.sin_addr));
	    debug(12, 0) ("icpHandleIcpV2: Disabling use of private keys\n");
	    neighbors_do_private_keys = 0;
	}
	url = buf + sizeof(icp_common_t);
	debug(12, 3) ("icpHandleIcpV2: %s from %s for '%s'\n",
	    icp_opcode_str[header.opcode],
	    inet_ntoa(from.sin_addr),
	    url);
	key = icpGetCacheKey(url, (int) header.reqnum);
	/* call neighborsUdpAck even if ping_status != PING_WAITING */
	neighborsUdpAck(key, &header, &from);
	break;

    case ICP_INVALID:
    case ICP_ERR:
	break;

    default:
	debug(12, 0) ("icpHandleIcpV2: UNKNOWN OPCODE: %d from %s\n",
	    header.opcode, inet_ntoa(from.sin_addr));
	break;
    }
    if (icp_request)
	requestDestroy(icp_request);
}