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

📄 ipcache.c

📁 -
💻 C
📖 第 1 页 / 共 2 页
字号:
    cbdataAdd(c, cbdataXfree, 0);    i->status = IP_DISPATCHED;    ipcacheLockEntry(i);    dnsSubmit(i->name, ipcacheHandleReply, c);}/* initialize the ipcache */voidipcache_init(void){    int n;    debug(14, 3) ("Initializing IP Cache...\n");    memset(&IpcacheStats, '\0', sizeof(IpcacheStats));    memset(&lru_list, '\0', sizeof(lru_list));    /* test naming lookup */    if (!opt_dns_tests) {	debug(14, 4) ("ipcache_init: Skipping DNS name lookup tests.\n");    } else if (!ipcache_testname()) {	fatal("ipcache_init: DNS name lookup tests failed.");    } else {	debug(14, 1) ("Successful DNS name lookup tests...\n");    }    memset(&static_addrs, '\0', sizeof(ipcache_addrs));    static_addrs.in_addrs = xcalloc(1, sizeof(struct in_addr));    static_addrs.bad_mask = xcalloc(1, sizeof(unsigned char));    ipcache_high = (long) (((float) Config.ipcache.size *	    (float) Config.ipcache.high) / (float) 100);    ipcache_low = (long) (((float) Config.ipcache.size *	    (float) Config.ipcache.low) / (float) 100);    n = hashPrime(ipcache_high / 4);    ip_table = hash_create((HASHCMP *) strcmp, n, hash4);    cachemgrRegister("ipcache",	"IP Cache Stats and Contents",	stat_ipcache_get, 0, 1);}intipcacheUnregister(const char *name, void *data){    ipcache_entry *i = NULL;    ip_pending *p = NULL;    int n = 0;    debug(14, 3) ("ipcacheUnregister: name '%s'\n", name);    if ((i = ipcache_get(name)) == NULL)	return 0;    if (i->status == IP_PENDING || i->status == IP_DISPATCHED) {	for (p = i->pending_head; p; p = p->next) {	    if (p->handlerData != data)		continue;	    p->handler = NULL;	    n++;	}    }    assert(n > 0);    debug(14, 3) ("ipcacheUnregister: unregistered %d handlers\n", n);    return n;}const ipcache_addrs *ipcache_gethostbyname(const char *name, int flags){    ipcache_entry *i = NULL;    ipcache_addrs *addrs;    if (!name)	fatal_dump("ipcache_gethostbyname: NULL name");    debug(14, 3) ("ipcache_gethostbyname: '%s', flags=%x\n", name, flags);    IpcacheStats.requests++;    if ((i = ipcache_get(name))) {	if (ipcacheExpiredEntry(i)) {	    ipcache_release(i);	    i = NULL;	}    }    if (i) {	if (i->status == IP_NEGATIVE_CACHED) {	    IpcacheStats.negative_hits++;	    dns_error_message = i->error_message;	    return NULL;	} else if (i->addrs.count == 0) {	    (void) 0;	} else {	    IpcacheStats.hits++;	    i->lastref = squid_curtime;	    return &i->addrs;	}    }    if ((addrs = ipcacheCheckNumeric(name)))	return addrs;    IpcacheStats.misses++;    if (flags & IP_LOOKUP_IF_MISS)	ipcache_nbgethostbyname(name, dummy_handler, NULL);    return NULL;}static voidipcacheStatPrint(ipcache_entry * i, StoreEntry * sentry){    int k;    storeAppendPrintf(sentry, " %-32.32s  %c%c %6d %6d %2d(%2d)",	i->name,	ipcache_status_char[i->status],	i->locks ? 'L' : ' ',	(int) (squid_curtime - i->lastref),	(int) (i->expires - squid_curtime),	(int) i->addrs.count,	(int) i->addrs.badcount);    for (k = 0; k < (int) i->addrs.count; k++) {	storeAppendPrintf(sentry, " %15s-%3s", inet_ntoa(i->addrs.in_addrs[k]),	    i->addrs.bad_mask[k] ? "BAD" : "OK ");    }    storeAppendPrintf(sentry, "\n");}/* process objects list */voidstat_ipcache_get(StoreEntry * sentry){    dlink_node *m;    assert(ip_table != NULL);    storeAppendPrintf(sentry, "IP Cache Statistics:\n");    storeAppendPrintf(sentry, "IPcache Entries: %d\n",	memInUse(MEM_IPCACHE_ENTRY));    storeAppendPrintf(sentry, "IPcache Requests: %d\n",	IpcacheStats.requests);    storeAppendPrintf(sentry, "IPcache Hits: %d\n",	IpcacheStats.hits);    storeAppendPrintf(sentry, "IPcache Pending Hits: %d\n",	IpcacheStats.pending_hits);    storeAppendPrintf(sentry, "IPcache Negative Hits: %d\n",	IpcacheStats.negative_hits);    storeAppendPrintf(sentry, "IPcache Misses: %d\n",	IpcacheStats.misses);    storeAppendPrintf(sentry, "Blocking calls to gethostbyname(): %d\n",	IpcacheStats.ghbn_calls);    storeAppendPrintf(sentry, "Attempts to release locked entries: %d\n",	IpcacheStats.release_locked);    storeAppendPrintf(sentry, "\n\n");    storeAppendPrintf(sentry, "IP Cache Contents:\n\n");    storeAppendPrintf(sentry, " %-29.29s %5s %6s %6s %1s\n",	"Hostname",	"Flags",	"lstref",	"TTL",	"N");    for (m = lru_list.head; m; m = m->next)	ipcacheStatPrint(m->data, sentry);}static voiddummy_handler(const ipcache_addrs * addrsnotused, void *datanotused){    return;}voidipcacheReleaseInvalid(const char *name){    ipcache_entry *i;    if (NULL == name) {	debug(14, 1) ("ipcacheReleaseInvalid: NULL name\n");	return;    }    if (0 == strlen(name)) {	debug(14, 1) ("ipcacheReleaseInvalid: Empty name\n");	return;    }    if ((i = ipcache_get(name)) == NULL)	return;    if (i->status != IP_NEGATIVE_CACHED)	return;    ipcache_release(i);}voidipcacheInvalidate(const char *name){    ipcache_entry *i;    if ((i = ipcache_get(name)) == NULL)	return;    i->expires = squid_curtime;    /* NOTE, don't call ipcache_release here becuase we might be here due     * to a thread started from ipcache_call_pending() which will cause a     * FMR */}ipcache_addrs *ipcacheCheckNumeric(const char *name){    struct in_addr ip;    /* check if it's already a IP address in text form. */    if (!safe_inet_addr(name, &ip))	return NULL;    static_addrs.count = 1;    static_addrs.cur = 0;    static_addrs.in_addrs[0].s_addr = ip.s_addr;    static_addrs.bad_mask[0] = FALSE;    static_addrs.badcount = 0;    return &static_addrs;}static voidipcacheLockEntry(ipcache_entry * i){    if (i->locks++ == 0) {	dlinkDelete(&i->lru, &lru_list);	dlinkAdd(i, &i->lru, &lru_list);    }}static voidipcacheUnlockEntry(ipcache_entry * i){    assert(i->locks > 0);    i->locks--;    if (ipcacheExpiredEntry(i))	ipcache_release(i);}voidipcacheCycleAddr(const char *name, ipcache_addrs * ia){    ipcache_entry *i;    unsigned char k;    assert(name || ia);    if (NULL == ia) {	if ((i = ipcache_get(name)) == NULL)	    return;	if (i->status != IP_CACHED)	    return;	ia = &i->addrs;    }    for (k = 0; k < ia->count; k++) {	if (++ia->cur == ia->count)	    ia->cur = 0;	if (!ia->bad_mask[ia->cur])	    break;;    }    if (k == ia->count) {	/* All bad, reset to All good */	debug(14, 3) ("ipcacheCycleAddr: Changing ALL %s addrs from BAD to OK\n",	    name);	for (k = 0; k < ia->count; k++)	    ia->bad_mask[k] = 0;	ia->badcount = 0;	ia->cur = 0;    }    debug(14, 3) ("ipcacheCycleAddr: %s now at %s\n", name,	inet_ntoa(ia->in_addrs[ia->cur]));}/* * Marks the given address as BAD and calls ipcacheCycleAddr to * advance the current pointer to the next OK address. */voidipcacheMarkBadAddr(const char *name, struct in_addr addr){    ipcache_entry *i;    ipcache_addrs *ia;    int k;    if ((i = ipcache_get(name)) == NULL)	return;    ia = &i->addrs;    for (k = 0; k < (int) ia->count; k++) {	if (ia->in_addrs[k].s_addr == addr.s_addr)	    break;    }    if (k == (int) ia->count)	/* not found */	return;    if (!ia->bad_mask[k]) {	ia->bad_mask[k] = TRUE;	ia->badcount++;	debug(14, 2) ("ipcacheMarkBadAddr: %s [%s]\n", name, inet_ntoa(addr));    }    ipcacheCycleAddr(name, ia);}voidipcacheMarkGoodAddr(const char *name, struct in_addr addr){    ipcache_entry *i;    ipcache_addrs *ia;    int k;    if ((i = ipcache_get(name)) == NULL)	return;    ia = &i->addrs;    for (k = 0; k < (int) ia->count; k++) {	if (ia->in_addrs[k].s_addr == addr.s_addr)	    break;    }    if (k == (int) ia->count)	/* not found */	return;    if (!ia->bad_mask[k])	/* already OK */	return;    ia->bad_mask[k] = FALSE;    ia->badcount--;    debug(14, 2) ("ipcacheMarkGoodAddr: %s [%s]\n", name, inet_ntoa(addr));}static voidipcacheFreeEntry(void *data){    ipcache_entry *i = data;    ip_pending *p;    while ((p = i->pending_head)) {	i->pending_head = p->next;	memFree(p, MEM_IPCACHE_PENDING);    }    safe_free(i->addrs.in_addrs);    safe_free(i->addrs.bad_mask);    safe_free(i->name);    safe_free(i->error_message);    memFree(i, MEM_IPCACHE_ENTRY);}voidipcacheFreeMemory(void){    hashFreeItems(ip_table, ipcacheFreeEntry);    hashFreeMemory(ip_table);    ip_table = NULL;}static voidipcacheChangeKey(ipcache_entry * i){    static int index = 0;    LOCAL_ARRAY(char, new_key, 256);    hash_link *table_entry = hash_lookup(ip_table, i->name);    if (table_entry == NULL) {	debug(14, 0) ("ipcacheChangeKey: Could not find key '%s'\n", i->name);	return;    }    assert(i == (ipcache_entry *) table_entry);    hash_remove_link(ip_table, table_entry);    snprintf(new_key, 256, "%d/%s", ++index, i->name);    debug(14, 1) ("ipcacheChangeKey: from '%s' to '%s'\n", i->name, new_key);    safe_free(i->name);    i->name = xstrdup(new_key);    hash_join(ip_table, (hash_link *) i);}/* call during reconfigure phase to clear out all the  * pending and dispatched reqeusts that got lost */voidipcache_restart(void){    ipcache_entry *this;    assert(ip_table != NULL);    hash_first(ip_table);    while ((this = (ipcache_entry *) hash_next(ip_table))) {	if (this->status == IP_CACHED)	    continue;	if (this->status == IP_NEGATIVE_CACHED)	    continue;    }    /* recalculate these while we're at it */    ipcache_high = (long) (((float) Config.ipcache.size *	    (float) Config.ipcache.high) / (float) 100);    ipcache_low = (long) (((float) Config.ipcache.size *	    (float) Config.ipcache.low) / (float) 100);}#ifdef SQUID_SNMP/* * The function to return the ip cache statistics to via SNMP */variable_list *snmp_netIpFn(variable_list * Var, snint * ErrP){    variable_list *Answer;    debug(49, 5) ("snmp_netIpFn: Processing request:\n", Var->name[LEN_SQ_NET + 1]);    snmpDebugOid(5, Var->name, Var->name_length);    Answer = snmp_var_new(Var->name, Var->name_length);    *ErrP = SNMP_ERR_NOERROR;    Answer->val_len = sizeof(snint);    Answer->val.integer = xmalloc(Answer->val_len);    Answer->type = SMI_COUNTER32;    switch (Var->name[LEN_SQ_NET + 1]) {    case IP_ENT:	*(Answer->val.integer) = memInUse(MEM_IPCACHE_ENTRY);	Answer->type = SMI_GAUGE32;	break;    case IP_REQ:	*(Answer->val.integer) = IpcacheStats.requests;	break;    case IP_HITS:	*(Answer->val.integer) = IpcacheStats.hits;	break;    case IP_PENDHIT:	*(Answer->val.integer) = IpcacheStats.pending_hits;	Answer->type = SMI_GAUGE32;	break;    case IP_NEGHIT:	*(Answer->val.integer) = IpcacheStats.negative_hits;	break;    case IP_MISS:	*(Answer->val.integer) = IpcacheStats.misses;	break;    case IP_GHBN:	*(Answer->val.integer) = IpcacheStats.ghbn_calls;	break;    case IP_LOC:	*(Answer->val.integer) = IpcacheStats.release_locked;	break;    default:	*ErrP = SNMP_ERR_NOSUCHNAME;	snmp_var_free(Answer);	return (NULL);    }    return Answer;}#endif /*SQUID_SNMP */

⌨️ 快捷键说明

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