]> git.ipfire.org Git - thirdparty/squid.git/blobdiff - src/client_db.cc
Source Format Enforcement (#532)
[thirdparty/squid.git] / src / client_db.cc
index cce0a12c042fe11b08fcbdb469c35027e9fa0d9b..be0bf50e4688e812bbd8f7db54e2e968265ce0e5 100644 (file)
@@ -1,44 +1,22 @@
 /*
- * DEBUG: section 00    Client Database
- * AUTHOR: Duane Wessels
- *
- * 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-2020 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 00    Client Database */
+
 #include "squid.h"
+#include "base/RunnersRegistry.h"
 #include "client_db.h"
+#include "ClientInfo.h"
 #include "event.h"
 #include "format/Token.h"
-#include "ClientInfo.h"
 #include "fqdncache.h"
 #include "ip/Address.h"
 #include "log/access_log.h"
-#include "Mem.h"
 #include "mgr/Registration.h"
 #include "SquidConfig.h"
 #include "SquidMath.h"
@@ -74,32 +52,32 @@ static int cleanup_removed;
 #define CLIENT_DB_HASH_SIZE 467
 #endif
 
-static ClientInfo *
+ClientInfo::ClientInfo(const Ip::Address &ip) :
+#if USE_DELAY_POOLS
+    BandwidthBucket(0, 0, 0),
+#endif
+    addr(ip),
+    n_established(0),
+    last_seen(0)
+#if USE_DELAY_POOLS
+    , writeLimitingActive(false),
+    firstTimeConnection(true),
+    quotaQueue(nullptr),
+    rationedQuota(0),
+    rationedCount(0),
+    eventWaiting(false)
+#endif
+{
+    debugs(77, 9, "ClientInfo constructed, this=" << static_cast<void*>(this));
+    char *buf = static_cast<char*>(xmalloc(MAX_IPSTRLEN)); // becomes hash.key
+    key = addr.toStr(buf,MAX_IPSTRLEN);
+}
 
+static ClientInfo *
 clientdbAdd(const Ip::Address &addr)
 {
-    ClientInfo *c;
-    char *buf = new char[MAX_IPSTRLEN];
-    c = (ClientInfo *)memAllocate(MEM_CLIENT_INFO);
-    c->hash.key = addr.NtoA(buf,MAX_IPSTRLEN);
-    c->addr = addr;
-#if USE_DELAY_POOLS
-    /* setup default values for client write limiter */
-    c->writeLimitingActive=false;
-    c->writeSpeedLimit=0;
-    c->bucketSize = 0;
-    c->firstTimeConnection=true;
-    c->quotaQueue = NULL;
-    c->rationedQuota = 0;
-    c->rationedCount = 0;
-    c->selectWaiting = false;
-    c->eventWaiting = false;
-
-    /* get current time */
-    getCurrentTime();
-    c->prevTime=current_dtime;/* put current time to have something sensible here */
-#endif
-    hash_join(client_table, &c->hash);
+    ClientInfo *c = new ClientInfo(addr);
+    hash_join(client_table, static_cast<hash_link*>(c));
     ++statCounter.client_http.clients;
 
     if ((statCounter.client_http.clients > max_clients) && !cleanup_running && cleanup_scheduled < 2) {
@@ -111,22 +89,29 @@ clientdbAdd(const Ip::Address &addr)
 }
 
 static void
-clientdbRegisterWithCacheManager(void)
-{
-    Mgr::RegisterAction("client_list", "Cache Client List", clientdbDump, 0, 1);
-}
-
-void
 clientdbInit(void)
 {
-    clientdbRegisterWithCacheManager();
-
     if (client_table)
         return;
 
     client_table = hash_create((HASHCMP *) strcmp, CLIENT_DB_HASH_SIZE, hash_string);
 }
 
+class ClientDbRr: public RegisteredRunner
+{
+public:
+    /* RegisteredRunner API */
+    virtual void useConfig();
+};
+RunnerRegistrationEntry(ClientDbRr);
+
+void
+ClientDbRr::useConfig()
+{
+    clientdbInit();
+    Mgr::RegisterAction("client_list", "Cache Client List", clientdbDump, 0, 1);
+}
+
 #if USE_DELAY_POOLS
 /* returns ClientInfo for given IP addr
    Returns NULL if no such client (or clientdb turned off)
@@ -140,7 +125,7 @@ ClientInfo * clientdbGetInfo(const Ip::Address &addr)
     if (!Config.onoff.client_db)
         return NULL;
 
-    addr.NtoA(key,MAX_IPSTRLEN);
+    addr.toStr(key,MAX_IPSTRLEN);
 
     c = (ClientInfo *) hash_lookup(client_table, key);
     if (c==NULL) {
@@ -151,7 +136,7 @@ ClientInfo * clientdbGetInfo(const Ip::Address &addr)
 }
 #endif
 void
-clientdbUpdate(const Ip::Address &addr, log_type ltype, AnyP::ProtocolType p, size_t size)
+clientdbUpdate(const Ip::Address &addr, const LogTags &ltype, AnyP::ProtocolType p, size_t size)
 {
     char key[MAX_IPSTRLEN];
     ClientInfo *c;
@@ -159,7 +144,7 @@ clientdbUpdate(const Ip::Address &addr, log_type ltype, AnyP::ProtocolType p, si
     if (!Config.onoff.client_db)
         return;
 
-    addr.NtoA(key,MAX_IPSTRLEN);
+    addr.toStr(key,MAX_IPSTRLEN);
 
     c = (ClientInfo *) hash_lookup(client_table, key);
 
@@ -171,18 +156,18 @@ clientdbUpdate(const Ip::Address &addr, log_type ltype, AnyP::ProtocolType p, si
 
     if (p == AnyP::PROTO_HTTP) {
         ++ c->Http.n_requests;
-        ++ c->Http.result_hist[ltype];
-        kb_incr(&c->Http.kbytes_out, size);
+        ++ c->Http.result_hist[ltype.oldType];
+        c->Http.kbytes_out += size;
 
-        if (logTypeIsATcpHit(ltype))
-            kb_incr(&c->Http.hit_kbytes_out, size);
+        if (ltype.isTcpHit())
+            c->Http.hit_kbytes_out += size;
     } else if (p == AnyP::PROTO_ICP) {
         ++ c->Icp.n_requests;
-        ++ c->Icp.result_hist[ltype];
-        kb_incr(&c->Icp.kbytes_out, size);
+        ++ c->Icp.result_hist[ltype.oldType];
+        c->Icp.kbytes_out += size;
 
-        if (LOG_UDP_HIT == ltype)
-            kb_incr(&c->Icp.hit_kbytes_out, size);
+        if (LOG_UDP_HIT == ltype.oldType)
+            c->Icp.hit_kbytes_out += size;
     }
 
     c->last_seen = squid_curtime;
@@ -203,7 +188,7 @@ clientdbEstablished(const Ip::Address &addr, int delta)
     if (!Config.onoff.client_db)
         return 0;
 
-    addr.NtoA(key,MAX_IPSTRLEN);
+    addr.toStr(key,MAX_IPSTRLEN);
 
     c = (ClientInfo *) hash_lookup(client_table, key);
 
@@ -233,7 +218,7 @@ clientdbCutoffDenied(const Ip::Address &addr)
     if (!Config.onoff.client_db)
         return 0;
 
-    addr.NtoA(key,MAX_IPSTRLEN);
+    addr.toStr(key,MAX_IPSTRLEN);
 
     c = (ClientInfo *) hash_lookup(client_table, key);
 
@@ -279,19 +264,10 @@ clientdbCutoffDenied(const Ip::Address &addr)
     return 1;
 }
 
-log_type &operator++ (log_type &aLogType)
-{
-    int tmp = (int)aLogType;
-    aLogType = (log_type)(++tmp);
-    return aLogType;
-}
-
 void
 clientdbDump(StoreEntry * sentry)
 {
     const char *name;
-    ClientInfo *c;
-    log_type l;
     int icp_total = 0;
     int icp_hits = 0;
     int http_total = 0;
@@ -299,8 +275,9 @@ clientdbDump(StoreEntry * sentry)
     storeAppendPrintf(sentry, "Cache Clients:\n");
     hash_first(client_table);
 
-    while ((c = (ClientInfo *) hash_next(client_table))) {
-        storeAppendPrintf(sentry, "Address: %s\n", hashKeyStr(&c->hash));
+    while (hash_link *hash = hash_next(client_table)) {
+        const ClientInfo *c = static_cast<const ClientInfo *>(hash);
+        storeAppendPrintf(sentry, "Address: %s\n", hashKeyStr(hash));
         if ( (name = fqdncache_gethostbyaddr(c->addr, 0)) ) {
             storeAppendPrintf(sentry, "Name:    %s\n", name);
         }
@@ -309,7 +286,7 @@ clientdbDump(StoreEntry * sentry)
         storeAppendPrintf(sentry, "    ICP  Requests %d\n",
                           c->Icp.n_requests);
 
-        for (l = LOG_TAG_NONE; l < LOG_TYPE_MAX; ++l) {
+        for (LogTags_ot l = LOG_TAG_NONE; l < LOG_TYPE_MAX; ++l) {
             if (c->Icp.result_hist[l] == 0)
                 continue;
 
@@ -318,23 +295,23 @@ clientdbDump(StoreEntry * sentry)
             if (LOG_UDP_HIT == l)
                 icp_hits += c->Icp.result_hist[l];
 
-            storeAppendPrintf(sentry, "        %-20.20s %7d %3d%%\n",Format::log_tags[l], c->Icp.result_hist[l], Math::intPercent(c->Icp.result_hist[l], c->Icp.n_requests));
+            storeAppendPrintf(sentry, "        %-20.20s %7d %3d%%\n", LogTags(l).c_str(), c->Icp.result_hist[l], Math::intPercent(c->Icp.result_hist[l], c->Icp.n_requests));
         }
 
         storeAppendPrintf(sentry, "    HTTP Requests %d\n", c->Http.n_requests);
 
-        for (l = LOG_TAG_NONE; l < LOG_TYPE_MAX; ++l) {
+        for (LogTags_ot l = LOG_TAG_NONE; l < LOG_TYPE_MAX; ++l) {
             if (c->Http.result_hist[l] == 0)
                 continue;
 
             http_total += c->Http.result_hist[l];
 
-            if (logTypeIsATcpHit(l))
+            if (LogTags(l).isTcpHit())
                 http_hits += c->Http.result_hist[l];
 
             storeAppendPrintf(sentry,
                               "        %-20.20s %7d %3d%%\n",
-                              Format::log_tags[l],
+                              LogTags(l).c_str(),
                               c->Http.result_hist[l],
                               Math::intPercent(c->Http.result_hist[l], c->Http.n_requests));
         }
@@ -353,16 +330,21 @@ static void
 clientdbFreeItem(void *data)
 {
     ClientInfo *c = (ClientInfo *)data;
-    safe_free(c->hash.key);
+    delete c;
+}
+
+ClientInfo::~ClientInfo()
+{
+    safe_free(key);
 
 #if USE_DELAY_POOLS
-    if (CommQuotaQueue *q = c->quotaQueue) {
+    if (CommQuotaQueue *q = quotaQueue) {
         q->clientInfo = NULL;
         delete q; // invalidates cbdata, cancelling any pending kicks
     }
 #endif
 
-    memFree(c, MEM_CLIENT_INFO);
+    debugs(77, 9, "ClientInfo destructed, this=" << static_cast<void*>(this));
 }
 
 void
@@ -374,14 +356,14 @@ clientdbFreeMemory(void)
 }
 
 static void
-clientdbScheduledGC(void *unused)
+clientdbScheduledGC(void *)
 {
     cleanup_scheduled = 0;
     clientdbStartGC();
 }
 
 static void
-clientdbGC(void *unused)
+clientdbGC(void *)
 {
     static int bucket = 0;
     hash_link *link_next;
@@ -408,7 +390,7 @@ clientdbGC(void *unused)
         if (age < 60)
             continue;
 
-        hash_remove_link(client_table, &c->hash);
+        hash_remove_link(client_table, static_cast<hash_link*>(c));
 
         clientdbFreeItem(c);
 
@@ -447,30 +429,22 @@ clientdbStartGC(void)
 Ip::Address *
 client_entry(Ip::Address *current)
 {
-    ClientInfo *c = NULL;
     char key[MAX_IPSTRLEN];
+    hash_first(client_table);
 
     if (current) {
-        current->NtoA(key,MAX_IPSTRLEN);
-        hash_first(client_table);
-        while ((c = (ClientInfo *) hash_next(client_table))) {
-            if (!strcmp(key, hashKeyStr(&c->hash)))
+        current->toStr(key,MAX_IPSTRLEN);
+        while (hash_link *hash = hash_next(client_table)) {
+            if (!strcmp(key, hashKeyStr(hash)))
                 break;
         }
-
-        c = (ClientInfo *) hash_next(client_table);
-    } else {
-        hash_first(client_table);
-        c = (ClientInfo *) hash_next(client_table);
     }
 
-    hash_last(client_table);
+    ClientInfo *c = static_cast<ClientInfo *>(hash_next(client_table));
 
-    if (c)
-        return (&c->addr);
-    else
-        return (NULL);
+    hash_last(client_table);
 
+    return c ? &c->addr : nullptr;
 }
 
 variable_list *
@@ -492,7 +466,7 @@ snmp_meshCtblFn(variable_list * Var, snint * ErrP)
         return NULL;
     }
 
-    keyIp.NtoA(key, sizeof(key));
+    keyIp.toStr(key, sizeof(key));
     debugs(49, 5, HERE << "[" << key << "] requested!");
     c = (ClientInfo *) hash_lookup(client_table, key);
 
@@ -504,13 +478,12 @@ snmp_meshCtblFn(variable_list * Var, snint * ErrP)
 
     variable_list *Answer = NULL;
     int aggr = 0;
-    log_type l;
 
     switch (Var->name[LEN_SQ_NET + 2]) {
 
     case MESH_CTBL_ADDR_TYPE: {
         int ival;
-        ival = c->addr.IsIPv4() ? INETADDRESSTYPE_IPV4 : INETADDRESSTYPE_IPV6 ;
+        ival = c->addr.isIPv4() ? INETADDRESSTYPE_IPV4 : INETADDRESSTYPE_IPV6 ;
         Answer = snmp_var_new_integer(Var->name, Var->name_length,
                                       ival, SMI_INTEGER);
     }
@@ -523,7 +496,7 @@ snmp_meshCtblFn(variable_list * Var, snint * ErrP)
         // See: rfc4001.txt
         Answer->type = ASN_OCTET_STR;
         char client[MAX_IPSTRLEN];
-        c->addr.NtoA(client,MAX_IPSTRLEN);
+        c->addr.toStr(client,MAX_IPSTRLEN);
         Answer->val_len = strlen(client);
         Answer->val.string =  (u_char *) xstrdup(client);
     }
@@ -543,8 +516,8 @@ snmp_meshCtblFn(variable_list * Var, snint * ErrP)
     case MESH_CTBL_HTHITS:
         aggr = 0;
 
-        for (l = LOG_TAG_NONE; l < LOG_TYPE_MAX; ++l) {
-            if (logTypeIsATcpHit(l))
+        for (LogTags_ot l = LOG_TAG_NONE; l < LOG_TYPE_MAX; ++l) {
+            if (LogTags(l).isTcpHit())
                 aggr += c->Http.result_hist[l];
         }
 
@@ -594,3 +567,4 @@ snmp_meshCtblFn(variable_list * Var, snint * ErrP)
 }
 
 #endif /*SQUID_SNMP */
+