#include "hash.h"
#include "ip/Address.h"
#include "LogTags.h"
+#include "mem/forward.h"
#include "typedefs.h"
#include <deque>
class ClientInfo
{
+ MEMPROXY_CLASS(ClientInfo);
+
public:
+ explicit ClientInfo(const Ip::Address &);
+ ~ClientInfo();
+
hash_link hash; /* must be first */
Ip::Address addr;
- struct {
+ struct Protocol {
+ Protocol() : n_requests(0) {
+ memset(result_hist, 0, sizeof(result_hist));
+ }
+
int result_hist[LOG_TYPE_MAX];
int n_requests;
ByteCounter kbytes_in;
ByteCounter hit_kbytes_out;
} Http, Icp;
- struct {
+ struct Cutoff {
+ Cutoff() : time(0), n_req(0), n_denied(0) {}
+
time_t time;
int n_req;
int n_denied;
HttpHdrContRange *
httpHdrContRangeCreate(void)
{
- HttpHdrContRange *r = (HttpHdrContRange *)memAllocate(MEM_HTTP_HDR_CONTENT_RANGE);
+ HttpHdrContRange *r = new HttpHdrContRange;
r->spec.offset = r->spec.length = range_spec_unknown;
r->elength = range_spec_unknown;
return r;
HttpHdrContRange *r = httpHdrContRangeCreate();
if (!httpHdrContRangeParseInit(r, str)) {
- httpHdrContRangeDestroy(r);
- r = NULL;
+ delete r;
+ return nullptr;
}
return r;
return 1;
}
-void
-httpHdrContRangeDestroy(HttpHdrContRange * range)
-{
- assert(range);
- memFree(range, MEM_HTTP_HDR_CONTENT_RANGE);
-}
-
HttpHdrContRange *
httpHdrContRangeDup(const HttpHdrContRange * range)
{
#ifndef SQUID_HTTPHDRCONTRANGE_H
#define SQUID_HTTPHDRCONTRANGE_H
-class HttpHeader;
-
-/* for HttpHdrRangeSpec */
#include "HttpHeaderRange.h"
+class HttpHeader;
+
/** HTTP Content-Range: header field */
class HttpHdrContRange
{
+ MEMPROXY_CLASS(HttpHdrContRange);
public:
+ HttpHdrContRange() : elength(0) {}
+
HttpHdrRangeSpec spec;
int64_t elength; /**< entity length, not content length */
};
HttpHdrContRange *httpHdrContRangeParseCreate(const char *crange_spec);
/** returns true if range is valid; inits HttpHdrContRange */
int httpHdrContRangeParseInit(HttpHdrContRange * crange, const char *crange_spec);
-void httpHdrContRangeDestroy(HttpHdrContRange * crange);
HttpHdrContRange *httpHdrContRangeDup(const HttpHdrContRange * crange);
void httpHdrContRangePackInto(const HttpHdrContRange * crange, Packable * p);
/** inits with given spec */
assert(hdr && ent_len >= 0);
httpHdrContRangeSet(cr, spec, ent_len);
hdr->putContRange(cr);
- httpHdrContRangeDestroy(cr);
+ delete cr;
}
/**
}
if (content_range) {
- httpHdrContRangeDestroy(content_range);
+ delete content_range;
content_range = NULL;
}
}
#include "AccessLogEntry.h"
#include "acl/Checklist.h"
-#include "cbdata.h"
+#include "base/CbcPointer.h"
#include "comm/forward.h"
#include "hier_code.h"
#include "ip/Address.h"
+#include "mem/forward.h"
#include "PingData.h"
class HttpRequest;
*/
class FwdServer
{
+ MEMPROXY_CLASS(FwdServer);
+
public:
- CachePeer *_peer; /* NULL --> origin server */
+ FwdServer(CachePeer *p, hier_code c) :
+ _peer(p),
+ code(c),
+ next(nullptr)
+ {}
+
+ CbcPointer<CachePeer> _peer; /* NULL --> origin server */
hier_code code;
FwdServer *next;
};
#define CLIENT_DB_HASH_SIZE 467
#endif
-static ClientInfo *
-
-clientdbAdd(const Ip::Address &addr)
+ClientInfo::ClientInfo(const Ip::Address &ip) :
+ addr(ip),
+ n_established(0),
+ last_seen(0)
+#if USE_DELAY_POOLS
+ , writeSpeedLimit(0),
+ prevTime(0),
+ bucketSize(0),
+ bucketSizeLimit(0),
+ writeLimitingActive(false),
+ firstTimeConnection(true),
+ quotaQueue(nullptr),
+ rationedQuota(0),
+ rationedCount(0),
+ selectWaiting(false),
+ eventWaiting(false)
+#endif
{
- ClientInfo *c;
- char *buf = static_cast<char*>(xmalloc(MAX_IPSTRLEN)); // becomes hash.key
- c = (ClientInfo *)memAllocate(MEM_CLIENT_INFO);
- debugs(77, 9, "ClientInfo constructed, this=" << c);
- c->hash.key = addr.toStr(buf,MAX_IPSTRLEN);
- c->addr = addr;
+ debugs(77, 9, "ClientInfo constructed, this=" << static_cast<void*>(this));
+
#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 */
+ /* put current time to have something sensible here */
+ prevTime = current_dtime;
#endif
+
+ char *buf = static_cast<char*>(xmalloc(MAX_IPSTRLEN)); // becomes hash.key
+ hash.key = addr.toStr(buf,MAX_IPSTRLEN);
+}
+
+static ClientInfo *
+clientdbAdd(const Ip::Address &addr)
+{
+ ClientInfo *c = new ClientInfo(addr);
hash_join(client_table, &c->hash);
++statCounter.client_http.clients;
clientdbFreeItem(void *data)
{
ClientInfo *c = (ClientInfo *)data;
- safe_free(c->hash.key);
+ delete c;
+}
+
+ClientInfo::~ClientInfo()
+{
+ safe_free(hash.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
- debugs(77, 9, "ClientInfo destructed, this=" << c);
- memFree(c, MEM_CLIENT_INFO);
+ debugs(77, 9, "ClientInfo destructed, this=" << static_cast<void*>(this));
}
void
}
if (!init) {
- memDataInit(MEM_IDNS_QUERY, "idns_query", sizeof(idns_query), 0);
memset(RcodeMatrix, '\0', sizeof(RcodeMatrix));
idns_lookup_hash = hash_create((HASHCMP *) strcmp, 103, hash_string);
++init;
#define FQDN_HIGH_WATER 95
/**
- \ingroup FQDNCacheAPI
* The data structure used for storing name-address mappings
* is a small hashtable (static hash_table *fqdn_table),
* where structures of type fqdncache_entry whose most
*/
class fqdncache_entry
{
+ MEMPROXY_CLASS(fqdncache_entry);
+
public:
+ fqdncache_entry(const char *name);
+ ~fqdncache_entry();
+
hash_link hash; /* must be first */
time_t lastref;
time_t expires;
dlink_node lru;
unsigned short locks;
- struct {
+ struct Flags {
+ Flags() : negcached(false), fromhosts(false) {}
+
bool negcached;
bool fromhosts;
} flags;
static IDNSCB fqdncacheHandleReply;
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);
static fqdncache_entry *fqdncache_get(const char *);
static int fqdncacheExpiredEntry(const fqdncache_entry *);
static void
fqdncacheRelease(fqdncache_entry * f)
{
- int k;
hash_remove_link(fqdn_table, (hash_link *) f);
-
- 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) << "'.");
-
dlinkDelete(&f->lru, &lru_list);
-
- safe_free(f->hash.key);
-
- safe_free(f->error_message);
-
- memFree(f, MEM_FQDNCACHE_ENTRY);
+ delete f;
}
/**
fqdncacheRelease(i);
}
-/**
- \ingroup FQDNCacheInternal
- *
- * Create blank fqdncache_entry
- */
-static fqdncache_entry *
-fqdncacheCreateEntry(const char *name)
+fqdncache_entry::fqdncache_entry(const char *name) :
+ lastref(0),
+ expires(squid_curtime + Config.negativeDnsTtl),
+ name_count(0),
+ handler(nullptr),
+ handlerData(nullptr),
+ error_message(nullptr),
+ locks(0) // XXX: use Lock
{
- static fqdncache_entry *f;
- f = (fqdncache_entry *)memAllocate(MEM_FQDNCACHE_ENTRY);
- f->hash.key = xstrdup(name);
- f->expires = squid_curtime + Config.negativeDnsTtl;
- return f;
+ hash.key = xstrdup(name);
+
+ memset(&request_time, 0, sizeof(request_time));
+ memset(&names, 0, sizeof(names));
}
/// \ingroup FQDNCacheInternal
debugs(35, 5, "fqdncache_nbgethostbyaddr: MISS for '" << name << "'");
++ FqdncacheStats.misses;
- f = fqdncacheCreateEntry(name);
+ f = new fqdncache_entry(name);
f->handler = handler;
f->handlerData = cbdataReference(handlerData);
f->request_time = current_time;
storeAppendPrintf(sentry, "FQDN Cache Statistics:\n");
storeAppendPrintf(sentry, "FQDNcache Entries In Use: %d\n",
- memInUse(MEM_FQDNCACHE_ENTRY));
+ fqdncache_entry::UseCount());
storeAppendPrintf(sentry, "FQDNcache Entries Cached: %d\n",
fqdncacheCount());
fqdncacheFreeEntry(void *data)
{
fqdncache_entry *f = (fqdncache_entry *)data;
- int k;
-
- for (k = 0; k < (int) f->name_count; ++k)
- safe_free(f->names[k]);
-
- safe_free(f->hash.key);
+ delete f;
+}
- safe_free(f->error_message);
+fqdncache_entry::~fqdncache_entry()
+{
+ for (int k = 0; k < (int)name_count; ++k)
+ xfree(names[k]);
- memFree(f, MEM_FQDNCACHE_ENTRY);
+ xfree(hash.key);
+ xfree(error_message);
}
/// \ingroup FQDNCacheAPI
}
}
- fce = fqdncacheCreateEntry(addr);
+ fce = new fqdncache_entry(addr);
while (hostnames) {
fce->names[j] = xstrdup(hostnames->key);
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
hash_remove_link(addr_table, hptr);
}
+net_db_name::net_db_name(const char *hostname, netdbEntry *e) :
+ next(e ? e->hosts : nullptr),
+ net_db_entry(e)
+{
+ if (e) {
+ e->hosts = this;
+ ++ e->link_count;
+ }
+}
+
static void
netdbHostInsert(netdbEntry * n, const char *hostname)
{
- net_db_name *x = (net_db_name *)memAllocate(MEM_NET_DB_NAME);
- x->hash.key = xstrdup(hostname);
- x->next = n->hosts;
- n->hosts = x;
- x->net_db_entry = n;
+ net_db_name *x = new net_db_name(hostname, n);
assert(hash_lookup(host_table, hostname) == NULL);
hash_join(host_table, &x->hash);
- ++ n->link_count;
}
static void
netdbHostDelete(const net_db_name * x)
{
- netdbEntry *n;
- net_db_name **X;
assert(x != NULL);
assert(x->net_db_entry != NULL);
- n = x->net_db_entry;
+
+ netdbEntry *n = x->net_db_entry;
-- n->link_count;
- for (X = &n->hosts; *X; X = &(*X)->next) {
+ for (auto **X = &n->hosts; *X; X = &(*X)->next) {
if (*X == x) {
*X = x->next;
break;
}
hash_remove_link(host_table, (hash_link *) x);
- xfree(x->hash.key);
- memFree((void *) x, MEM_NET_DB_NAME);
+ delete x;
}
static netdbEntry *
netdbFreeNameEntry(void *data)
{
net_db_name *x = (net_db_name *)data;
- xfree(x->hash.key);
- memFree(x, MEM_NET_DB_NAME);
+ delete x;
}
static void
#include "hash.h"
#include "ip/forward.h"
+#include "mem/forward.h"
class CachePeer;
class HttpRequest;
class StoreEntry;
class URL;
-// POD
class net_db_name
{
+ MEMPROXY_CLASS(net_db_name);
+
public:
+ net_db_name(const char *name, netdbEntry *);
+ ~net_db_name() {xfree(hash.key);}
+
hash_link hash; /* must be first */
net_db_name *next;
netdbEntry *net_db_entry;
*/
class ipcache_entry
{
+ MEMPROXY_CLASS(ipcache_entry);
+
public:
+ ipcache_entry(const char *);
+ ~ipcache_entry();
+
hash_link hash; /* must be first */
time_t lastref;
time_t expires;
struct timeval request_time;
dlink_node lru;
unsigned short locks;
- struct {
+ struct Flags {
+ Flags() : negcached(false), fromhosts(false) {}
+
bool negcached;
bool fromhosts;
} flags;
ipcacheRelease(i);
}
-/**
- \ingroup IPCacheInternal
- *
- * create blank ipcache_entry
- */
-static ipcache_entry *
-ipcacheCreateEntry(const char *name)
+ipcache_entry::ipcache_entry(const char *name) :
+ lastref(0),
+ expires(0),
+ handler(nullptr),
+ handlerData(nullptr),
+ error_message(nullptr),
+ locks(0) // XXX: use Lock type ?
{
- static ipcache_entry *i;
- i = (ipcache_entry *)memAllocate(MEM_IPCACHE_ENTRY);
- i->hash.key = xstrdup(name);
- Tolower(static_cast<char*>(i->hash.key));
- i->expires = squid_curtime + Config.negativeDnsTtl;
- return i;
+ hash.key = xstrdup(name);
+ Tolower(static_cast<char*>(hash.key));
+ expires = squid_curtime + Config.negativeDnsTtl;
+
+ memset(&request_time, 0, sizeof(request_time));
}
/// \ingroup IPCacheInternal
debugs(14, 5, "ipcache_nbgethostbyname: MISS for '" << name << "'");
++IpcacheStats.misses;
- i = ipcacheCreateEntry(name);
+ i = new ipcache_entry(name);
i->handler = handler;
i->handlerData = cbdataReference(handlerData);
i->request_time = current_time;
(float) Config.ipcache.low) / (float) 100);
n = hashPrime(ipcache_high / 4);
ip_table = hash_create((HASHCMP *) strcmp, n, hash4);
- memDataInit(MEM_IPCACHE_ENTRY, "ipcache_entry", sizeof(ipcache_entry), 0);
ipcacheRegisterWithCacheManager();
}
assert(ip_table != NULL);
storeAppendPrintf(sentry, "IP Cache Statistics:\n");
storeAppendPrintf(sentry, "IPcache Entries In Use: %d\n",
- memInUse(MEM_IPCACHE_ENTRY));
+ ipcache_entry::UseCount());
storeAppendPrintf(sentry, "IPcache Entries Cached: %d\n",
ipcacheCount());
storeAppendPrintf(sentry, "IPcache Requests: %d\n",
ipcacheFreeEntry(void *data)
{
ipcache_entry *i = (ipcache_entry *)data;
- safe_free(i->addrs.in_addrs);
- safe_free(i->addrs.bad_mask);
- safe_free(i->hash.key);
- safe_free(i->error_message);
- memFree(i, MEM_IPCACHE_ENTRY);
+ delete i;
+}
+
+ipcache_entry::~ipcache_entry()
+{
+ xfree(addrs.in_addrs);
+ xfree(addrs.bad_mask);
+ xfree(error_message);
+ xfree(hash.key);
}
/// \ingroup IPCacheAPI
}
}
- i = ipcacheCreateEntry(name);
+ i = new ipcache_entry(name);
i->addrs.count = 1;
i->addrs.cur = 0;
i->addrs.badcount = 0;
#define _SQUID_IPCACHE_H
#include "dns/forward.h"
+#include "ip/forward.h"
-namespace Ip
+class ipcache_addrs
{
-class Address;
-}
+public:
+ ipcache_addrs() : in_addrs(nullptr), bad_mask(nullptr), count(0), cur(0), badcount(0) {}
-typedef struct _ipcache_addrs {
Ip::Address *in_addrs;
unsigned char *bad_mask;
unsigned char count;
unsigned char cur;
unsigned char badcount;
-} ipcache_addrs;
+};
typedef void IPH(const ipcache_addrs *, const Dns::LookupDetails &details, void *);
#include "base/Subscription.h"
#include "base/TextException.h"
#include "cache_cf.h"
+#include "CachePeer.h"
#include "carp.h"
#include "client_db.h"
#include "client_side.h"
MEM_64K_BUF,
MEM_ACL_DENY_INFO_LIST,
MEM_ACL_NAME_LIST,
- MEM_CLIENT_INFO,
MEM_LINK_LIST,
MEM_DLINK_NODE,
MEM_DREAD_CTRL,
MEM_DWRITE_Q,
- MEM_HTTP_HDR_CONTENT_RANGE,
MEM_MD5_DIGEST,
MEM_NETDBENTRY,
- MEM_NET_DB_NAME,
- // IMPORTANT: leave this here. pools above are initialized early with memInit()
- MEM_DONTFREE,
- // following pools are initialized late by their component if needed (or never)
- MEM_FQDNCACHE_ENTRY,
- MEM_FWD_SERVER,
- MEM_IDNS_QUERY,
- MEM_IPCACHE_ENTRY,
MEM_MAX
} mem_type;
MemPools::GetInstance().setIdleLimit(new_pool_limit);
}
-/* XXX make these classes do their own memory management */
-#include "HttpHdrContRange.h"
-
void
Mem::Init(void)
{
memDataInit(MEM_DLINK_NODE, "dlink_node", sizeof(dlink_node), 10);
memDataInit(MEM_DREAD_CTRL, "dread_ctrl", sizeof(dread_ctrl), 0);
memDataInit(MEM_DWRITE_Q, "dwrite_q", sizeof(dwrite_q), 0);
- memDataInit(MEM_HTTP_HDR_CONTENT_RANGE, "HttpHdrContRange", sizeof(HttpHdrContRange), 0);
memDataInit(MEM_NETDBENTRY, "netdbEntry", sizeof(netdbEntry), 0);
- memDataInit(MEM_NET_DB_NAME, "net_db_name", sizeof(net_db_name), 0);
- memDataInit(MEM_CLIENT_INFO, "ClientInfo", sizeof(ClientInfo), 0);
memDataInit(MEM_MD5_DIGEST, "MD5 digest", SQUID_MD5_DIGEST_LENGTH, 0);
GetPool(MEM_MD5_DIGEST)->setChunkSize(512 * 1024);
{
mem_type t = MEM_NONE;
- while (++t < MEM_DONTFREE) {
+ while (++t < MEM_MAX) {
/*
* If you hit this assertion, then you forgot to add a
* memDataInit() line for type 't'.
- * Or placed the pool type in the wrong section of the enum list.
*/
assert(GetPool(t));
}
{
while (servers) {
FwdServer *next = servers->next;
- cbdataReferenceDone(servers->_peer);
- memFree(servers, MEM_FWD_SERVER);
+ delete servers;
servers = next;
}
Comm::ConnectionPointer p = new Comm::Connection();
p->remote = req->clientConnectionManager->clientConnection->local;
p->peerType = ORIGINAL_DST; // fs->code is DIRECT. This fixes the display.
- p->setPeer(fs->_peer);
+ p->setPeer(fs->_peer.get());
// check for a configured outgoing address for this destination...
getOutgoingAddress(psstate->request, p);
// clear the used fs and continue
psstate->servers = fs->next;
- cbdataReferenceDone(fs->_peer);
- memFree(fs, MEM_FWD_SERVER);
+ delete fs;
peerSelectDnsPaths(psstate);
return;
}
// convert the list of FwdServer destinations into destinations IP addresses
if (fs && psstate->paths->size() < (unsigned int)Config.forward_max_tries) {
// send the next one off for DNS lookup.
- const char *host = fs->_peer ? fs->_peer->host : psstate->request->url.host();
+ const char *host = fs->_peer.valid() ? fs->_peer->host : psstate->request->url.host();
debugs(44, 2, "Find IP destination for: " << psstate->url() << "' via " << host);
ipcache_nbgethostbyname(host, peerSelectDnsResults, psstate);
return;
assert(fs == psstate->servers);
while (fs) {
psstate->servers = fs->next;
- cbdataReferenceDone(fs->_peer);
- memFree(fs, MEM_FWD_SERVER);
+ delete fs;
fs = psstate->servers;
}
}
break;
// for TPROXY spoofing we must skip unusable addresses.
- if (psstate->request->flags.spoofClientIp && !(fs->_peer && fs->_peer->options.no_tproxy) ) {
+ if (psstate->request->flags.spoofClientIp && !(fs->_peer.valid() && fs->_peer->options.no_tproxy) ) {
if (ia->in_addrs[ip].isIPv4() != psstate->request->client_addr.isIPv4()) {
// we CAN'T spoof the address on this link. find another.
continue;
// when IPv6 is disabled we cannot use it
if (!Ip::EnableIpv6 && p->remote.isIPv6()) {
- const char *host = (fs->_peer ? fs->_peer->host : psstate->request->url.host());
+ const char *host = (fs->_peer.valid() ? fs->_peer->host : psstate->request->url.host());
ipcacheMarkBadAddr(host, p->remote);
continue;
}
- p->remote.port(fs->_peer ? fs->_peer->http_port : psstate->request->url.port());
+ p->remote.port(fs->_peer.valid() ? fs->_peer->http_port : psstate->request->url.port());
p->peerType = fs->code;
- p->setPeer(fs->_peer);
+ p->setPeer(fs->_peer.get());
// check for a configured outgoing address for this destination...
getOutgoingAddress(psstate->request, p);
psstate->paths->push_back(p);
}
} else {
- debugs(44, 3, "Unknown host: " << (fs->_peer ? fs->_peer->host : psstate->request->url.host()));
+ debugs(44, 3, "Unknown host: " << (fs->_peer.valid() ? fs->_peer->host : psstate->request->url.host()));
// discard any previous error.
delete psstate->lastError;
psstate->lastError = NULL;
}
psstate->servers = fs->next;
- cbdataReferenceDone(fs->_peer);
- memFree(fs, MEM_FWD_SERVER);
+ delete fs;
// see if more paths can be found
peerSelectDnsPaths(psstate);
peerSelectInit(void)
{
memset(&PeerStats, '\0', sizeof(PeerStats));
- memDataInit(MEM_FWD_SERVER, "FwdServer", sizeof(FwdServer), 0);
}
static void
static void
peerAddFwdServer(FwdServer ** FSVR, CachePeer * p, hier_code code)
{
- FwdServer *fs = (FwdServer *)memAllocate(MEM_FWD_SERVER);
debugs(44, 5, "peerAddFwdServer: adding " <<
(p ? p->host : "DIRECT") << " " <<
hier_code_str[code] );
- fs->_peer = cbdataReference(p);
- fs->code = code;
+ FwdServer *fs = new FwdServer(p, code);
while (*FSVR)
FSVR = &(*FSVR)->next;