
Fix IP/FQDN cache accounting to avoid idle caches on busy servers.

When maintaining the IP/FQDN cache size, use the number of entries in the cache
rather than the number of allocated and not freed MEM_IPCACHE_ENTRY and
MEM_FQDNCACHE_ENTRY objects. These objects are used outside the cache 
for DNS queries. If queries leak (or perhaps when there are just a lot of them),
the memory-pool-based count overestimates the cache size, sometimes to 
such a degree that the cache remains nearly empty despite lots of misses.

Use memory-pool-based counter to estimate cache size also violates IP/FQDN cache
encapsulation boundaries because it effectively prevents others from using 
the same memory pool.

=== modified file 'src/fqdncache.cc'
--- src/fqdncache.cc	2010-10-29 00:12:28 +0000
+++ src/fqdncache.cc	2011-01-21 11:07:12 +0000
@@ -152,6 +152,9 @@
 /// \ingroup FQDNCacheInternal
 static long fqdncache_high = 200;
 
+/// \ingroup FQDNCacheInternal
+inline int fqdncacheCount() { return fqdn_table ? fqdn_table->count : 0; }
+
 int
 fqdncache_entry::age() const
 {
@@ -229,7 +232,7 @@
     eventAdd("fqdncache_purgelru", fqdncache_purgelru, NULL, 10.0, 1);
 
     for (m = lru_list.tail; m; m = prev) {
-        if (memInUse(MEM_FQDNCACHE_ENTRY) < fqdncache_low)
+        if (fqdncacheCount() < fqdncache_low)
             break;
 
         prev = m->prev;
@@ -698,9 +701,12 @@
 
     storeAppendPrintf(sentry, "FQDN Cache Statistics:\n");
 
-    storeAppendPrintf(sentry, "FQDNcache Entries: %d\n",
+    storeAppendPrintf(sentry, "FQDNcache Entries In Use: %d\n",
                       memInUse(MEM_FQDNCACHE_ENTRY));
 
+    storeAppendPrintf(sentry, "FQDNcache Entries Cached: %d\n",
+                      fqdncacheCount());
+
     storeAppendPrintf(sentry, "FQDNcache Requests: %d\n",
                       FqdncacheStats.requests);
 
@@ -882,7 +888,7 @@
 
     case FQDN_ENT:
         Answer = snmp_var_new_integer(Var->name, Var->name_length,
-                                      memInUse(MEM_FQDNCACHE_ENTRY),
+                                      fqdncacheCount(),
                                       SMI_GAUGE32);
         break;
 

=== modified file 'src/ipcache.cc'
--- src/ipcache.cc	2010-12-13 11:31:14 +0000
+++ src/ipcache.cc	2011-01-21 10:09:05 +0000
@@ -161,6 +161,9 @@
 extern int _dns_ttl_;
 #endif
 
+/// \ingroup IPCacheInternal
+inline int ipcacheCount() { return ip_table ? ip_table->count : 0; }
+
 int
 ipcache_entry::age() const
 {
@@ -235,7 +238,7 @@
     eventAdd("ipcache_purgelru", ipcache_purgelru, NULL, 10.0, 1);
 
     for (m = lru_list.tail; m; m = prev) {
-        if (memInUse(MEM_IPCACHE_ENTRY) < ipcache_low)
+        if (ipcacheCount() < ipcache_low)
             break;
 
         prev = m->prev;
@@ -855,8 +858,10 @@
     dlink_node *m;
     assert(ip_table != NULL);
     storeAppendPrintf(sentry, "IP Cache Statistics:\n");
-    storeAppendPrintf(sentry, "IPcache Entries:  %d\n",
+    storeAppendPrintf(sentry, "IPcache Entries In Use:  %d\n",
                       memInUse(MEM_IPCACHE_ENTRY));
+    storeAppendPrintf(sentry, "IPcache Entries Cached:  %d\n",
+                      ipcacheCount());
     storeAppendPrintf(sentry, "IPcache Requests: %d\n",
                       IpcacheStats.requests);
     storeAppendPrintf(sentry, "IPcache Hits:            %d\n",
@@ -1231,7 +1236,7 @@
 
     case IP_ENT:
         Answer = snmp_var_new_integer(Var->name, Var->name_length,
-                                      memInUse(MEM_IPCACHE_ENTRY),
+                                      ipcacheCount(),
                                       SMI_GAUGE32);
         break;
 


