📄 fqdncache.c
字号:
FqdncacheStats.misses++; f = fqdncacheAddNew(name, NULL, FQDN_PENDING); fqdncacheAddPending(f, handler, handlerData); f->request_time = current_time; } else if (f->status == FQDN_CACHED || f->status == FQDN_NEGATIVE_CACHED) { /* HIT */ debug(35, 4) ("fqdncache_nbgethostbyaddr: HIT for '%s'\n", name); if (f->status == FQDN_NEGATIVE_CACHED) FqdncacheStats.negative_hits++; else FqdncacheStats.hits++; fqdncacheAddPending(f, handler, handlerData); fqdncache_call_pending(f); return; } else if (f->status == FQDN_PENDING || f->status == FQDN_DISPATCHED) { debug(35, 4) ("fqdncache_nbgethostbyaddr: PENDING for '%s'\n", name); FqdncacheStats.pending_hits++; fqdncacheAddPending(f, handler, handlerData); if (squid_curtime - f->expires > 600) { debug(35, 0) ("fqdncache_nbgethostbyname: '%s' PENDING for %d seconds, aborting\n", name, (int) (squid_curtime + Config.negativeDnsTtl - f->expires)); fqdncacheChangeKey(f); fqdncache_call_pending(f); } return; } else { debug(35, 1) ("fqdncache_nbgethostbyaddr: BAD status %d", (int) f->status); assert(0); } /* for HIT, PENDING, DISPATCHED we've returned. For MISS we submit */ c = xcalloc(1, sizeof(*c)); c->data = f; cbdataAdd(c, cbdataXfree, 0); f->status = FQDN_DISPATCHED; fqdncacheLockEntry(f); /* lock while FQDN_DISPATCHED */ dnsSubmit(f->name, fqdncacheHandleReply, c);}/* initialize the fqdncache */voidfqdncache_init(void){ int n; if (fqdn_table) return; debug(35, 3) ("Initializing FQDN Cache...\n"); memset(&FqdncacheStats, '\0', sizeof(FqdncacheStats)); memset(&lru_list, '\0', sizeof(lru_list)); fqdncache_high = (long) (((float) Config.fqdncache.size * (float) FQDN_HIGH_WATER) / (float) 100); fqdncache_low = (long) (((float) Config.fqdncache.size * (float) FQDN_LOW_WATER) / (float) 100); n = hashPrime(fqdncache_high / 4); fqdn_table = hash_create((HASHCMP *) strcmp, n, hash4); cachemgrRegister("fqdncache", "FQDN Cache Stats and Contents", fqdnStats, 0, 1);}/* clean up the pending entries in dnsserver *//* return 1 if we found the host, 0 otherwise */intfqdncacheUnregister(struct in_addr addr, void *data){ char *name = inet_ntoa(addr); fqdncache_entry *f = NULL; fqdn_pending *p = NULL; int n = 0; debug(35, 3) ("fqdncacheUnregister: name '%s'\n", name); if ((f = fqdncache_get(name)) == NULL) return 0; if (f->status == FQDN_PENDING || f->status == FQDN_DISPATCHED) { for (p = f->pending_head; p; p = p->next) { if (p->handlerData != data) continue; p->handler = NULL; n++; } } if (n == 0) debug_trap("fqdncacheUnregister: callback data not found"); debug(35, 3) ("fqdncacheUnregister: unregistered %d handlers\n", n); return n;}const char *fqdncache_gethostbyaddr(struct in_addr addr, int flags){ char *name = inet_ntoa(addr); fqdncache_entry *f = NULL; struct in_addr ip; assert(name); FqdncacheStats.requests++; if ((f = fqdncache_get(name))) { if (fqdncacheExpiredEntry(f)) { fqdncache_release(f); f = NULL; } } if (f) { if (f->status == FQDN_NEGATIVE_CACHED) { FqdncacheStats.negative_hits++; dns_error_message = f->error_message; return NULL; } else { FqdncacheStats.hits++; f->lastref = squid_curtime; return f->names[0]; } } /* check if it's already a FQDN address in text form. */ if (!safe_inet_addr(name, &ip)) return name; FqdncacheStats.misses++; if (flags & FQDN_LOOKUP_IF_MISS) fqdncache_nbgethostbyaddr(addr, dummy_handler, NULL); return NULL;}/* process objects list */voidfqdnStats(StoreEntry * sentry){ fqdncache_entry *f = NULL; int k; int ttl; if (fqdn_table == NULL) return; storeAppendPrintf(sentry, "FQDN Cache Statistics:\n"); storeAppendPrintf(sentry, "FQDNcache Entries: %d\n", memInUse(MEM_FQDNCACHE_ENTRY)); storeAppendPrintf(sentry, "FQDNcache Requests: %d\n", FqdncacheStats.requests); storeAppendPrintf(sentry, "FQDNcache Hits: %d\n", FqdncacheStats.hits); storeAppendPrintf(sentry, "FQDNcache Pending Hits: %d\n", FqdncacheStats.pending_hits); storeAppendPrintf(sentry, "FQDNcache Negative Hits: %d\n", FqdncacheStats.negative_hits); storeAppendPrintf(sentry, "FQDNcache Misses: %d\n", FqdncacheStats.misses); storeAppendPrintf(sentry, "Blocking calls to gethostbyaddr(): %d\n", FqdncacheStats.ghba_calls); storeAppendPrintf(sentry, "FQDN Cache Contents:\n\n"); hash_first(fqdn_table); while ((f = (fqdncache_entry *) hash_next(fqdn_table))) { if (f->status == FQDN_PENDING || f->status == FQDN_DISPATCHED) ttl = 0; else ttl = (f->expires - squid_curtime); storeAppendPrintf(sentry, " %-32.32s %c %6d %d", f->name, fqdncache_status_char[f->status], ttl, (int) f->name_count); for (k = 0; k < (int) f->name_count; k++) storeAppendPrintf(sentry, " %s", f->names[k]); storeAppendPrintf(sentry, "\n"); }}static voiddummy_handler(const char *bufnotused, void *datanotused){ return;}voidfqdncacheReleaseInvalid(const char *name){ fqdncache_entry *f; if ((f = fqdncache_get(name)) == NULL) return; if (f->status != FQDN_NEGATIVE_CACHED) return; fqdncache_release(f);}const char *fqdnFromAddr(struct in_addr addr){ const char *n; static char buf[32]; if (Config.onoff.log_fqdn && (n = fqdncache_gethostbyaddr(addr, 0))) return n; xstrncpy(buf, inet_ntoa(addr), 32); return buf;}static voidfqdncacheLockEntry(fqdncache_entry * f){ if (f->locks++ == 0) { dlinkDelete(&f->lru, &lru_list); dlinkAdd(f, &f->lru, &lru_list); }}static voidfqdncacheUnlockEntry(fqdncache_entry * f){ if (f->locks == 0) { debug_trap("fqdncacheUnlockEntry: Entry has no locks"); return; } f->locks--; if (fqdncacheExpiredEntry(f)) fqdncache_release(f);}static voidfqdncacheFreeEntry(void *data){ fqdncache_entry *f = data; fqdn_pending *p = NULL; int k; while ((p = f->pending_head)) { f->pending_head = p->next; memFree(p, MEM_FQDNCACHE_PENDING); } for (k = 0; k < (int) f->name_count; k++) safe_free(f->names[k]); safe_free(f->name); safe_free(f->error_message); memFree(f, MEM_FQDNCACHE_ENTRY);}voidfqdncacheFreeMemory(void){ hashFreeItems(fqdn_table, fqdncacheFreeEntry); hashFreeMemory(fqdn_table); fqdn_table = NULL;}static voidfqdncacheChangeKey(fqdncache_entry * f){ static int index = 0; LOCAL_ARRAY(char, new_key, 256); hash_link *table_entry = hash_lookup(fqdn_table, f->name); if (table_entry == NULL) { debug(35, 0) ("fqdncacheChangeKey: Could not find key '%s'\n", f->name); return; } if (f != (fqdncache_entry *) table_entry) { debug_trap("fqdncacheChangeKey: f != table_entry!"); return; } hash_remove_link(fqdn_table, table_entry); snprintf(new_key, 256, "%d/", ++index); strncat(new_key, f->name, 128); debug(35, 1) ("fqdncacheChangeKey: from '%s' to '%s'\n", f->name, new_key); safe_free(f->name); f->name = xstrdup(new_key); hash_join(fqdn_table, (hash_link *) f);}/* call during reconfigure phase to clear out all the * pending and dispatched reqeusts that got lost */voidfqdncache_restart(void){ fqdncache_entry *this; assert(fqdn_table); hash_first(fqdn_table); while ((this = (fqdncache_entry *) hash_next(fqdn_table))) { if (this->status == FQDN_CACHED) continue; if (this->status == FQDN_NEGATIVE_CACHED) continue; } fqdncache_high = (long) (((float) Config.fqdncache.size * (float) FQDN_HIGH_WATER) / (float) 100); fqdncache_low = (long) (((float) Config.fqdncache.size * (float) FQDN_LOW_WATER) / (float) 100);}#ifdef SQUID_SNMP/* * The function to return the fqdn statistics via SNMP */variable_list *snmp_netFqdnFn(variable_list * Var, snint * ErrP){ variable_list *Answer; debug(49, 5) ("snmp_netFqdnFn: 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 FQDN_ENT: *(Answer->val.integer) = memInUse(MEM_FQDNCACHE_ENTRY); Answer->type = SMI_GAUGE32; break; case FQDN_REQ: *(Answer->val.integer) = FqdncacheStats.requests; break; case FQDN_HITS: *(Answer->val.integer) = FqdncacheStats.hits; break; case FQDN_PENDHIT: *(Answer->val.integer) = FqdncacheStats.pending_hits; Answer->type = SMI_GAUGE32; break; case FQDN_NEGHIT: *(Answer->val.integer) = FqdncacheStats.negative_hits; break; case FQDN_MISS: *(Answer->val.integer) = FqdncacheStats.misses; break; case FQDN_GHBN: *(Answer->val.integer) = FqdncacheStats.ghba_calls; 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 + -