]> git.ipfire.org Git - thirdparty/squid.git/blame - src/fqdncache.cc
DW:
[thirdparty/squid.git] / src / fqdncache.cc
CommitLineData
f88bb09c 1
2/*
58cd5bbd 3 * $Id: fqdncache.cc,v 1.141 2000/10/17 08:06:03 adrian Exp $
f88bb09c 4 *
7cf620a9 5 * DEBUG: section 35 FQDN Cache
f88bb09c 6 * AUTHOR: Harvest Derived
7 *
42c04c16 8 * SQUID Internet Object Cache http://squid.nlanr.net/Squid/
e25c139f 9 * ----------------------------------------------------------
f88bb09c 10 *
11 * Squid is the result of efforts by numerous individuals from the
12 * Internet community. Development is led by Duane Wessels of the
e25c139f 13 * National Laboratory for Applied Network Research and funded by the
14 * National Science Foundation. Squid is Copyrighted (C) 1998 by
efd900cb 15 * the Regents of the University of California. Please see the
16 * COPYRIGHT file for full details. Squid incorporates software
17 * developed and/or copyrighted by other sources. Please see the
18 * CREDITS file for full details.
f88bb09c 19 *
20 * This program is free software; you can redistribute it and/or modify
21 * it under the terms of the GNU General Public License as published by
22 * the Free Software Foundation; either version 2 of the License, or
23 * (at your option) any later version.
24 *
25 * This program is distributed in the hope that it will be useful,
26 * but WITHOUT ANY WARRANTY; without even the implied warranty of
27 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
28 * GNU General Public License for more details.
29 *
30 * You should have received a copy of the GNU General Public License
31 * along with this program; if not, write to the Free Software
cbdec147 32 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111, USA.
e25c139f 33 *
f88bb09c 34 */
35
36#include "squid.h"
37
f88bb09c 38#define FQDN_LOW_WATER 90
39#define FQDN_HIGH_WATER 95
f88bb09c 40
add5d21f 41typedef struct _fqdncache_entry fqdncache_entry;
42
43struct _fqdncache_entry {
44 /* first two items must be equivalent to hash_link */
45 char *name;
46 fqdncache_entry *next;
47 time_t lastref;
48 time_t expires;
49 unsigned char name_count;
50 char *names[FQDN_MAX_NAMES + 1];
51 FQDNH *handler;
52 void *handlerData;
53 char *error_message;
54 struct timeval request_time;
55 dlink_node lru;
ac06f720 56 unsigned short locks;
add5d21f 57 struct {
58 unsigned int negcached:1;
59 } flags;
60};
61
f88bb09c 62static struct {
63 int requests;
64 int replies;
65 int hits;
66 int misses;
f88bb09c 67 int negative_hits;
68 int errors;
f88bb09c 69 int ghba_calls; /* # calls to blocking gethostbyaddr() */
70} FqdncacheStats;
71
4bc76d59 72static dlink_list lru_list;
73
59f34d62 74#if USE_DNSSERVERS
74addf6c 75static HLPCB fqdncacheHandleReply;
76static fqdncache_entry *fqdncacheParse(const char *buf);
59f34d62 77#else
78static IDNSCB fqdncacheHandleReply;
79static fqdncache_entry *fqdncacheParse(rfc1035_rr *, int);
80#endif
add5d21f 81static void fqdncacheRelease(fqdncache_entry *);
82static fqdncache_entry *fqdncacheCreateEntry(const char *name);
83static void fqdncacheCallback(fqdncache_entry *);
f5b8bbc4 84static fqdncache_entry *fqdncache_get(const char *);
348b2031 85static FQDNH dummy_handler;
f5b8bbc4 86static int fqdncacheExpiredEntry(const fqdncache_entry *);
f5b8bbc4 87static void fqdncacheLockEntry(fqdncache_entry * f);
88static void fqdncacheUnlockEntry(fqdncache_entry * f);
ec878047 89static FREE fqdncacheFreeEntry;
add5d21f 90static void fqdncacheAddEntry(fqdncache_entry * f);
f88bb09c 91
365e5b34 92static hash_table *fqdn_table = NULL;
f88bb09c 93
24382924 94static long fqdncache_low = 180;
95static long fqdncache_high = 200;
f88bb09c 96
f88bb09c 97/* removes the given fqdncache entry */
b8d8561b 98static void
add5d21f 99fqdncacheRelease(fqdncache_entry * f)
f88bb09c 100{
f88bb09c 101 int k;
3fda0827 102 hash_remove_link(fqdn_table, (hash_link *) f);
add5d21f 103 for (k = 0; k < (int) f->name_count; k++)
104 safe_free(f->names[k]);
105 debug(35, 5) ("fqdncacheRelease: Released FQDN record for '%s'.\n",
106 f->name);
4bc76d59 107 dlinkDelete(&f->lru, &lru_list);
429fdbec 108 safe_free(f->name);
109 safe_free(f->error_message);
db1cd23c 110 memFree(f, MEM_FQDNCACHE_ENTRY);
f88bb09c 111}
112
113/* return match for given name */
b8d8561b 114static fqdncache_entry *
0ee4272b 115fqdncache_get(const char *name)
f88bb09c 116{
117 hash_link *e;
118 static fqdncache_entry *f;
f88bb09c 119 f = NULL;
120 if (fqdn_table) {
121 if ((e = hash_lookup(fqdn_table, name)) != NULL)
122 f = (fqdncache_entry *) e;
123 }
124 return f;
125}
126
b8d8561b 127static int
fe4e214f 128fqdncacheExpiredEntry(const fqdncache_entry * f)
f88bb09c 129{
429fdbec 130 if (f->locks != 0)
131 return 0;
e84703ad 132 if (f->expires > squid_curtime)
f88bb09c 133 return 0;
134 return 1;
135}
136
59c4d35b 137void
138fqdncache_purgelru(void *notused)
f88bb09c 139{
4bc76d59 140 dlink_node *m;
141 dlink_node *prev = NULL;
142 fqdncache_entry *f;
f88bb09c 143 int removed = 0;
52040193 144 eventAdd("fqdncache_purgelru", fqdncache_purgelru, NULL, 10.0, 1);
4bc76d59 145 for (m = lru_list.tail; m; m = prev) {
59c4d35b 146 if (memInUse(MEM_FQDNCACHE_ENTRY) < fqdncache_low)
4bc76d59 147 break;
148 prev = m->prev;
149 f = m->data;
4bc76d59 150 if (f->locks != 0)
151 continue;
add5d21f 152 fqdncacheRelease(f);
f88bb09c 153 removed++;
154 }
ac750329 155 debug(35, 9) ("fqdncache_purgelru: removed %d entries\n", removed);
f88bb09c 156}
157
f88bb09c 158/* create blank fqdncache_entry */
b8d8561b 159static fqdncache_entry *
add5d21f 160fqdncacheCreateEntry(const char *name)
f88bb09c 161{
4bc76d59 162 static fqdncache_entry *f;
59c4d35b 163 f = memAllocate(MEM_FQDNCACHE_ENTRY);
4bc76d59 164 f->name = xstrdup(name);
165 f->expires = squid_curtime + Config.negativeDnsTtl;
4bc76d59 166 return f;
f88bb09c 167}
168
b8d8561b 169static void
add5d21f 170fqdncacheAddEntry(fqdncache_entry * f)
f88bb09c 171{
add5d21f 172 hash_link *e = hash_lookup(fqdn_table, f->name);
173 if (NULL != e) {
174 /* avoid colission */
175 fqdncache_entry *q = (fqdncache_entry *) e;
176 fqdncacheRelease(q);
429fdbec 177 }
add5d21f 178 hash_join(fqdn_table, (hash_link *) f);
179 dlinkAdd(f, &f->lru, &lru_list);
429fdbec 180 f->lastref = squid_curtime;
f88bb09c 181}
182
183/* walks down the pending list, calling handlers */
b8d8561b 184static void
add5d21f 185fqdncacheCallback(fqdncache_entry * f)
f88bb09c 186{
add5d21f 187 FQDNH *handler = f->handler;
188 void *handlerData = f->handlerData;
f88bb09c 189 f->lastref = squid_curtime;
add5d21f 190 if (NULL == handler)
191 return;
5a2aa048 192 fqdncacheLockEntry(f);
add5d21f 193 f->handler = NULL;
194 f->handlerData = NULL;
195 if (cbdataValid(handlerData)) {
196 dns_error_message = f->error_message;
6b65d31c 197 handler(f->flags.negcached ? NULL : f->names[0], handlerData);
f88bb09c 198 }
add5d21f 199 cbdataUnlock(handlerData);
429fdbec 200 fqdncacheUnlockEntry(f);
f88bb09c 201}
202
b8d8561b 203static fqdncache_entry *
b18baa48 204#if USE_DNSSERVERS
74addf6c 205fqdncacheParse(const char *inbuf)
f88bb09c 206{
bd34f258 207 LOCAL_ARRAY(char, buf, DNS_INBUF_SZ);
e84703ad 208 char *token;
209 static fqdncache_entry f;
bd34f258 210 int ttl;
bd34f258 211 f.expires = squid_curtime;
add5d21f 212 f.flags.negcached = 1;
c68e9c6b 213 if (inbuf == NULL) {
214 debug(35, 1) ("fqdncacheParse: Got <NULL> reply\n");
215 return &f;
216 }
c579f632 217 xstrncpy(buf, inbuf, DNS_INBUF_SZ);
218 debug(35, 5) ("fqdncacheParse: parsing: {%s}\n", buf);
bd34f258 219 token = strtok(buf, w_space);
220 if (NULL == token) {
6a78c18e 221 debug(35, 1) ("fqdncacheParse: Got <NULL>, expecting '$name'\n");
bd34f258 222 return &f;
223 }
224 if (0 == strcmp(token, "$fail")) {
225 f.expires = squid_curtime + Config.negativeDnsTtl;
226 token = strtok(NULL, "\n");
227 assert(NULL != token);
228 f.error_message = xstrdup(token);
229 return &f;
230 }
231 if (0 != strcmp(token, "$name")) {
6a78c18e 232 debug(35, 1) ("fqdncacheParse: Got '%s', expecting '$name'\n", token);
bd34f258 233 return &f;
234 }
235 token = strtok(NULL, w_space);
236 if (NULL == token) {
6a78c18e 237 debug(35, 1) ("fqdncacheParse: Got <NULL>, expecting TTL\n");
bd34f258 238 return &f;
239 }
add5d21f 240 f.flags.negcached = 0;
bd34f258 241 ttl = atoi(token);
242 if (ttl > 0)
243 f.expires = squid_curtime + ttl;
244 else
245 f.expires = squid_curtime + Config.positiveDnsTtl;
246 token = strtok(NULL, w_space);
247 if (NULL != token) {
248 f.names[0] = xstrdup(token);
249 f.name_count = 1;
f88bb09c 250 }
e84703ad 251 return &f;
f88bb09c 252}
59f34d62 253#else
59f34d62 254fqdncacheParse(rfc1035_rr * answers, int nr)
255{
256 static fqdncache_entry f;
257 int k;
258 int j;
259 int na = 0;
260 memset(&f, '\0', sizeof(f));
261 f.expires = squid_curtime;
add5d21f 262 f.flags.negcached = 1;
59f34d62 263 if (nr < 0) {
b18baa48 264 debug(35, 3) ("fqdncacheParse: Lookup failed (error %d)\n",
59f34d62 265 rfc1035_errno);
266 assert(rfc1035_error_message);
267 f.error_message = xstrdup(rfc1035_error_message);
268 return &f;
269 }
270 if (nr == 0) {
b18baa48 271 debug(35, 3) ("fqdncacheParse: No DNS records\n");
59f34d62 272 f.error_message = xstrdup("No DNS records");
273 return &f;
274 }
39d5df9b 275 debug(35, 3) ("fqdncacheParse: %d answers\n", nr);
59f34d62 276 assert(answers);
277 for (j = 0, k = 0; k < nr; k++) {
278 if (answers[k].type != RFC1035_TYPE_PTR)
279 continue;
280 if (answers[k].class != RFC1035_CLASS_IN)
281 continue;
282 na++;
add5d21f 283 f.flags.negcached = 0;
59f34d62 284 f.names[0] = xstrdup(answers[k].rdata);
285 f.name_count = 1;
286 f.expires = squid_curtime + answers[k].ttl;
287 return &f;
288 }
289 debug(35, 1) ("fqdncacheParse: No PTR record\n");
290 f.error_message = xstrdup("No PTR record");
291 return &f;
292}
293#endif
f88bb09c 294
429fdbec 295static void
59f34d62 296#if USE_DNSSERVERS
74addf6c 297fqdncacheHandleReply(void *data, char *reply)
59f34d62 298#else
299fqdncacheHandleReply(void *data, rfc1035_rr * answers, int na)
300#endif
f88bb09c 301{
f88bb09c 302 int n;
74addf6c 303 generic_cbdata *c = data;
304 fqdncache_entry *f = c->data;
e84703ad 305 fqdncache_entry *x = NULL;
74addf6c 306 cbdataFree(c);
307 c = NULL;
c68e9c6b 308 n = ++FqdncacheStats.replies;
83704487 309 statHistCount(&statCounter.dns.svc_time,
74addf6c 310 tvSubMsec(f->request_time, current_time));
59f34d62 311#if USE_DNSSERVERS
c68e9c6b 312 x = fqdncacheParse(reply);
59f34d62 313#else
314 x = fqdncacheParse(answers, na);
315#endif
c68e9c6b 316 assert(x);
317 f->name_count = x->name_count;
318 for (n = 0; n < (int) f->name_count; n++)
319 f->names[n] = x->names[n];
320 f->error_message = x->error_message;
c68e9c6b 321 f->expires = x->expires;
add5d21f 322 f->flags = x->flags;
323 fqdncacheAddEntry(f);
324 fqdncacheCallback(f);
f88bb09c 325}
326
429fdbec 327void
348b2031 328fqdncache_nbgethostbyaddr(struct in_addr addr, FQDNH * handler, void *handlerData)
f88bb09c 329{
330 fqdncache_entry *f = NULL;
f88bb09c 331 char *name = inet_ntoa(addr);
74addf6c 332 generic_cbdata *c;
698e6f16 333 assert(handler);
a3d5953d 334 debug(35, 4) ("fqdncache_nbgethostbyaddr: Name '%s'.\n", name);
f88bb09c 335 FqdncacheStats.requests++;
f88bb09c 336 if (name == NULL || name[0] == '\0') {
a3d5953d 337 debug(35, 4) ("fqdncache_nbgethostbyaddr: Invalid name!\n");
348b2031 338 handler(NULL, handlerData);
429fdbec 339 return;
f88bb09c 340 }
add5d21f 341 f = fqdncache_get(name);
342 if (NULL == f) {
343 /* miss */
344 (void) 0;
345 } else if (fqdncacheExpiredEntry(f)) {
346 /* hit, but expired -- bummer */
347 fqdncacheRelease(f);
348 f = NULL;
349 } else {
350 /* hit */
a3d5953d 351 debug(35, 4) ("fqdncache_nbgethostbyaddr: HIT for '%s'\n", name);
add5d21f 352 if (f->flags.negcached)
f88bb09c 353 FqdncacheStats.negative_hits++;
354 else
355 FqdncacheStats.hits++;
add5d21f 356 f->handler = handler;
357 f->handlerData = handlerData;
358 cbdataLock(handlerData);
359 fqdncacheCallback(f);
429fdbec 360 return;
f88bb09c 361 }
add5d21f 362
363 debug(35, 5) ("fqdncache_nbgethostbyaddr: MISS for '%s'\n", name);
364 FqdncacheStats.misses++;
365 f = fqdncacheCreateEntry(name);
366 f->handler = handler;
367 f->handlerData = handlerData;
368 cbdataLock(handlerData);
369 f->request_time = current_time;
58cd5bbd 370 c = memAllocate(MEM_GEN_CBDATA);
74addf6c 371 c->data = f;
58cd5bbd 372 cbdataAdd(c, memFree, MEM_GEN_CBDATA);
59f34d62 373#if USE_DNSSERVERS
74addf6c 374 dnsSubmit(f->name, fqdncacheHandleReply, c);
59f34d62 375#else
376 idnsPTRLookup(addr, fqdncacheHandleReply, c);
377#endif
f88bb09c 378}
379
f88bb09c 380/* initialize the fqdncache */
b8d8561b 381void
0673c0ba 382fqdncache_init(void)
f88bb09c 383{
aa9e2cab 384 int n;
19054954 385 if (fqdn_table)
386 return;
a3d5953d 387 debug(35, 3) ("Initializing FQDN Cache...\n");
f88bb09c 388 memset(&FqdncacheStats, '\0', sizeof(FqdncacheStats));
3eb55834 389 memset(&lru_list, '\0', sizeof(lru_list));
e55650e3 390 fqdncache_high = (long) (((float) Config.fqdncache.size *
f88bb09c 391 (float) FQDN_HIGH_WATER) / (float) 100);
e55650e3 392 fqdncache_low = (long) (((float) Config.fqdncache.size *
f88bb09c 393 (float) FQDN_LOW_WATER) / (float) 100);
aa9e2cab 394 n = hashPrime(fqdncache_high / 4);
6a78c18e 395 fqdn_table = hash_create((HASHCMP *) strcmp, n, hash4);
22f3fd98 396 cachemgrRegister("fqdncache",
397 "FQDN Cache Stats and Contents",
1da3b90b 398 fqdnStats, 0, 1);
add5d21f 399 memDataInit(MEM_FQDNCACHE_ENTRY, "fqdncache_entry",
400 sizeof(fqdncache_entry), 0);
f88bb09c 401}
402
0ee4272b 403const char *
b8d8561b 404fqdncache_gethostbyaddr(struct in_addr addr, int flags)
f88bb09c 405{
406 char *name = inet_ntoa(addr);
407 fqdncache_entry *f = NULL;
429fdbec 408 struct in_addr ip;
698e6f16 409 assert(name);
f88bb09c 410 FqdncacheStats.requests++;
add5d21f 411 f = fqdncache_get(name);
412 if (NULL == f) {
413 (void) 0;
414 } else if (fqdncacheExpiredEntry(f)) {
415 fqdncacheRelease(f);
416 f = NULL;
417 } else if (f->flags.negcached) {
418 FqdncacheStats.negative_hits++;
419 dns_error_message = f->error_message;
420 return NULL;
421 } else {
422 FqdncacheStats.hits++;
423 f->lastref = squid_curtime;
424 return f->names[0];
f88bb09c 425 }
f88bb09c 426 /* check if it's already a FQDN address in text form. */
429fdbec 427 if (!safe_inet_addr(name, &ip))
f88bb09c 428 return name;
429fdbec 429 FqdncacheStats.misses++;
f88bb09c 430 if (flags & FQDN_LOOKUP_IF_MISS)
348b2031 431 fqdncache_nbgethostbyaddr(addr, dummy_handler, NULL);
f88bb09c 432 return NULL;
433}
434
435
436/* process objects list */
b8d8561b 437void
438fqdnStats(StoreEntry * sentry)
f88bb09c 439{
440 fqdncache_entry *f = NULL;
441 int k;
442 int ttl;
4bc76d59 443 if (fqdn_table == NULL)
f88bb09c 444 return;
15576b6a 445 storeAppendPrintf(sentry, "FQDN Cache Statistics:\n");
446 storeAppendPrintf(sentry, "FQDNcache Entries: %d\n",
59c4d35b 447 memInUse(MEM_FQDNCACHE_ENTRY));
15576b6a 448 storeAppendPrintf(sentry, "FQDNcache Requests: %d\n",
f88bb09c 449 FqdncacheStats.requests);
15576b6a 450 storeAppendPrintf(sentry, "FQDNcache Hits: %d\n",
f88bb09c 451 FqdncacheStats.hits);
15576b6a 452 storeAppendPrintf(sentry, "FQDNcache Negative Hits: %d\n",
f88bb09c 453 FqdncacheStats.negative_hits);
15576b6a 454 storeAppendPrintf(sentry, "FQDNcache Misses: %d\n",
f88bb09c 455 FqdncacheStats.misses);
15576b6a 456 storeAppendPrintf(sentry, "Blocking calls to gethostbyaddr(): %d\n",
f88bb09c 457 FqdncacheStats.ghba_calls);
15576b6a 458 storeAppendPrintf(sentry, "FQDN Cache Contents:\n\n");
f88bb09c 459
0f6bebac 460 hash_first(fqdn_table);
461 while ((f = (fqdncache_entry *) hash_next(fqdn_table))) {
add5d21f 462 ttl = (f->expires - squid_curtime);
15576b6a 463 storeAppendPrintf(sentry, " %-32.32s %c %6d %d",
f88bb09c 464 f->name,
add5d21f 465 f->flags.negcached ? 'N' : ' ',
f88bb09c 466 ttl,
467 (int) f->name_count);
468 for (k = 0; k < (int) f->name_count; k++)
469 storeAppendPrintf(sentry, " %s", f->names[k]);
22f3fd98 470 storeAppendPrintf(sentry, "\n");
f88bb09c 471 }
f88bb09c 472}
473
b8d8561b 474static void
79d39a72 475dummy_handler(const char *bufnotused, void *datanotused)
f88bb09c 476{
477 return;
478}
479
0ee4272b 480const char *
b8d8561b 481fqdnFromAddr(struct in_addr addr)
28ab0c0a 482{
0ee4272b 483 const char *n;
39de381a 484 static char buf[32];
17a0a4ee 485 if (Config.onoff.log_fqdn && (n = fqdncache_gethostbyaddr(addr, 0)))
28ab0c0a 486 return n;
f2052513 487 xstrncpy(buf, inet_ntoa(addr), 32);
39de381a 488 return buf;
28ab0c0a 489}
f201f309 490
429fdbec 491static void
492fqdncacheLockEntry(fqdncache_entry * f)
493{
4bc76d59 494 if (f->locks++ == 0) {
495 dlinkDelete(&f->lru, &lru_list);
496 dlinkAdd(f, &f->lru, &lru_list);
497 }
429fdbec 498}
499
500static void
501fqdncacheUnlockEntry(fqdncache_entry * f)
502{
ac06f720 503 assert(f->locks > 0);
429fdbec 504 f->locks--;
505 if (fqdncacheExpiredEntry(f))
add5d21f 506 fqdncacheRelease(f);
429fdbec 507}
508
ec878047 509static void
510fqdncacheFreeEntry(void *data)
511{
512 fqdncache_entry *f = data;
513 int k;
514 for (k = 0; k < (int) f->name_count; k++)
515 safe_free(f->names[k]);
516 safe_free(f->name);
517 safe_free(f->error_message);
db1cd23c 518 memFree(f, MEM_FQDNCACHE_ENTRY);
ec878047 519}
520
56e15c50 521void
522fqdncacheFreeMemory(void)
523{
ec878047 524 hashFreeItems(fqdn_table, fqdncacheFreeEntry);
56e15c50 525 hashFreeMemory(fqdn_table);
afe95a7e 526 fqdn_table = NULL;
56e15c50 527}
429fdbec 528
d20b1cd0 529/* Recalculate FQDN cache size upon reconfigure */
429fdbec 530void
531fqdncache_restart(void)
532{
e55650e3 533 fqdncache_high = (long) (((float) Config.fqdncache.size *
e144eae4 534 (float) FQDN_HIGH_WATER) / (float) 100);
e55650e3 535 fqdncache_low = (long) (((float) Config.fqdncache.size *
e144eae4 536 (float) FQDN_LOW_WATER) / (float) 100);
429fdbec 537}
ce75f381 538
539#ifdef SQUID_SNMP
e7ef99a7 540/*
135171fe 541 * The function to return the fqdn statistics via SNMP
542 */
d60c11be 543
86115da5 544variable_list *
e7ef99a7 545snmp_netFqdnFn(variable_list * Var, snint * ErrP)
d60c11be 546{
736eb6ad 547 variable_list *Answer = NULL;
d20b1cd0 548 debug(49, 5) ("snmp_netFqdnFn: Processing request:\n", Var->name[LEN_SQ_NET + 1]);
e7ef99a7 549 snmpDebugOid(5, Var->name, Var->name_length);
86115da5 550 *ErrP = SNMP_ERR_NOERROR;
135171fe 551 switch (Var->name[LEN_SQ_NET + 1]) {
e7ef99a7 552 case FQDN_ENT:
736eb6ad 553 Answer = snmp_var_new_integer(Var->name, Var->name_length,
554 memInUse(MEM_FQDNCACHE_ENTRY),
555 SMI_GAUGE32);
135171fe 556 break;
e7ef99a7 557 case FQDN_REQ:
736eb6ad 558 Answer = snmp_var_new_integer(Var->name, Var->name_length,
559 FqdncacheStats.requests,
560 SMI_COUNTER32);
135171fe 561 break;
e7ef99a7 562 case FQDN_HITS:
736eb6ad 563 Answer = snmp_var_new_integer(Var->name, Var->name_length,
564 FqdncacheStats.hits,
565 SMI_COUNTER32);
135171fe 566 break;
e7ef99a7 567 case FQDN_PENDHIT:
add5d21f 568 /* this is now worthless */
736eb6ad 569 Answer = snmp_var_new_integer(Var->name, Var->name_length,
add5d21f 570 0,
736eb6ad 571 SMI_GAUGE32);
135171fe 572 break;
e7ef99a7 573 case FQDN_NEGHIT:
736eb6ad 574 Answer = snmp_var_new_integer(Var->name, Var->name_length,
575 FqdncacheStats.negative_hits,
576 SMI_COUNTER32);
135171fe 577 break;
e7ef99a7 578 case FQDN_MISS:
736eb6ad 579 Answer = snmp_var_new_integer(Var->name, Var->name_length,
580 FqdncacheStats.misses,
581 SMI_COUNTER32);
135171fe 582 break;
e7ef99a7 583 case FQDN_GHBN:
736eb6ad 584 Answer = snmp_var_new_integer(Var->name, Var->name_length,
585 FqdncacheStats.ghba_calls,
586 SMI_COUNTER32);
135171fe 587 break;
ce75f381 588 default:
135171fe 589 *ErrP = SNMP_ERR_NOSUCHNAME;
736eb6ad 590 break;
86115da5 591 }
592 return Answer;
ce75f381 593}
e7ef99a7 594
135171fe 595#endif /*SQUID_SNMP */