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

📄 net_db.c

📁 -
💻 C
📖 第 1 页 / 共 2 页
字号:
/* * $Id: net_db.c,v 1.136.2.1 1999/03/22 03:21:54 wessels Exp $ * * DEBUG: section 38    Network Measurement Database * 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"#if USE_ICMPtypedef struct {    peer *p;    StoreEntry *e;    request_t *r;    off_t seen;    off_t used;    size_t buf_sz;    char *buf;} netdbExchangeState;static hash_table *addr_table = NULL;static hash_table *host_table = NULL;static struct in_addr networkFromInaddr(struct in_addr a);static void netdbRelease(netdbEntry * n);static void netdbHashInsert(netdbEntry * n, struct in_addr addr);static void netdbHashDelete(const char *key);static void netdbHostInsert(netdbEntry * n, const char *hostname);static void netdbHostDelete(const net_db_name * x);static void netdbPurgeLRU(void);static netdbEntry *netdbLookupHost(const char *key);static net_db_peer *netdbPeerByName(const netdbEntry * n, const char *);static net_db_peer *netdbPeerAdd(netdbEntry * n, peer * e);static char *netdbPeerName(const char *name);static IPH netdbSendPing;static QS sortPeerByRtt;static QS sortByRtt;static QS netdbLRU;static FREE netdbFreeNameEntry;static FREE netdbFreeNetdbEntry;static STCB netdbExchangeHandleReply;static void netdbExchangeDone(void *);/* We have to keep a local list of peer names.  The Peers structure * gets freed during a reconfigure.  We want this database to * remain persisitent, so _net_db_peer->peername points into this * linked list */static wordlist *peer_names = NULL;static voidnetdbHashInsert(netdbEntry * n, struct in_addr addr){    xstrncpy(n->network, inet_ntoa(networkFromInaddr(addr)), 16);    n->key = n->network;    assert(hash_lookup(addr_table, n->network) == NULL);    hash_join(addr_table, (hash_link *) n);}static voidnetdbHashDelete(const char *key){    hash_link *hptr = hash_lookup(addr_table, key);    if (hptr == NULL) {	debug_trap("netdbHashDelete: key not found");	return;    }    hash_remove_link(addr_table, hptr);}static voidnetdbHostInsert(netdbEntry * n, const char *hostname){    net_db_name *x = memAllocate(MEM_NET_DB_NAME);    x->name = xstrdup(hostname);    x->next = n->hosts;    n->hosts = x;    x->net_db_entry = n;    assert(hash_lookup(host_table, hostname) == NULL);    hash_join(host_table, (hash_link *) x);    n->link_count++;}static voidnetdbHostDelete(const net_db_name * x){    netdbEntry *n;    net_db_name **X;    assert(x != NULL);    assert(x->net_db_entry != NULL);    n = x->net_db_entry;    n->link_count--;    for (X = &n->hosts; *X; X = &(*X)->next) {	if (*X == x) {	    *X = x->next;	    break;	}    }    hash_remove_link(host_table, (hash_link *) x);    xfree(x->name);    memFree((void *) x, MEM_NET_DB_NAME);}static netdbEntry *netdbLookupHost(const char *key){    net_db_name *x = (net_db_name *) hash_lookup(host_table, key);    return x ? x->net_db_entry : NULL;}static voidnetdbRelease(netdbEntry * n){    net_db_name *x;    net_db_name *next;    for (x = n->hosts; x; x = next) {	next = x->next;	netdbHostDelete(x);    }    n->hosts = NULL;    safe_free(n->peers);    n->peers = NULL;    n->n_peers = 0;    n->n_peers_alloc = 0;    if (n->link_count == 0) {	netdbHashDelete(n->network);	memFree(n, MEM_NETDBENTRY);    }}static intnetdbLRU(const void *A, const void *B){    const netdbEntry *const *n1 = A;    const netdbEntry *const *n2 = B;    if ((*n1)->last_use_time > (*n2)->last_use_time)	return (1);    if ((*n1)->last_use_time < (*n2)->last_use_time)	return (-1);    return (0);}static voidnetdbPurgeLRU(void){    netdbEntry *n;    netdbEntry **list;    int k = 0;    int list_count = 0;    int removed = 0;    list = xcalloc(memInUse(MEM_NETDBENTRY), sizeof(netdbEntry *));    hash_first(addr_table);    while ((n = (netdbEntry *) hash_next(addr_table))) {	assert(list_count < memInUse(MEM_NETDBENTRY));	*(list + list_count) = n;	list_count++;    }    qsort((char *) list,	list_count,	sizeof(netdbEntry *),	netdbLRU);    for (k = 0; k < list_count; k++) {	if (memInUse(MEM_NETDBENTRY) < Config.Netdb.low)	    break;	netdbRelease(*(list + k));	removed++;    }    xfree(list);}static netdbEntry *netdbLookupAddr(struct in_addr addr){    netdbEntry *n;    char *key = inet_ntoa(networkFromInaddr(addr));    n = (netdbEntry *) hash_lookup(addr_table, key);    return n;}static netdbEntry *netdbAdd(struct in_addr addr){    netdbEntry *n;    if (memInUse(MEM_NETDBENTRY) > Config.Netdb.high)	netdbPurgeLRU();    if ((n = netdbLookupAddr(addr)) == NULL) {	n = memAllocate(MEM_NETDBENTRY);	netdbHashInsert(n, addr);    }    return n;}static voidnetdbSendPing(const ipcache_addrs * ia, void *data){    struct in_addr addr;    char *hostname = data;    netdbEntry *n;    netdbEntry *na;    net_db_name *x;    net_db_name **X;    cbdataUnlock(hostname);    if (ia == NULL) {	cbdataFree(hostname);	return;    }    addr = ia->in_addrs[ia->cur];    if ((n = netdbLookupHost(hostname)) == NULL) {	n = netdbAdd(addr);	netdbHostInsert(n, hostname);    } else if ((na = netdbLookupAddr(addr)) != n) {	/*	 *hostname moved from 'network n' to 'network na'!	 */	if (na == NULL)	    na = netdbAdd(addr);	debug(38, 3) ("netdbSendPing: %s moved from %s to %s\n",	    hostname, n->network, na->network);	x = (net_db_name *) hash_lookup(host_table, hostname);	if (x == NULL) {	    debug(38, 1) ("netdbSendPing: net_db_name list bug: %s not found", hostname);	    cbdataFree(hostname);	    return;	}	/* remove net_db_name from 'network n' linked list */	for (X = &n->hosts; *X; X = &(*X)->next) {	    if (*X == x) {		*X = x->next;		break;	    }	}	n->link_count--;	/* point to 'network na' from host entry */	x->net_db_entry = na;	/* link net_db_name to 'network na' */	x->next = na->hosts;	na->hosts = x;	na->link_count++;	n = na;    }    if (n->next_ping_time <= squid_curtime) {	debug(38, 3) ("netdbSendPing: pinging %s\n", hostname);	icmpDomainPing(addr, hostname);	n->pings_sent++;	n->next_ping_time = squid_curtime + Config.Netdb.period;	n->last_use_time = squid_curtime;    }    cbdataFree(hostname);}static struct in_addrnetworkFromInaddr(struct in_addr a){    struct in_addr b;    b.s_addr = ntohl(a.s_addr);#if USE_CLASSFUL    if (IN_CLASSC(b.s_addr))	b.s_addr &= IN_CLASSC_NET;    else if (IN_CLASSB(b.s_addr))	b.s_addr &= IN_CLASSB_NET;    else if (IN_CLASSA(b.s_addr))	b.s_addr &= IN_CLASSA_NET;#else    /* use /24 for everything */    b.s_addr &= IN_CLASSC_NET;#endif    b.s_addr = htonl(b.s_addr);    return b;}static intsortByRtt(const void *A, const void *B){    const netdbEntry *const *n1 = A;    const netdbEntry *const *n2 = B;    if ((*n1)->rtt > (*n2)->rtt)	return 1;    else if ((*n1)->rtt < (*n2)->rtt)	return -1;    else	return 0;}static net_db_peer *netdbPeerByName(const netdbEntry * n, const char *peername){    int i;    net_db_peer *p = n->peers;    for (i = 0; i < n->n_peers; i++, p++) {	if (!strcmp(p->peername, peername))	    return p;    }    return NULL;}static net_db_peer *netdbPeerAdd(netdbEntry * n, peer * e){    net_db_peer *p;    net_db_peer *o;    int osize;    int i;    if (n->n_peers == n->n_peers_alloc) {	o = n->peers;	osize = n->n_peers_alloc;	if (n->n_peers_alloc == 0)	    n->n_peers_alloc = 2;	else	    n->n_peers_alloc <<= 1;	debug(38, 3) ("netdbPeerAdd: Growing peer list for '%s' to %d\n",	    n->network, n->n_peers_alloc);	n->peers = xcalloc(n->n_peers_alloc, sizeof(net_db_peer));	for (i = 0; i < osize; i++)	    *(n->peers + i) = *(o + i);	if (osize) {	    safe_free(o);	}    }    p = n->peers + n->n_peers;    p->peername = netdbPeerName(e->host);    n->n_peers++;    return p;}static intsortPeerByRtt(const void *A, const void *B){    const net_db_peer *p1 = A;    const net_db_peer *p2 = B;    if (p1->rtt > p2->rtt)	return 1;    else if (p1->rtt < p2->rtt)	return -1;    else	return 0;}static voidnetdbSaveState(void *foo){    LOCAL_ARRAY(char, path, SQUID_MAXPATHLEN);    FILE *fp;    netdbEntry *n;    net_db_name *x;    struct timeval start = current_time;    int count = 0;    snprintf(path, SQUID_MAXPATHLEN, "%s/netdb_state", storeSwapDir(0));    fp = fopen(path, "w");    if (fp == NULL) {	debug(50, 1) ("netdbSaveState: %s: %s\n", path, xstrerror());	return;    }    hash_first(addr_table);    while ((n = (netdbEntry *) hash_next(addr_table))) {	if (n->pings_recv == 0)	    continue;	fprintf(fp, "%s %d %d %10.5f %10.5f %d %d",	    n->network,	    n->pings_sent,	    n->pings_recv,	    n->hops,	    n->rtt,	    (int) n->next_ping_time,	    (int) n->last_use_time);	for (x = n->hosts; x; x = x->next)	    fprintf(fp, " %s", x->name);	fprintf(fp, "\n");	count++;    }    fclose(fp);    getCurrentTime();    debug(38, 1) ("NETDB state saved; %d entries, %d msec\n",	count, tvSubMsec(start, current_time));    eventAddIsh("netdbSaveState", netdbSaveState, NULL, 3600.0, 1);}static voidnetdbReloadState(void){    LOCAL_ARRAY(char, path, SQUID_MAXPATHLEN);    char *buf;    char *t;    FILE *fp;    netdbEntry *n;    netdbEntry N;    struct in_addr addr;    int count = 0;    struct timeval start = current_time;    snprintf(path, SQUID_MAXPATHLEN, "%s/netdb_state", storeSwapDir(0));    fp = fopen(path, "r");    if (fp == NULL)	return;    buf = memAllocate(MEM_4K_BUF);    while (fgets(buf, 4095, fp)) {	memset(&N, '\0', sizeof(netdbEntry));	if ((t = strtok(buf, w_space)) == NULL)	    continue;	if (!safe_inet_addr(t, &addr))	    continue;	if (netdbLookupAddr(addr) != NULL)	/* no dups! */	    continue;	if ((t = strtok(NULL, w_space)) == NULL)	    continue;	N.pings_sent = atoi(t);	if ((t = strtok(NULL, w_space)) == NULL)	    continue;	N.pings_recv = atoi(t);	if (N.pings_recv == 0)	    continue;	/* give this measurement low weight */	N.pings_sent = 1;	N.pings_recv = 1;	if ((t = strtok(NULL, w_space)) == NULL)	    continue;	N.hops = atof(t);	if ((t = strtok(NULL, w_space)) == NULL)	    continue;	N.rtt = atof(t);	if ((t = strtok(NULL, w_space)) == NULL)	    continue;	N.next_ping_time = (time_t) atoi(t);	if ((t = strtok(NULL, w_space)) == NULL)	    continue;	N.last_use_time = (time_t) atoi(t);	n = memAllocate(MEM_NETDBENTRY);	xmemcpy(n, &N, sizeof(netdbEntry));	netdbHashInsert(n, addr);	while ((t = strtok(NULL, w_space)) != NULL) {	    if (netdbLookupHost(t) != NULL)	/* no dups! */		continue;	    netdbHostInsert(n, t);	}	count++;    }    memFree(buf, MEM_4K_BUF);    fclose(fp);    getCurrentTime();    debug(38, 1) ("NETDB state reloaded; %d entries, %d msec\n",	count, tvSubMsec(start, current_time));}static char *netdbPeerName(const char *name){    wordlist *w;    for (w = peer_names; w; w = w->next) {	if (!strcmp(w->key, name))	    return w->key;    }    w = wordlistAdd(&peer_names, name);    return w->key;}static voidnetdbFreeNetdbEntry(void *data){    netdbEntry *n = data;    safe_free(n->peers);    memFree(n, MEM_NETDBENTRY);}static voidnetdbFreeNameEntry(void *data){    net_db_name *x = data;    xfree(x->name);    memFree(x, MEM_NET_DB_NAME);}static voidnetdbExchangeHandleReply(void *data, char *buf, ssize_t size){    netdbExchangeState *ex = data;    int rec_sz = 0;    off_t o;    struct in_addr addr;    double rtt;    double hops;    char *p;    int j;    HttpReply *rep;    size_t hdr_sz;    int nused = 0;

⌨️ 快捷键说明

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