-
/*
- * $Id: ipcache.cc,v 1.269 2008/02/26 21:49:35 amosjeffries Exp $
- *
* DEBUG: section 14 IP Cache
* AUTHOR: Harvest Derived
*
#include "SquidTime.h"
#include "Store.h"
#include "wordlist.h"
-#include "IPAddress.h"
+#include "ip/IpAddress.h"
/**
\defgroup IPCacheAPI IP Cache API
* the ipcache_high threshold.
*/
-/// \ingroup IPCacheAPI
-typedef struct _ipcache_entry ipcache_entry;
-
/**
\ingroup IPCacheAPI
*
* where structures of type ipcache_entry whose most
* interesting members are:
*/
-struct _ipcache_entry {
+class ipcache_entry
+{
+public:
hash_link hash; /* must be first */
time_t lastref;
time_t expires;
unsigned int negcached:1;
unsigned int fromhosts:1;
} flags;
+
+ int age() const; ///< time passed since request_time or -1 if unknown
};
/// \ingroup IPCacheInternal
extern int _dns_ttl_;
#endif
+int
+ipcache_entry::age() const
+{
+ return request_time.tv_sec ? tvSubMsec(request_time, current_time) : -1;
+}
+
+
+
/**
\ingroup IPCacheInternal
*
* walks down the pending list, calling handlers
*/
static void
-ipcacheCallback(ipcache_entry * i)
+ipcacheCallback(ipcache_entry *i, int wait)
{
IPH *callback = i->handler;
void *cbdata = NULL;
i->handler = NULL;
if (cbdataReferenceValidDone(i->handlerData, &cbdata)) {
- dns_error_message = i->error_message;
- callback(i->addrs.count ? &i->addrs : NULL, cbdata);
+ const DnsLookupDetails details(i->error_message, wait);
+ callback((i->addrs.count ? &i->addrs : NULL), details, cbdata);
}
ipcacheUnlockEntry(i);
if (ipcount > 0) {
int j, k;
- i->addrs.in_addrs = (IPAddress *)xcalloc(ipcount, sizeof(IPAddress));
+ i->addrs.in_addrs = (IpAddress *)xcalloc(ipcount, sizeof(IpAddress));
for (int l = 0; l < ipcount; l++)
i->addrs.in_addrs[l].SetEmpty(); // perform same init actions as constructor would.
i->addrs.bad_mask = (unsigned char *)xcalloc(ipcount, sizeof(unsigned char));
return 0;
}
- i->addrs.in_addrs = (IPAddress *)xcalloc(na, sizeof(IPAddress));
+ i->addrs.in_addrs = (IpAddress *)xcalloc(na, sizeof(IpAddress));
for (int l = 0; l < na; l++)
i->addrs.in_addrs[l].SetEmpty(); // perform same init actions as constructor would.
i->addrs.bad_mask = (unsigned char *)xcalloc(na, sizeof(unsigned char));
ipcache_entry *i;
static_cast<generic_cbdata *>(data)->unwrap(&i);
IpcacheStats.replies++;
- statHistCount(&statCounter.dns.svc_time,
- tvSubMsec(i->request_time, current_time));
+ const int age = i->age();
+ statHistCount(&statCounter.dns.svc_time, age);
+
#if USE_DNSSERVERS
done = ipcacheParse(i, reply);
{
ipcacheAddEntry(i);
- ipcacheCallback(i);
+ ipcacheCallback(i, age);
}
}
if (name == NULL || name[0] == '\0') {
debugs(14, 4, "ipcache_nbgethostbyname: Invalid name!");
IpcacheStats.invalid++;
- dns_error_message = "Invalid hostname";
- handler(NULL, handlerData);
+ const DnsLookupDetails details("Invalid hostname", -1); // error, no lookup
+ handler(NULL, details, handlerData);
return;
}
if ((addrs = ipcacheCheckNumeric(name))) {
debugs(14, 4, "ipcache_nbgethostbyname: BYPASS for '" << name << "' (already numeric)");
- dns_error_message = NULL;
IpcacheStats.numeric_hits++;
- handler(addrs, handlerData);
+ const DnsLookupDetails details(NULL, -1); // no error, no lookup
+ handler(addrs, details, handlerData);
return;
}
i->handlerData = cbdataReference(handlerData);
- ipcacheCallback(i);
+ ipcacheCallback(i, -1); // no lookup
return;
}
memset(&lru_list, '\0', sizeof(lru_list));
memset(&static_addrs, '\0', sizeof(ipcache_addrs));
- static_addrs.in_addrs = (IPAddress *)xcalloc(1, sizeof(IPAddress));
- static_addrs.in_addrs->SetEmpty(); // properly setup the IPAddress!
+ static_addrs.in_addrs = (IpAddress *)xcalloc(1, sizeof(IpAddress));
+ static_addrs.in_addrs->SetEmpty(); // properly setup the IpAddress!
static_addrs.bad_mask = (unsigned char *)xcalloc(1, sizeof(unsigned char));
ipcache_high = (long) (((float) Config.ipcache.size *
(float) Config.ipcache.high) / (float) 100);
i = NULL;
} else if (i->flags.negcached) {
IpcacheStats.negative_hits++;
- dns_error_message = i->error_message;
+ // ignore i->error_message: the caller just checks IP cache presence
return NULL;
} else {
IpcacheStats.hits++;
i->lastref = squid_curtime;
- dns_error_message = i->error_message;
+ // ignore i->error_message: the caller just checks IP cache presence
return &i->addrs;
}
- dns_error_message = NULL;
+ /* no entry [any more] */
if ((addrs = ipcacheCheckNumeric(name))) {
IpcacheStats.numeric_hits++;
ipcacheStatPrint(ipcache_entry * i, StoreEntry * sentry)
{
int k;
- int count = i->addrs.count;
char buf[MAX_IPSTRLEN];
if (!sentry) {
debugs(14, 0, HERE << "CRITICAL: sentry is NULL!");
+ return;
}
if (!i) {
return;
}
+ int count = i->addrs.count;
+
storeAppendPrintf(sentry, " %-32.32s %c%c %6d %6d %2d(%2d)",
hashKeyStr(&i->hash),
i->flags.fromhosts ? 'H' : ' ',
}
/** \par
- * Cached entries have IPs listed with a BNF of: <IP> '-' ('OK'|'BAD') */
+ * Cached entries have IPs listed with a BNF of: ip-address '-' ('OK'|'BAD') */
for (k = 0; k < count; k++) {
/* Display tidy-up: IPv6 are so big make the list vertical */
if (k == 0)
#if DNS_CNAME
/**
- * Takes two IPAddress arrays and merges them into a single array
+ * Takes two IpAddress arrays and merges them into a single array
* which is allocated dynamically to fit the number of unique addresses
*
\param aaddrs One list to merge
\param outlen Size of list out
*/
void
-ipcacheMergeIPLists(const IPAddress *aaddrs, const int alen,
- const IPAddress *baddrs, const int blen,
- IPAddress **out, int &outlen )
+ipcacheMergeIPLists(const IpAddress *aaddrs, const int alen,
+ const IpAddress *baddrs, const int blen,
+ IpAddress **out, int &outlen )
{
int fc=0, t=0, c=0;
- IPAddress const *ip4ptrs[255];
+ IpAddress const *ip4ptrs[255];
#if USE_IPV6
- IPAddress const *ip6ptrs[255];
+ IpAddress const *ip6ptrs[255];
#endif
int num_ip4 = 0;
int num_ip6 = 0;
- memset(ip4ptrs, 0, sizeof(IPAddress*)*255);
+ memset(ip4ptrs, 0, sizeof(IpAddress*)*255);
#if USE_IPV6
- memset(ip6ptrs, 0, sizeof(IPAddress*)*255);
+ memset(ip6ptrs, 0, sizeof(IpAddress*)*255);
#endif
// for each unique address in list A - grab ptr
debugs(14, 5, "ipcacheMergeIPLists: Merge " << alen << "+" << blen << " into " << fc << " unique IPs.");
// copy the old IPs into the new list buffer.
- (*out) = (IPAddress*)xcalloc(fc, sizeof(IPAddress));
+ (*out) = (IpAddress*)xcalloc(fc, sizeof(IpAddress));
outlen=0;
assert(out != NULL);
/// \ingroup IPCacheInternal
/// Callback.
static void
-ipcacheHandleCnameRecurse(const ipcache_addrs *addrs, void *cbdata)
+ipcacheHandleCnameRecurse(const ipcache_addrs *addrs, const DnsLookupDetails &, void *cbdata)
{
#if DNS_CNAME
ipcache_entry *i = NULL;
char *pname = NULL;
- IPAddress *tmpbuf = NULL;
+ IpAddress *tmpbuf = NULL;
int fc = 0;
int ttl = 0;
generic_cbdata* gcb = (generic_cbdata*)cbdata;
/* finish the lookup we were doing on parent when we got side-tracked for CNAME loop */
if (i->cname_wait == 0) {
ipcacheAddEntry(i);
- ipcacheCallback(i);
+ ipcacheCallback(i, i->age()); // age since i creation, includes CNAMEs
}
// else still more CNAME to be found.
#endif /* DNS_CNAME */
ipcacheCheckNumeric(const char *name)
{
- IPAddress ip;
+ IpAddress ip;
/* check if it's already a IP address in text form. */
/* it may be IPv6-wrapped */
\param addr specific addres to be marked bad
*/
void
-ipcacheMarkBadAddr(const char *name, IPAddress &addr)
+ipcacheMarkBadAddr(const char *name, IpAddress &addr)
{
ipcache_entry *i;
ipcache_addrs *ia;
if (!ia->bad_mask[k]) {
ia->bad_mask[k] = TRUE;
ia->badcount++;
- i->expires = XMIN(squid_curtime + XMAX((time_t)60, Config.negativeDnsTtl), i->expires);
+ i->expires = min(squid_curtime + max((time_t)60, Config.negativeDnsTtl), i->expires);
debugs(14, 2, "ipcacheMarkBadAddr: " << name << " " << addr );
}
/// \ingroup IPCacheAPI
void
-ipcacheMarkGoodAddr(const char *name, IPAddress &addr)
+ipcacheMarkGoodAddr(const char *name, IpAddress &addr)
{
ipcache_entry *i;
ipcache_addrs *ia;
{
ipcache_entry *i;
- IPAddress ip;
+ IpAddress ip;
if (!(ip = ipaddr)) {
#if USE_IPV6
i->addrs.cur = 0;
i->addrs.badcount = 0;
- i->addrs.in_addrs = (IPAddress *)xcalloc(1, sizeof(IPAddress));
+ i->addrs.in_addrs = (IpAddress *)xcalloc(1, sizeof(IpAddress));
i->addrs.bad_mask = (unsigned char *)xcalloc(1, sizeof(unsigned char));
i->addrs.in_addrs[0] = ip;
i->addrs.bad_mask[0] = FALSE;