]> git.ipfire.org Git - thirdparty/squid.git/blobdiff - src/fqdncache.cc
SourceFormat Enforcement
[thirdparty/squid.git] / src / fqdncache.cc
index 375b7e4ee3f09c86e1c73813be5652f43043c7a2..3daff6082829c2a104d36a6d0c1896114f4a1aef 100644 (file)
@@ -1,47 +1,31 @@
 /*
- * $Id$
- *
- * DEBUG: section 35    FQDN Cache
- * AUTHOR: Harvest Derived
- *
- * SQUID Web Proxy Cache          http://www.squid-cache.org/
- * ----------------------------------------------------------
- *
- *  Squid is the result of efforts by numerous individuals from
- *  the Internet community; see the CONTRIBUTORS file for full
- *  details.   Many organizations have provided support for Squid's
- *  development; see the SPONSORS file for full details.  Squid is
- *  Copyrighted (C) 2001 by the Regents of the University of
- *  California; see the COPYRIGHT file for full details.  Squid
- *  incorporates software developed and/or copyrighted by other
- *  sources; see the CREDITS file for full details.
- *
- *  This program is free software; you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation; either version 2 of the License, or
- *  (at your option) any later version.
- *
- *  This program is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with this program; if not, write to the Free Software
- *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111, USA.
+ * Copyright (C) 1996-2015 The Squid Software Foundation and contributors
  *
+ * Squid software is distributed under GPLv2+ license and includes
+ * contributions from numerous individuals and organizations.
+ * Please see the COPYING and CONTRIBUTORS files for details.
  */
 
+/* DEBUG: section 35    FQDN Cache */
+
 #include "squid.h"
 #include "cbdata.h"
 #include "DnsLookupDetails.h"
 #include "event.h"
+#include "helper.h"
 #include "mgr/Registration.h"
+#include "SquidConfig.h"
+#include "SquidDns.h"
 #include "SquidTime.h"
-#include "StatHist.h"
+#include "StatCounters.h"
 #include "Store.h"
+#include "util.h"
 #include "wordlist.h"
 
+#if SQUID_SNMP
+#include "snmp_core.h"
+#endif
+
 /**
  \defgroup FQDNCacheAPI FQDN Cache API
  \ingroup Components
@@ -95,7 +79,7 @@
 class fqdncache_entry
 {
 public:
-    hash_link hash;            /* must be first */
+    hash_link hash;     /* must be first */
     time_t lastref;
     time_t expires;
     unsigned char name_count;
@@ -109,8 +93,8 @@ public:
     unsigned short locks;
 
     struct {
-        unsigned int negcached:1;
-        unsigned int fromhosts:1;
+        bool negcached;
+        bool fromhosts;
     } flags;
 
     int age() const; ///< time passed since request_time or -1 if unknown
@@ -128,13 +112,8 @@ static struct _fqdn_cache_stats {
 /// \ingroup FQDNCacheInternal
 static dlink_list lru_list;
 
-#if USE_DNSSERVERS
-static HLPCB fqdncacheHandleReply;
-static int fqdncacheParse(fqdncache_entry *, const char *buf);
-#else
 static IDNSCB fqdncacheHandleReply;
-static int fqdncacheParse(fqdncache_entry *, rfc1035_rr *, int, const char *error_message);
-#endif
+static int fqdncacheParse(fqdncache_entry *, const rfc1035_rr *, int, const char *error_message);
 static void fqdncacheRelease(fqdncache_entry *);
 static fqdncache_entry *fqdncacheCreateEntry(const char *name);
 static void fqdncacheCallback(fqdncache_entry *, int wait);
@@ -163,7 +142,6 @@ fqdncache_entry::age() const
     return request_time.tv_sec ? tvSubMsec(request_time, current_time) : -1;
 }
 
-
 /**
  \ingroup FQDNCacheInternal
  * Removes the given fqdncache entry
@@ -174,7 +152,7 @@ fqdncacheRelease(fqdncache_entry * f)
     int k;
     hash_remove_link(fqdn_table, (hash_link *) f);
 
-    for (k = 0; k < (int) f->name_count; k++)
+    for (k = 0; k < (int) f->name_count; ++k)
         safe_free(f->names[k]);
 
     debugs(35, 5, "fqdncacheRelease: Released FQDN record for '" << hashKeyStr(&f->hash) << "'.");
@@ -190,7 +168,7 @@ fqdncacheRelease(fqdncache_entry * f)
 
 /**
  \ingroup FQDNCacheInternal
- \param name   FQDN hash string.
+ \param name    FQDN hash string.
  \retval Match for given name
  */
 static fqdncache_entry *
@@ -225,7 +203,7 @@ fqdncacheExpiredEntry(const fqdncache_entry * f)
 
 /// \ingroup FQDNCacheAPI
 void
-fqdncache_purgelru(void *notused)
+fqdncache_purgelru(void *)
 {
     dlink_node *m;
     dlink_node *prev = NULL;
@@ -246,7 +224,7 @@ fqdncache_purgelru(void *notused)
 
         fqdncacheRelease(f);
 
-        removed++;
+        ++removed;
     }
 
     debugs(35, 9, "fqdncache_purgelru: removed " << removed << " entries");
@@ -261,8 +239,8 @@ purge_entries_fromhosts(void)
     fqdncache_entry *t;
 
     while (m) {
-        if (i != NULL) {       /* need to delay deletion */
-            fqdncacheRelease(i);       /* we just override locks */
+        if (i != NULL) {    /* need to delay deletion */
+            fqdncacheRelease(i);    /* we just override locks */
             i = NULL;
         }
 
@@ -340,89 +318,14 @@ fqdncacheCallback(fqdncache_entry * f, int wait)
 }
 
 /// \ingroup FQDNCacheInternal
-#if USE_DNSSERVERS
 static int
-fqdncacheParse(fqdncache_entry *f, const char *inbuf)
-{
-    LOCAL_ARRAY(char, buf, DNS_INBUF_SZ);
-    char *token;
-    int ttl;
-    const char *name = (const char *)f->hash.key;
-    f->expires = squid_curtime + Config.negativeDnsTtl;
-    f->flags.negcached = 1;
-
-    if (inbuf == NULL) {
-        debugs(35, 1, "fqdncacheParse: Got <NULL> reply in response to '" << name << "'");
-        f->error_message = xstrdup("Internal Error");
-        return -1;
-    }
-
-    xstrncpy(buf, inbuf, DNS_INBUF_SZ);
-    debugs(35, 5, "fqdncacheParse: parsing: {" << buf << "}");
-    token = strtok(buf, w_space);
-
-    if (NULL == token) {
-        debugs(35, 1, "fqdncacheParse: Got <NULL>, expecting '$name' in response to '" << name << "'");
-        f->error_message = xstrdup("Internal Error");
-        return -1;
-    }
-
-    if (0 == strcmp(token, "$fail")) {
-        token = strtok(NULL, "\n");
-        assert(NULL != token);
-        f->error_message = xstrdup(token);
-        return 0;
-    }
-
-    if (0 != strcmp(token, "$name")) {
-        debugs(35, 1, "fqdncacheParse: Got '" << inbuf << "', expecting '$name' in response to '" << name << "'");
-        f->error_message = xstrdup("Internal Error");
-        return -1;
-    }
-
-    token = strtok(NULL, w_space);
-
-    if (NULL == token) {
-        debugs(35, 1, "fqdncacheParse: Got '" << inbuf << "', expecting TTL in response to '" << name << "'");
-        f->error_message = xstrdup("Internal Error");
-        return -1;
-    }
-
-    ttl = atoi(token);
-
-    token = strtok(NULL, w_space);
-
-    if (NULL == token) {
-        debugs(35, 1, "fqdncacheParse: Got '" << inbuf << "', expecting hostname in response to '" << name << "'");
-        f->error_message = xstrdup("Internal Error");
-        return -1;
-    }
-
-    f->names[0] = xstrdup(token);
-    f->name_count = 1;
-
-    if (ttl == 0 || ttl > Config.positiveDnsTtl)
-        ttl = Config.positiveDnsTtl;
-
-    if (ttl < Config.negativeDnsTtl)
-        ttl = Config.negativeDnsTtl;
-
-    f->expires = squid_curtime + ttl;
-
-    f->flags.negcached = 0;
-
-    return f->name_count;
-}
-
-#else
-static int
-fqdncacheParse(fqdncache_entry *f, rfc1035_rr * answers, int nr, const char *error_message)
+fqdncacheParse(fqdncache_entry *f, const rfc1035_rr * answers, int nr, const char *error_message)
 {
     int k;
     int ttl = 0;
     const char *name = (const char *)f->hash.key;
     f->expires = squid_curtime + Config.negativeDnsTtl;
-    f->flags.negcached = 1;
+    f->flags.negcached = true;
 
     if (nr < 0) {
         debugs(35, 3, "fqdncacheParse: Lookup of '" << name << "' failed (" << error_message << ")");
@@ -439,7 +342,7 @@ fqdncacheParse(fqdncache_entry *f, rfc1035_rr * answers, int nr, const char *err
     debugs(35, 3, "fqdncacheParse: " << nr << " answers for '" << name << "'");
     assert(answers);
 
-    for (k = 0; k < nr; k++) {
+    for (k = 0; k < nr; ++k) {
         if (answers[k]._class != RFC1035_CLASS_IN)
             continue;
 
@@ -454,7 +357,8 @@ fqdncacheParse(fqdncache_entry *f, rfc1035_rr * answers, int nr, const char *err
                 continue;
             }
 
-            f->names[f->name_count++] = xstrdup(answers[k].rdata);
+            f->names[f->name_count] = xstrdup(answers[k].rdata);
+            ++ f->name_count;
         } else if (answers[k].type != RFC1035_TYPE_CNAME)
             continue;
 
@@ -466,7 +370,7 @@ fqdncacheParse(fqdncache_entry *f, rfc1035_rr * answers, int nr, const char *err
     }
 
     if (f->name_count == 0) {
-        debugs(35, 1, "fqdncacheParse: No PTR record for '" << name << "'");
+        debugs(35, DBG_IMPORTANT, "fqdncacheParse: No PTR record for '" << name << "'");
         return 0;
     }
 
@@ -478,53 +382,38 @@ fqdncacheParse(fqdncache_entry *f, rfc1035_rr * answers, int nr, const char *err
 
     f->expires = squid_curtime + ttl;
 
-    f->flags.negcached = 0;
+    f->flags.negcached = false;
 
     return f->name_count;
 }
 
-#endif
-
-
 /**
  \ingroup FQDNCacheAPI
  *
  * Callback for handling DNS results.
  */
 static void
-#if USE_DNSSERVERS
-fqdncacheHandleReply(void *data, char *reply)
-#else
-fqdncacheHandleReply(void *data, rfc1035_rr * answers, int na, const char *error_message)
-#endif
+fqdncacheHandleReply(void *data, const rfc1035_rr * answers, int na, const char *error_message)
 {
     fqdncache_entry *f;
     static_cast<generic_cbdata *>(data)->unwrap(&f);
     ++FqdncacheStats.replies;
     const int age = f->age();
-    statHistCount(&statCounter.dns.svc_time, age);
-#if USE_DNSSERVERS
-
-    fqdncacheParse(f, reply);
-#else
-
+    statCounter.dns.svcTime.count(age);
     fqdncacheParse(f, answers, na, error_message);
-#endif
-
     fqdncacheAddEntry(f);
-
     fqdncacheCallback(f, age);
 }
 
 /**
  \ingroup FQDNCacheAPI
  *
- \param addr           IP address of domain to resolve.
- \param handler                A pointer to the function to be called when
- *                     the reply from the FQDN cache
- *                     (or the DNS if the FQDN cache misses)
- \param handlerData    Information that is passed to the handler
- *                     and does not affect the FQDN cache.
+ \param addr        IP address of domain to resolve.
+ \param handler     A pointer to the function to be called when
+ *          the reply from the FQDN cache
+ *          (or the DNS if the FQDN cache misses)
+ \param handlerData Information that is passed to the handler
+ *          and does not affect the FQDN cache.
  */
 void
 fqdncache_nbgethostbyaddr(const Ip::Address &addr, FQDNH * handler, void *handlerData)
@@ -532,9 +421,9 @@ fqdncache_nbgethostbyaddr(const Ip::Address &addr, FQDNH * handler, void *handle
     fqdncache_entry *f = NULL;
     char name[MAX_IPSTRLEN];
     generic_cbdata *c;
-    addr.NtoA(name,MAX_IPSTRLEN);
+    addr.toStr(name,MAX_IPSTRLEN);
     debugs(35, 4, "fqdncache_nbgethostbyaddr: Name '" << name << "'.");
-    FqdncacheStats.requests++;
+    ++FqdncacheStats.requests;
 
     if (name[0] == '\0') {
         debugs(35, 4, "fqdncache_nbgethostbyaddr: Invalid name!");
@@ -558,9 +447,9 @@ fqdncache_nbgethostbyaddr(const Ip::Address &addr, FQDNH * handler, void *handle
         debugs(35, 4, "fqdncache_nbgethostbyaddr: HIT for '" << name << "'");
 
         if (f->flags.negcached)
-            FqdncacheStats.negative_hits++;
+            ++ FqdncacheStats.negative_hits;
         else
-            FqdncacheStats.hits++;
+            ++ FqdncacheStats.hits;
 
         f->handler = handler;
 
@@ -572,63 +461,13 @@ fqdncache_nbgethostbyaddr(const Ip::Address &addr, FQDNH * handler, void *handle
     }
 
     debugs(35, 5, "fqdncache_nbgethostbyaddr: MISS for '" << name << "'");
-    FqdncacheStats.misses++;
+    ++ FqdncacheStats.misses;
     f = fqdncacheCreateEntry(name);
     f->handler = handler;
     f->handlerData = cbdataReference(handlerData);
     f->request_time = current_time;
     c = new generic_cbdata(f);
-#if USE_DNSSERVERS
-
-    dnsSubmit(hashKeyStr(&f->hash), fqdncacheHandleReply, c);
-#else
     idnsPTRLookup(addr, fqdncacheHandleReply, c);
-#endif
-}
-
-/// \ingroup FQDNCacheInternal
-static void
-fqdncacheRegisterWithCacheManager(void)
-{
-    Mgr::RegisterAction("fqdncache", "FQDN Cache Stats and Contents",
-                        fqdnStats, 0, 1);
-
-}
-
-/**
- \ingroup FQDNCacheAPI
- *
- * Initialize the fqdncache.
- * Called after IP cache initialization.
- */
-void
-fqdncache_init(void)
-{
-    int n;
-
-    fqdncacheRegisterWithCacheManager();
-
-    if (fqdn_table)
-        return;
-
-    debugs(35, 3, "Initializing FQDN Cache...");
-
-    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);
-
-    memDataInit(MEM_FQDNCACHE_ENTRY, "fqdncache_entry",
-                sizeof(fqdncache_entry), 0);
 }
 
 /**
@@ -639,8 +478,8 @@ fqdncache_init(void)
  * DNS, unless this is requested, by setting the flags
  * to FQDN_LOOKUP_IF_MISS.
  *
- \param addr   address of the FQDN being resolved
- \param flags  values are NULL or FQDN_LOOKUP_IF_MISS. default is NULL.
+ \param addr    address of the FQDN being resolved
+ \param flags   values are NULL or FQDN_LOOKUP_IF_MISS. default is NULL.
  *
  */
 const char *
@@ -649,12 +488,12 @@ fqdncache_gethostbyaddr(const Ip::Address &addr, int flags)
     char name[MAX_IPSTRLEN];
     fqdncache_entry *f = NULL;
 
-    if (addr.IsAnyAddr() || addr.IsNoAddr()) {
+    if (addr.isAnyAddr() || addr.isNoAddr()) {
         return NULL;
     }
 
-    addr.NtoA(name,MAX_IPSTRLEN);
-    FqdncacheStats.requests++;
+    addr.toStr(name,MAX_IPSTRLEN);
+    ++ FqdncacheStats.requests;
     f = fqdncache_get(name);
 
     if (NULL == f) {
@@ -663,11 +502,11 @@ fqdncache_gethostbyaddr(const Ip::Address &addr, int flags)
         fqdncacheRelease(f);
         f = NULL;
     } else if (f->flags.negcached) {
-        FqdncacheStats.negative_hits++;
+        ++ FqdncacheStats.negative_hits;
         // ignore f->error_message: the caller just checks FQDN cache presence
         return NULL;
     } else {
-        FqdncacheStats.hits++;
+        ++ FqdncacheStats.hits;
         f->lastref = squid_curtime;
         // ignore f->error_message: the caller just checks FQDN cache presence
         return f->names[0];
@@ -675,7 +514,7 @@ fqdncache_gethostbyaddr(const Ip::Address &addr, int flags)
 
     /* no entry [any more] */
 
-    FqdncacheStats.misses++;
+    ++ FqdncacheStats.misses;
 
     if (flags & FQDN_LOOKUP_IF_MISS) {
         fqdncache_nbgethostbyaddr(addr, NULL, NULL);
@@ -684,7 +523,6 @@ fqdncache_gethostbyaddr(const Ip::Address &addr, int flags)
     return NULL;
 }
 
-
 /**
  \ingroup FQDNCacheInternal
  *
@@ -736,30 +574,13 @@ fqdnStats(StoreEntry * sentry)
                           ttl,
                           (int) f->name_count);
 
-        for (k = 0; k < (int) f->name_count; k++)
+        for (k = 0; k < (int) f->name_count; ++k)
             storeAppendPrintf(sentry, " %s", f->names[k]);
 
         storeAppendPrintf(sentry, "\n");
     }
 }
 
-/// \ingroup FQDNCacheAPI
-const char *
-fqdnFromAddr(const Ip::Address &addr)
-{
-    const char *n;
-    static char buf[MAX_IPSTRLEN];
-
-    if (Config.onoff.log_fqdn && (n = fqdncache_gethostbyaddr(addr, 0)))
-        return n;
-
-/// \todo Perhapse this should use toHostname() instead of straight NtoA.
-///       that would wrap the IPv6 properly when raw.
-    addr.NtoA(buf, MAX_IPSTRLEN);
-
-    return buf;
-}
-
 /// \ingroup FQDNCacheInternal
 static void
 fqdncacheLockEntry(fqdncache_entry * f)
@@ -775,7 +596,7 @@ static void
 fqdncacheUnlockEntry(fqdncache_entry * f)
 {
     assert(f->locks > 0);
-    f->locks--;
+    -- f->locks;
 
     if (fqdncacheExpiredEntry(f))
         fqdncacheRelease(f);
@@ -788,7 +609,7 @@ fqdncacheFreeEntry(void *data)
     fqdncache_entry *f = (fqdncache_entry *)data;
     int k;
 
-    for (k = 0; k < (int) f->name_count; k++)
+    for (k = 0; k < (int) f->name_count; ++k)
         safe_free(f->names[k]);
 
     safe_free(f->hash.key);
@@ -832,8 +653,8 @@ fqdncache_restart(void)
  * The worldist is to be managed by the caller,
  * including pointed-to strings
  *
- \param addr           FQDN name to be added.
- \param hostnames      ??
+ \param addr        FQDN name to be added.
+ \param hostnames   ??
  */
 void
 fqdncacheAddEntryFromHosts(char *addr, wordlist * hostnames)
@@ -845,7 +666,7 @@ fqdncacheAddEntryFromHosts(char *addr, wordlist * hostnames)
         if (1 == fce->flags.fromhosts) {
             fqdncacheUnlockEntry(fce);
         } else if (fce->locks > 0) {
-            debugs(35, 1, "fqdncacheAddEntryFromHosts: can't add static entry for locked address '" << addr << "'");
+            debugs(35, DBG_IMPORTANT, "fqdncacheAddEntryFromHosts: can't add static entry for locked address '" << addr << "'");
             return;
         } else {
             fqdncacheRelease(fce);
@@ -857,7 +678,7 @@ fqdncacheAddEntryFromHosts(char *addr, wordlist * hostnames)
     while (hostnames) {
         fce->names[j] = xstrdup(hostnames->key);
         Tolower(fce->names[j]);
-        j++;
+        ++j;
         hostnames = hostnames->next;
 
         if (j >= FQDN_MAX_NAMES)
@@ -865,12 +686,56 @@ fqdncacheAddEntryFromHosts(char *addr, wordlist * hostnames)
     }
 
     fce->name_count = j;
-    fce->names[j] = NULL;      /* it's safe */
-    fce->flags.fromhosts = 1;
+    fce->names[j] = NULL;   /* it's safe */
+    fce->flags.fromhosts = true;
     fqdncacheAddEntry(fce);
     fqdncacheLockEntry(fce);
 }
 
+/// \ingroup FQDNCacheInternal
+static void
+fqdncacheRegisterWithCacheManager(void)
+{
+    Mgr::RegisterAction("fqdncache", "FQDN Cache Stats and Contents",
+                        fqdnStats, 0, 1);
+
+}
+
+/**
+ \ingroup FQDNCacheAPI
+ *
+ * Initialize the fqdncache.
+ * Called after IP cache initialization.
+ */
+void
+fqdncache_init(void)
+{
+    int n;
+
+    fqdncacheRegisterWithCacheManager();
+
+    if (fqdn_table)
+        return;
+
+    debugs(35, 3, "Initializing FQDN Cache...");
+
+    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);
+
+    memDataInit(MEM_FQDNCACHE_ENTRY, "fqdncache_entry",
+                sizeof(fqdncache_entry), 0);
+}
 
 #if SQUID_SNMP
 /**
@@ -939,3 +804,4 @@ snmp_netFqdnFn(variable_list * Var, snint * ErrP)
 }
 
 #endif /*SQUID_SNMP */
+