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

📄 neighbors.c

📁 -
💻 C
📖 第 1 页 / 共 3 页
字号:
/* * $Id: neighbors.c,v 1.270.2.4 1999/07/07 02:02:26 wessels Exp $ * * DEBUG: section 15    Neighbor Routines * AUTHOR: Harvest Derived * * SQUID Internet Object Cache  http://squid.nlanr.net/Squid/ * ---------------------------------------------------------- * *  Squid is the result of efforts by numerous individuals from the *  Internet community.  Development is led by Duane Wessels of the *  National Laboratory for Applied Network Research and funded by the *  National Science Foundation.  Squid is Copyrighted (C) 1998 by *  Duane Wessels and the University of California San Diego.  Please *  see the COPYRIGHT file for full details.  Squid incorporates *  software developed and/or copyrighted by other sources.  Please see *  the CREDITS file for full details. * *  This program is free software; you can redistribute it and/or modify *  it under the terms of the GNU General Public License as published by *  the Free Software Foundation; either version 2 of the License, or *  (at your option) any later version. *   *  This program is distributed in the hope that it will be useful, *  but WITHOUT ANY WARRANTY; without even the implied warranty of *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the *  GNU General Public License for more details. *   *  You should have received a copy of the GNU General Public License *  along with this program; if not, write to the Free Software *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111, USA. * */#include "squid.h"/* count mcast group peers every 15 minutes */#define MCAST_COUNT_RATE 900static int peerAllowedToUse(const peer *, request_t *);static int peerWouldBePinged(const peer *, request_t *);static void neighborRemove(peer *);static void neighborAlive(peer *, const MemObject *, const icp_common_t *);#if USE_HTCPstatic void neighborAliveHtcp(peer *, const MemObject *, const htcpReplyData *);#endifstatic void neighborCountIgnored(peer *);static void peerRefreshDNS(void *);static IPH peerDNSConfigure;static EVH peerCheckConnect;static IPH peerCheckConnect2;static CNCB peerCheckConnectDone;static void peerCountMcastPeersDone(void *data);static void peerCountMcastPeersStart(void *data);static void peerCountMcastPeersSchedule(peer * p, time_t when);static IRCB peerCountHandleIcpReply;static void neighborIgnoreNonPeer(const struct sockaddr_in *, icp_opcode);static OBJH neighborDumpPeers;static OBJH neighborDumpNonPeers;static void dump_peers(StoreEntry * sentry, peer * peers);static icp_common_t echo_hdr;static u_short echo_port;static int NLateReplies = 0;static peer *first_ping = NULL;char *neighborTypeStr(const peer * p){    if (p->type == PEER_NONE)	return "Non-Peer";    if (p->type == PEER_SIBLING)	return "Sibling";    if (p->type == PEER_MULTICAST)	return "Multicast Group";    return "Parent";}peer *whichPeer(const struct sockaddr_in * from){    int j;    u_short port = ntohs(from->sin_port);    struct in_addr ip = from->sin_addr;    peer *p = NULL;    debug(15, 3) ("whichPeer: from %s port %d\n", inet_ntoa(ip), port);    for (p = Config.peers; p; p = p->next) {	for (j = 0; j < p->n_addresses; j++) {	    if (ip.s_addr == p->addresses[j].s_addr && port == p->icp.port) {		return p;	    }	}    }    return NULL;}peer_tneighborType(const peer * p, const request_t * request){    const struct _domain_type *d = NULL;    for (d = p->typelist; d; d = d->next) {	if (matchDomainName(d->domain, request->host))	    if (d->type != PEER_NONE)		return d->type;    }    return p->type;}/* * peerAllowedToUse * * this function figures out if it is appropriate to fetch REQUEST * from PEER. */static intpeerAllowedToUse(const peer * p, request_t * request){    const struct _domain_ping *d = NULL;    int do_ping = 1;    aclCheck_t checklist;    assert(request != NULL);    if (neighborType(p, request) == PEER_SIBLING) {	if (request->flags.nocache)	    return 0;	if (request->flags.refresh)	    return 0;	if (request->flags.loopdetect)	    return 0;	if (request->flags.need_validation)	    return 0;    }    if (p->peer_domain == NULL && p->access == NULL)	return do_ping;    do_ping = 0;    for (d = p->peer_domain; d; d = d->next) {	if (matchDomainName(d->domain, request->host)) {	    do_ping = d->do_ping;	    break;	}	do_ping = !d->do_ping;    }    if (p->peer_domain && 0 == do_ping)	return do_ping;    if (p->access == NULL)	return do_ping;    checklist.src_addr = request->client_addr;    checklist.my_addr = request->my_addr;    checklist.request = request;    return aclCheckFast(p->access, &checklist);}/* Return TRUE if it is okay to send an ICP request to this peer.   */static intpeerWouldBePinged(const peer * p, request_t * request){    if (!peerAllowedToUse(p, request))	return 0;    if (p->options.no_query)	return 0;    if (p->options.mcast_responder)	return 0;    /* the case below seems strange, but can happen if the     * URL host is on the other side of a firewall */    if (p->type == PEER_SIBLING)	if (!request->flags.hierarchical)	    return 0;    if (p->icp.port == echo_port)	if (!neighborUp(p))	    return 0;    if (p->n_addresses == 0)	return 0;    return 1;}/* Return TRUE if it is okay to send an HTTP request to this peer. */intpeerHTTPOkay(const peer * p, request_t * request){    if (!peerAllowedToUse(p, request))	return 0;    if (!neighborUp(p))	return 0;    return 1;}intneighborsCount(request_t * request){    peer *p = NULL;    int count = 0;    for (p = Config.peers; p; p = p->next)	if (peerWouldBePinged(p, request))	    count++;    debug(15, 3) ("neighborsCount: %d\n", count);    return count;}peer *getSingleParent(request_t * request){    peer *p = NULL;    peer *q = NULL;    for (q = Config.peers; q; q = q->next) {	if (!peerHTTPOkay(q, request))	    continue;	if (neighborType(q, request) != PEER_PARENT)	    return NULL;	/* oops, found SIBLING */	if (p)	    return NULL;	/* oops, found second parent */	p = q;    }    if (p != NULL && !p->options.no_query)	return NULL;    debug(15, 3) ("getSingleParent: returning %s\n", p ? p->host : "NULL");    return p;}peer *getFirstUpParent(request_t * request){    peer *p = NULL;    for (p = Config.peers; p; p = p->next) {	if (!neighborUp(p))	    continue;	if (neighborType(p, request) != PEER_PARENT)	    continue;	if (!peerHTTPOkay(p, request))	    continue;	break;    }    debug(15, 3) ("getFirstUpParent: returning %s\n", p ? p->host : "NULL");    return p;}peer *getRoundRobinParent(request_t * request){    peer *p;    peer *q = NULL;    for (p = Config.peers; p; p = p->next) {	if (!p->options.roundrobin)	    continue;	if (neighborType(p, request) != PEER_PARENT)	    continue;	if (!peerHTTPOkay(p, request))	    continue;	if (q && q->rr_count < p->rr_count)	    continue;	q = p;    }    if (q)	q->rr_count++;    debug(15, 3) ("getRoundRobinParent: returning %s\n", q ? q->host : "NULL");    return q;}peer *getDefaultParent(request_t * request){    peer *p = NULL;    for (p = Config.peers; p; p = p->next) {	if (neighborType(p, request) != PEER_PARENT)	    continue;	if (!p->options.default_parent)	    continue;	if (!peerHTTPOkay(p, request))	    continue;	debug(15, 3) ("getDefaultParent: returning %s\n", p->host);	return p;    }    debug(15, 3) ("getDefaultParent: returning NULL\n");    return NULL;}peer *getAnyParent(request_t * request){    peer *p = NULL;    for (p = Config.peers; p; p = p->next) {	if (neighborType(p, request) != PEER_PARENT)	    continue;	if (!peerHTTPOkay(p, request))	    continue;	debug(15, 3) ("getAnyParent: returning %s\n", p->host);	return p;    }    debug(15, 3) ("getAnyParent: returning NULL\n");    return NULL;}peer *getNextPeer(peer * p){    return p->next;}peer *getFirstPeer(void){    return Config.peers;}static voidneighborRemove(peer * target){    peer *p = NULL;    peer **P = NULL;    p = Config.peers;    P = &Config.peers;    while (p) {	if (target == p)	    break;	P = &p->next;	p = p->next;    }    if (p) {	*P = p->next;	cbdataFree(p);	Config.npeers--;    }    first_ping = Config.peers;}voidneighbors_open(int fd){    struct sockaddr_in name;    socklen_t len = sizeof(struct sockaddr_in);    struct servent *sep = NULL;    memset(&name, '\0', sizeof(struct sockaddr_in));    if (getsockname(fd, (struct sockaddr *) &name, &len) < 0)	debug(15, 1) ("getsockname(%d,%p,%p) failed.\n", fd, &name, &len);    peerRefreshDNS((void *) 1);    if (0 == echo_hdr.opcode) {	echo_hdr.opcode = ICP_SECHO;	echo_hdr.version = ICP_VERSION_CURRENT;	echo_hdr.length = 0;	echo_hdr.reqnum = 0;	echo_hdr.flags = 0;	echo_hdr.pad = 0;	echo_hdr.shostid = name.sin_addr.s_addr;	sep = getservbyname("echo", "udp");	echo_port = sep ? ntohs((u_short) sep->s_port) : 7;    }    first_ping = Config.peers;    cachemgrRegister("server_list",	"Peer Cache Statistics",	neighborDumpPeers, 0, 1);    cachemgrRegister("non_peers",	"List of Unknown sites sending ICP messages",	neighborDumpNonPeers, 0, 1);}intneighborsUdpPing(request_t * request,    StoreEntry * entry,    IRCB * callback,    void *callback_data,    int *exprep,    int *timeout){    const char *url = storeUrl(entry);    MemObject *mem = entry->mem_obj;    peer *p = NULL;    int i;    int reqnum = 0;    int flags;    icp_common_t *query;    int queries_sent = 0;    int peers_pinged = 0;    if (Config.peers == NULL)	return 0;    if (theOutIcpConnection < 0)	fatal("neighborsUdpPing: There is no ICP socket!");    assert(entry->swap_status == SWAPOUT_NONE);    mem->start_ping = current_time;    mem->ping_reply_callback = callback;    mem->ircb_data = callback_data;    *timeout = 0.0;    reqnum = icpSetCacheKey(entry->key);    for (i = 0, p = first_ping; i++ < Config.npeers; p = p->next) {	if (p == NULL)	    p = Config.peers;	debug(15, 5) ("neighborsUdpPing: Peer %s\n", p->host);	if (!peerWouldBePinged(p, request))	    continue;		/* next peer */	peers_pinged++;	debug(15, 4) ("neighborsUdpPing: pinging peer %s for '%s'\n",	    p->host, url);	if (p->type == PEER_MULTICAST)	    mcastSetTtl(theOutIcpConnection, p->mcast.ttl);	debug(15, 3) ("neighborsUdpPing: key = '%s'\n", storeKeyText(entry->key));	debug(15, 3) ("neighborsUdpPing: reqnum = %d\n", reqnum);#if USE_HTCP	if (p->options.htcp) {	    debug(15, 3) ("neighborsUdpPing: sending HTCP query\n");	    htcpQuery(entry, request, p);	} else#endif	if (p->icp.port == echo_port) {	    debug(15, 4) ("neighborsUdpPing: Looks like a dumb cache, send DECHO ping\n");	    echo_hdr.reqnum = reqnum;	    query = icpCreateMessage(ICP_DECHO, 0, url, reqnum, 0);	    icpUdpSend(theOutIcpConnection,		&p->in_addr,		query,		LOG_ICP_QUERY,		0);	} else {	    flags = 0;	    if (Config.onoff.query_icmp)		if (p->icp.version == ICP_VERSION_2)		    flags |= ICP_FLAG_SRC_RTT;	    query = icpCreateMessage(ICP_QUERY, flags, url, reqnum, 0);	    icpUdpSend(theOutIcpConnection,		&p->in_addr,		query,		LOG_ICP_QUERY,		0);	}	queries_sent++;	p->stats.pings_sent++;	if (p->type == PEER_MULTICAST) {	    /*	     * set a bogus last_reply time so neighborUp() never	     * says a multicast peer is dead.	     */	    p->stats.last_reply = squid_curtime;	    (*exprep) += p->mcast.n_replies_expected;	} else if (squid_curtime - p->stats.last_query > Config.Timeout.deadPeer) {

⌨️ 快捷键说明

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