* 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);
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;
}
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++;
/// \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;
/* 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 */