📄 ipcache.c
字号:
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 + -