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

📄 peer_select.c

📁 -
💻 C
📖 第 1 页 / 共 2 页
字号:
/* * $Id: peer_select.c,v 1.98.2.3 1999/05/11 20:37:05 wessels Exp $ * * DEBUG: section 44    Peer Selection Algorithm * AUTHOR: Duane Wessels * * 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"const char *hier_strings[] ={    "NONE",    "DIRECT",    "SIBLING_HIT",    "PARENT_HIT",    "DEFAULT_PARENT",    "SINGLE_PARENT",    "FIRST_UP_PARENT",    "FIRST_PARENT_MISS",    "CLOSEST_PARENT_MISS",    "CLOSEST_PARENT",    "CLOSEST_DIRECT",    "NO_DIRECT_FAIL",    "SOURCE_FASTEST",    "ROUNDROBIN_PARENT",#if USE_CACHE_DIGESTS    "CACHE_DIGEST_HIT",#endif#if USE_CARP    "CARP",#endif    "ANY_PARENT",    "INVALID CODE"};static struct {    int timeouts;} PeerStats;static char *DirectStr[] ={    "DIRECT_UNKNOWN",    "DIRECT_NO",    "DIRECT_MAYBE",    "DIRECT_YES"};static void peerSelectFoo(ps_state *);static void peerPingTimeout(void *data);static void peerSelectCallback(ps_state * psstate);static IRCB peerHandlePingReply;static void peerSelectStateFree(ps_state * psstate);static void peerIcpParentMiss(peer *, icp_common_t *, ps_state *);#if USE_HTCPstatic void peerHtcpParentMiss(peer *, htcpReplyData *, ps_state *);static void peerHandleHtcpReply(peer *, peer_t, htcpReplyData *, void *);#endifstatic int peerCheckNetdbDirect(ps_state * psstate);static void peerGetSomeNeighbor(ps_state *);static void peerGetSomeNeighborReplies(ps_state *);static void peerGetSomeDirect(ps_state *);static void peerGetSomeParent(ps_state *);static void peerAddFwdServer(FwdServer **, peer *, hier_code);static voidpeerSelectStateFree(ps_state * psstate){    if (psstate->acl_checklist) {	debug(44, 1) ("calling aclChecklistFree() from peerSelectStateFree\n");	aclChecklistFree(psstate->acl_checklist);    }    requestUnlink(psstate->request);    psstate->request = NULL;    if (psstate->entry) {	assert(psstate->entry->ping_status != PING_WAITING);	storeUnlockObject(psstate->entry);	psstate->entry = NULL;    }    cbdataFree(psstate);}intpeerSelectIcpPing(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;}voidpeerSelect(request_t * request,    StoreEntry * entry,    PSC * callback,    void *callback_data){    ps_state *psstate = xcalloc(1, sizeof(ps_state));    if (entry)	debug(44, 3) ("peerSelect: %s\n", storeUrl(entry));    else	debug(44, 3) ("peerSelect: %s\n", RequestMethodStr[request->method]);    cbdataAdd(psstate, cbdataXfree, 0);    psstate->request = requestLink(request);    psstate->entry = entry;    psstate->callback = callback;    psstate->callback_data = callback_data;    psstate->direct = DIRECT_UNKNOWN;#if USE_CACHE_DIGESTS    request->hier.peer_select_start = current_time;#endif    if (psstate->entry)	storeLockObject(psstate->entry);    cbdataLock(callback_data);    peerSelectFoo(psstate);}static voidpeerCheckNeverDirectDone(int answer, void *data){    ps_state *psstate = data;    psstate->acl_checklist = NULL;    debug(44, 3) ("peerCheckNeverDirectDone: %d\n", answer);    psstate->never_direct = answer ? 1 : -1;    peerSelectFoo(psstate);}static voidpeerCheckAlwaysDirectDone(int answer, void *data){    ps_state *psstate = data;    psstate->acl_checklist = NULL;    debug(44, 3) ("peerCheckAlwaysDirectDone: %d\n", answer);    psstate->always_direct = answer ? 1 : -1;    peerSelectFoo(psstate);}static voidpeerSelectCallback(ps_state * psstate){    StoreEntry *entry = psstate->entry;    FwdServer *fs = psstate->servers;    void *data = psstate->callback_data;    if (entry) {	debug(44, 3) ("peerSelectCallback: %s\n", storeUrl(entry));	if (entry->ping_status == PING_WAITING)	    eventDelete(peerPingTimeout, psstate);	entry->ping_status = PING_DONE;    }    if (fs == NULL) {	debug(44, 1) ("Failed to select source for '%s'\n", storeUrl(entry));	debug(44, 1) ("  always_direct = %d\n", psstate->always_direct);	debug(44, 1) ("   never_direct = %d\n", psstate->never_direct);	debug(44, 1) ("       timedout = %d\n", psstate->ping.timedout);    }    psstate->ping.stop = current_time;    psstate->request->hier.ping = psstate->ping;    if (cbdataValid(data)) {	psstate->servers = NULL;	psstate->callback(fs, data);    }    cbdataUnlock(data);    peerSelectStateFree(psstate);}static intpeerCheckNetdbDirect(ps_state * psstate){    peer *p = whichPeer(&psstate->closest_parent_miss);    int myrtt;    int myhops;    if (p == NULL)	return 0;    myrtt = netdbHostRtt(psstate->request->host);    debug(44, 3) ("peerCheckNetdbDirect: MY RTT = %d msec\n", myrtt);    debug(44, 3) ("peerCheckNetdbDirect: closest_parent_miss RTT = %d msec\n",	psstate->ping.p_rtt);    if (myrtt && myrtt < psstate->ping.p_rtt)	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;    return 0;}static voidpeerSelectFoo(ps_state * ps){    StoreEntry *entry = ps->entry;    request_t *request = ps->request;    debug(44, 3) ("peerSelectFoo: '%s %s'\n",	RequestMethodStr[request->method],	request->host);    if (ps->direct == DIRECT_UNKNOWN) {	if (ps->always_direct == 0 && Config.accessList.AlwaysDirect) {	    ps->acl_checklist = aclChecklistCreate(		Config.accessList.AlwaysDirect,		request,		request->client_addr,		request->my_addr,		NULL,		/* user agent */		NULL);		/* ident */	    aclNBCheck(ps->acl_checklist,		peerCheckAlwaysDirectDone,		ps);	    return;	} else if (ps->always_direct > 0) {	    ps->direct = DIRECT_YES;	} else if (ps->never_direct == 0 && Config.accessList.NeverDirect) {	    ps->acl_checklist = aclChecklistCreate(		Config.accessList.NeverDirect,		request,		request->client_addr,		request->my_addr,		NULL,		/* user agent */		NULL);		/* ident */	    aclNBCheck(ps->acl_checklist,		peerCheckNeverDirectDone,		ps);	    return;	} else if (ps->never_direct > 0) {	    ps->direct = DIRECT_NO;	} else if (request->flags.loopdetect) {	    ps->direct = DIRECT_YES;	} else {	    ps->direct = DIRECT_MAYBE;	}	debug(44, 3) ("peerSelectFoo: direct = %s\n",	    DirectStr[ps->direct]);    }    if (entry == NULL) {	(void) 0;    } else if (entry->ping_status == PING_NONE) {	peerGetSomeNeighbor(ps);	if (entry->ping_status == PING_WAITING)	    return;    } else if (entry->ping_status == PING_WAITING) {	peerGetSomeNeighborReplies(ps);	entry->ping_status = PING_DONE;    }    if (Config.onoff.prefer_direct)	peerGetSomeDirect(ps);    peerGetSomeParent(ps);    if (!Config.onoff.prefer_direct)	peerGetSomeDirect(ps);    peerSelectCallback(ps);}/* * peerGetSomeNeighbor *  * Selects a neighbor (parent or sibling) based on one of the * following methods: *      Cache Digests *      CARP *      Netdb RTT estimates *      ICP/HTCP queries */static voidpeerGetSomeNeighbor(ps_state * ps){    StoreEntry *entry = ps->entry;    request_t *request = ps->request;    peer *p;    hier_code code = HIER_NONE;    assert(entry->ping_status == PING_NONE);

⌨️ 快捷键说明

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