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

📄 fqdncache.c

📁 -
💻 C
📖 第 1 页 / 共 2 页
字号:
/* * $Id: fqdncache.c,v 1.126 1998/12/05 00:54:24 wessels Exp $ * * DEBUG: section 35    FQDN Cache * 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"#define FQDN_LOW_WATER       90#define FQDN_HIGH_WATER      95static struct {    int requests;    int replies;    int hits;    int misses;    int pending_hits;    int negative_hits;    int errors;    int ghba_calls;		/* # calls to blocking gethostbyaddr() */} FqdncacheStats;static dlink_list lru_list;static HLPCB fqdncacheHandleReply;static fqdncache_entry *fqdncacheParse(const char *buf);static void fqdncache_release(fqdncache_entry *);static fqdncache_entry *fqdncache_create(const char *name);static void fqdncache_call_pending(fqdncache_entry *);static void fqdncacheAddHostent(fqdncache_entry *, const struct hostent *);static fqdncache_entry *fqdncache_get(const char *);static FQDNH dummy_handler;static int fqdncacheExpiredEntry(const fqdncache_entry *);static void fqdncacheAddPending(fqdncache_entry *, FQDNH *, void *);static void fqdncacheChangeKey(fqdncache_entry * i);static void fqdncacheLockEntry(fqdncache_entry * f);static void fqdncacheUnlockEntry(fqdncache_entry * f);static FREE fqdncacheFreeEntry;static hash_table *fqdn_table = NULL;static char fqdncache_status_char[] ={    'C',    'N',    'P',    'D'};static long fqdncache_low = 180;static long fqdncache_high = 200;/* removes the given fqdncache entry */static voidfqdncache_release(fqdncache_entry * f){    int k;    assert(f->status != FQDN_PENDING);    assert(f->status != FQDN_DISPATCHED);    assert(f->pending_head == NULL);    hash_remove_link(fqdn_table, (hash_link *) f);    if (f->status == FQDN_CACHED) {	for (k = 0; k < (int) f->name_count; k++)	    safe_free(f->names[k]);	debug(35, 5) ("fqdncache_release: Released FQDN record for '%s'.\n",	    f->name);    }    dlinkDelete(&f->lru, &lru_list);    safe_free(f->name);    safe_free(f->error_message);    memFree(f, MEM_FQDNCACHE_ENTRY);}/* return match for given name */static fqdncache_entry *fqdncache_get(const char *name){    hash_link *e;    static fqdncache_entry *f;    f = NULL;    if (fqdn_table) {	if ((e = hash_lookup(fqdn_table, name)) != NULL)	    f = (fqdncache_entry *) e;    }    return f;}static intfqdncacheExpiredEntry(const fqdncache_entry * f){    if (f->status == FQDN_PENDING)	return 0;    if (f->status == FQDN_DISPATCHED)	return 0;    if (f->locks != 0)	return 0;    if (f->expires > squid_curtime)	return 0;    return 1;}voidfqdncache_purgelru(void *notused){    dlink_node *m;    dlink_node *prev = NULL;    fqdncache_entry *f;    int removed = 0;    eventAdd("fqdncache_purgelru", fqdncache_purgelru, NULL, 10.0, 1);    for (m = lru_list.tail; m; m = prev) {	if (memInUse(MEM_FQDNCACHE_ENTRY) < fqdncache_low)	    break;	prev = m->prev;	f = m->data;	if (f->status == FQDN_PENDING)	    continue;	if (f->status == FQDN_DISPATCHED)	    continue;	if (f->locks != 0)	    continue;	fqdncache_release(f);	removed++;    }    debug(35, 9) ("fqdncache_purgelru: removed %d entries\n", removed);}/* create blank fqdncache_entry */static fqdncache_entry *fqdncache_create(const char *name){    static fqdncache_entry *f;    f = memAllocate(MEM_FQDNCACHE_ENTRY);    f->name = xstrdup(name);    f->expires = squid_curtime + Config.negativeDnsTtl;    hash_join(fqdn_table, (hash_link *) f);    dlinkAdd(f, &f->lru, &lru_list);    return f;}static voidfqdncacheAddHostent(fqdncache_entry * f, const struct hostent *hp){    int k;    f->name_count = 0;    f->names[f->name_count++] = xstrdup((char *) hp->h_name);    for (k = 0; hp->h_aliases[k]; k++) {	f->names[f->name_count++] = xstrdup(hp->h_aliases[k]);	if (f->name_count == FQDN_MAX_NAMES)	    break;    }}static fqdncache_entry *fqdncacheAddNew(const char *name, const struct hostent *hp, fqdncache_status_t status){    fqdncache_entry *f;    assert(fqdncache_get(name) == NULL);    debug(35, 10) ("fqdncacheAddNew: Adding '%s', status=%c\n",	name,	fqdncache_status_char[status]);    f = fqdncache_create(name);    if (hp)	fqdncacheAddHostent(f, hp);    f->status = status;    f->lastref = squid_curtime;    return f;}/* walks down the pending list, calling handlers */static voidfqdncache_call_pending(fqdncache_entry * f){    fqdn_pending *p = NULL;    int nhandler = 0;    f->lastref = squid_curtime;    fqdncacheLockEntry(f);    while (f->pending_head != NULL) {	p = f->pending_head;	f->pending_head = p->next;	if (p->handler) {	    nhandler++;	    dns_error_message = f->error_message;	    p->handler((f->status == FQDN_CACHED) ? f->names[0] : NULL,		p->handlerData);	}	memFree(p, MEM_FQDNCACHE_PENDING);    }    f->pending_head = NULL;	/* nuke list */    debug(35, 10) ("fqdncache_call_pending: Called %d handlers.\n", nhandler);    fqdncacheUnlockEntry(f);}static fqdncache_entry *fqdncacheParse(const char *inbuf){    LOCAL_ARRAY(char, buf, DNS_INBUF_SZ);    char *token;    static fqdncache_entry f;    int ttl;    xstrncpy(buf, inbuf, DNS_INBUF_SZ);    debug(35, 5) ("fqdncacheParse: parsing: {%s}\n", buf);    memset(&f, '\0', sizeof(f));    f.expires = squid_curtime;    f.status = FQDN_NEGATIVE_CACHED;    if (inbuf == NULL) {	debug(35, 1) ("fqdncacheParse: Got <NULL> reply\n");	return &f;    }    token = strtok(buf, w_space);    if (NULL == token) {	debug(35, 1) ("fqdncacheParse: Got <NULL>, expecting '$name'\n");	return &f;    }    if (0 == strcmp(token, "$fail")) {	f.expires = squid_curtime + Config.negativeDnsTtl;	token = strtok(NULL, "\n");	assert(NULL != token);	f.error_message = xstrdup(token);	return &f;    }    if (0 != strcmp(token, "$name")) {	debug(35, 1) ("fqdncacheParse: Got '%s', expecting '$name'\n", token);	return &f;    }    token = strtok(NULL, w_space);    if (NULL == token) {	debug(35, 1) ("fqdncacheParse: Got <NULL>, expecting TTL\n");	return &f;    }    f.status = FQDN_CACHED;    ttl = atoi(token);    if (ttl > 0)	f.expires = squid_curtime + ttl;    else	f.expires = squid_curtime + Config.positiveDnsTtl;    token = strtok(NULL, w_space);    if (NULL != token) {	f.names[0] = xstrdup(token);	f.name_count = 1;    }    return &f;}static voidfqdncacheHandleReply(void *data, char *reply){    int n;    generic_cbdata *c = data;    fqdncache_entry *f = c->data;    fqdncache_entry *x = NULL;    assert(f->status == FQDN_DISPATCHED);    assert(f->locks);    cbdataFree(c);    c = NULL;    n = ++FqdncacheStats.replies;    statHistCount(&Counter.dns.svc_time,	tvSubMsec(f->request_time, current_time));    x = fqdncacheParse(reply);    assert(x);    f->name_count = x->name_count;    for (n = 0; n < (int) f->name_count; n++)	f->names[n] = x->names[n];    f->error_message = x->error_message;    f->status = x->status;    f->expires = x->expires;    fqdncache_call_pending(f);    fqdncacheUnlockEntry(f);	/* unlock from FQDN_DISPATCHED */}static voidfqdncacheAddPending(fqdncache_entry * f, FQDNH * handler, void *handlerData){    fqdn_pending *pending = memAllocate(MEM_FQDNCACHE_PENDING);    fqdn_pending **I = NULL;    f->lastref = squid_curtime;    pending->handler = handler;    pending->handlerData = handlerData;    for (I = &(f->pending_head); *I; I = &((*I)->next));    *I = pending;}voidfqdncache_nbgethostbyaddr(struct in_addr addr, FQDNH * handler, void *handlerData){    fqdncache_entry *f = NULL;    char *name = inet_ntoa(addr);    generic_cbdata *c;    assert(handler);    debug(35, 4) ("fqdncache_nbgethostbyaddr: Name '%s'.\n", name);    FqdncacheStats.requests++;    if (name == NULL || name[0] == '\0') {	debug(35, 4) ("fqdncache_nbgethostbyaddr: Invalid name!\n");	handler(NULL, handlerData);	return;    }    if ((f = fqdncache_get(name))) {	if (fqdncacheExpiredEntry(f)) {	    fqdncache_release(f);	    f = NULL;	}    }    if (f == NULL) {	/* MISS: No entry, create the new one */	debug(35, 5) ("fqdncache_nbgethostbyaddr: MISS for '%s'\n", name);

⌨️ 快捷键说明

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