⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 neighbors.c

📁 -
💻 C
📖 第 1 页 / 共 3 页
字号:
	    /*	     * fake a recent reply if its been a long time since our	     * last query	     */	    p->stats.last_reply = squid_curtime;	    /*	     * We used to not expect a reply in this case; we assumed	     * the peer was DEAD if we hadn't queried it in a long	     * time.  However, the number of people whining to	     * squid-users that ICP is broken became unbearable.  They	     * tried a single request which, to their amazement, was	     * forwarded directly to the origin server, even thought	     * they KNEW it was in a neighbor cache.  Ok, I give up, you	     * win!	     */	    (*exprep)++;	    (*timeout) += 1000;	} else if (neighborUp(p)) {	    /* its alive, expect a reply from it */	    (*exprep)++;	    (*timeout) += p->stats.rtt;	} else {	    /* Neighbor is dead; ping it anyway, but don't expect a reply */	    /* log it once at the threshold */	    if (p->stats.logged_state == PEER_ALIVE) {		debug(15, 1) ("Detected DEAD %s: %s/%d/%d\n",		    neighborTypeStr(p),		    p->host, p->http_port, p->icp.port);		p->stats.logged_state = PEER_DEAD;	    }	}	p->stats.last_query = squid_curtime;    }    if ((first_ping = first_ping->next) == NULL)	first_ping = Config.peers;#if ALLOW_SOURCE_PING    /* only do source_ping if we have neighbors */    if (Config.npeers) {	const ipcache_addrs *ia = NULL;	struct sockaddr_in to_addr;	char *host = request->host;	if (!Config.onoff.source_ping) {	    debug(15, 6) ("neighborsUdpPing: Source Ping is disabled.\n");	} else if ((ia = ipcache_gethostbyname(host, 0))) {	    debug(15, 6) ("neighborsUdpPing: Source Ping: to %s for '%s'\n",		host, url);	    echo_hdr.reqnum = reqnum;	    if (icmp_sock != -1) {		icmpSourcePing(ia->in_addrs[ia->cur], &echo_hdr, url);	    } else {		to_addr.sin_family = AF_INET;		to_addr.sin_addr = ia->in_addrs[ia->cur];		to_addr.sin_port = htons(echo_port);		query = icpCreateMessage(ICP_SECHO, 0, url, reqnum, 0);		icpUdpSend(theOutIcpConnection,		    &to_addr,		    query,		    LOG_ICP_QUERY,		    0);	    }	} else {	    debug(15, 6) ("neighborsUdpPing: Source Ping: unknown host: %s\n",		host);	}    }#endif    /*     * If there is a configured timeout, use it     */    if (Config.Timeout.icp_query)	*timeout = Config.Timeout.icp_query;    else if (*exprep > 0)	(*timeout) = 2 * (*timeout) / (*exprep);    else	*timeout = 2000;	/* 2 seconds */    return peers_pinged;}/* lookup the digest of a given peer */lookup_tpeerDigestLookup(peer * p, request_t * request, StoreEntry * entry){#if USE_CACHE_DIGESTS    const cache_key *key = request ? storeKeyPublic(storeUrl(entry), request->method) : NULL;    assert(p);    assert(request);    debug(15, 5) ("peerDigestLookup: peer %s\n", p->host);    /* does the peeer have a valid digest? */    if (!p->digest) {	debug(15, 5) ("peerDigestLookup: gone!\n");	return LOOKUP_NONE;    } else if (!peerHTTPOkay(p, request)) {	debug(15, 5) ("peerDigestLookup: !peerHTTPOkay\n");	return LOOKUP_NONE;    } else if (p->digest->flags.usable) {	debug(15, 5) ("peerDigestLookup: usable\n");	/* fall through; put here to have common case on top */ ;    } else if (!p->digest->flags.needed) {	debug(15, 5) ("peerDigestLookup: note need\n");	peerDigestNeeded(p->digest);	return LOOKUP_NONE;    } else {	debug(15, 5) ("peerDigestLookup: !ready && %srequested\n",	    p->digest->flags.requested ? "" : "!");	return LOOKUP_NONE;    }    debug(15, 5) ("peerDigestLookup: OK to lookup peer %s\n", p->host);    assert(p->digest->cd);    /* does digest predict a hit? */    if (!cacheDigestTest(p->digest->cd, key))	return LOOKUP_MISS;    debug(15, 5) ("peerDigestLookup: peer %s says HIT!\n", p->host);    return LOOKUP_HIT;#endif    return LOOKUP_NONE;}/* select best peer based on cache digests */peer *neighborsDigestSelect(request_t * request, StoreEntry * entry){    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 = storeKeyPublic(storeUrl(entry), request->method);    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, entry);	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->host, 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->host, 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;}voidpeerNoteDigestLookup(request_t * request, peer * p, lookup_t lookup){#if USE_CACHE_DIGESTS    if (p)	strncpy(request->hier.cd_host, p->host, sizeof(request->hier.cd_host));    else	*request->hier.cd_host = '\0';    request->hier.cd_lookup = lookup;    debug(15, 4) ("peerNoteDigestLookup: peer %s, lookup: %s\n",	p ? p->host : "<none>", lookup_t_str[lookup]);#endif}static voidneighborAlive(peer * p, const MemObject * mem, const icp_common_t * header){    if (p->stats.logged_state == PEER_DEAD && p->tcp_up) {	debug(15, 1) ("Detected REVIVED %s: %s/%d/%d\n",	    neighborTypeStr(p),	    p->host, p->http_port, p->icp.port);	p->stats.logged_state = PEER_ALIVE;    }    p->stats.last_reply = squid_curtime;    p->stats.pings_acked++;    if ((icp_opcode) header->opcode <= ICP_END)	p->icp.counts[header->opcode]++;    p->icp.version = (int) header->version;}static voidneighborUpdateRtt(peer * p, MemObject * mem){    int rtt;    if (!mem)	return;    if (!mem->start_ping.tv_sec)	return;    rtt = tvSubMsec(mem->start_ping, current_time);    if (rtt < 1 || rtt > 10000)	return;    p->stats.rtt = intAverage(p->stats.rtt, rtt,	p->stats.pings_acked, RTT_AV_FACTOR);}#if USE_HTCPstatic voidneighborAliveHtcp(peer * p, const MemObject * mem, const htcpReplyData * htcp){    if (p->stats.logged_state == PEER_DEAD && p->tcp_up) {	debug(15, 1) ("Detected REVIVED %s: %s/%d/%d\n",	    neighborTypeStr(p),	    p->host, p->http_port, p->icp.port);	p->stats.logged_state = PEER_ALIVE;    }    p->stats.last_reply = squid_curtime;    p->stats.pings_acked++;    p->htcp.counts[htcp->hit ? 1 : 0]++;    p->htcp.version = htcp->version;}#endifstatic voidneighborCountIgnored(peer * p){    if (p == NULL)	return;    p->stats.ignored_replies++;    NLateReplies++;}static peer *non_peers = NULL;static voidneighborIgnoreNonPeer(const struct sockaddr_in *from, icp_opcode opcode){    peer *np;    double x;    for (np = non_peers; np; np = np->next) {	if (np->in_addr.sin_addr.s_addr != from->sin_addr.s_addr)	    continue;	if (np->in_addr.sin_port != from->sin_port)	    continue;	break;    }    if (np == NULL) {	np = xcalloc(1, sizeof(peer));	np->in_addr.sin_addr = from->sin_addr;	np->in_addr.sin_port = from->sin_port;	np->icp.port = ntohl(from->sin_port);	np->type = PEER_NONE;	np->host = xstrdup(inet_ntoa(from->sin_addr));	np->next = non_peers;	non_peers = np;    }    np->stats.ignored_replies++;    np->icp.counts[opcode]++;    x = log(np->stats.ignored_replies) / log(10.0);    if (0.0 != x - (double) (int) x)	return;    debug(15, 1) ("WARNING: Ignored %d replies from non-peer %s\n",	np->stats.ignored_replies, np->host);}/* ignoreMulticastReply *  * We want to ignore replies from multicast peers if the * cache_host_domain rules would normally prevent the peer * from being used */static intignoreMulticastReply(peer * p, MemObject * mem){    if (p == NULL)	return 0;    if (!p->options.mcast_responder)	return 0;    if (peerHTTPOkay(p, mem->request))	return 0;    return 1;}/* 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 */voidneighborsUdpAck(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;    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->host : "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->host);	    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->host);		debug(15, 0) ("Disabling '%s', please check your configuration.\n", p->host);		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);    }}peer *peerFindByName(const char *name){    peer *p = NULL;    for (p = Config.peers; p; p = p->next) {	if (!strcasecmp(name, p->host))	    break;    }    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

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -