/* * Copyright (C) 1996-2023 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. */ #include "squid.h" #include "base/PackableStream.h" #include "mgr/Registration.h" #include "ssl/context_storage.h" #include "Store.h" #include #if USE_OPENSSL #include "compat/openssl.h" #if HAVE_OPENSSL_SSL_H #include #endif #endif Ssl::CertificateStorageAction::CertificateStorageAction(const Mgr::Command::Pointer &aCmd) : Mgr::Action(aCmd) {} Ssl::CertificateStorageAction::Pointer Ssl::CertificateStorageAction::Create(const Mgr::Command::Pointer &aCmd) { return new CertificateStorageAction(aCmd); } void Ssl::CertificateStorageAction::dump (StoreEntry *sentry) { PackableStream stream(*sentry); const char delimiter = '\t'; const char endString = '\n'; // Page title. stream << "Cached ssl certificates statistic.\n"; // Title of statistic table. stream << "Port" << delimiter << "Max mem(KB)" << delimiter << "Cert number" << delimiter << "KB/cert" << delimiter << "Mem used(KB)" << delimiter << "Mem free(KB)" << endString; // Add info for each port. for (std::map::iterator i = TheGlobalContextStorage.storage.begin(); i != TheGlobalContextStorage.storage.end(); ++i) { stream << i->first << delimiter; LocalContextStorage & ssl_store_policy(*(i->second)); const auto memoryPerEntry = ssl_store_policy.entries() ? ssl_store_policy.memoryUsed() / ssl_store_policy.entries() : 0; stream << ssl_store_policy.memLimit() / 1024 << delimiter; stream << ssl_store_policy.entries() << delimiter; stream << memoryPerEntry / 1024 << delimiter; stream << ssl_store_policy.memoryUsed() / 1024 << delimiter; stream << ssl_store_policy.freeMem() / 1024 << endString; } stream << endString; stream.flush(); } /////////////////////////////////////////////////////// Ssl::GlobalContextStorage::GlobalContextStorage() : reconfiguring(true) { RegisterAction("cached_ssl_cert", "Statistic of cached generated ssl certificates", &CertificateStorageAction::Create, 0, 1); } Ssl::GlobalContextStorage::~GlobalContextStorage() { for (std::map::iterator i = storage.begin(); i != storage.end(); ++i) { delete i->second; } } void Ssl::GlobalContextStorage::addLocalStorage(Ip::Address const & address, size_t size_of_store) { assert(reconfiguring); configureStorage.insert(std::pair(address, size_of_store)); } Ssl::LocalContextStorage *Ssl::GlobalContextStorage::getLocalStorage(Ip::Address const & address) { reconfigureFinish(); std::map::iterator i = storage.find(address); if (i == storage.end()) return nullptr; else return i->second; } void Ssl::GlobalContextStorage::reconfigureStart() { configureStorage.clear(); reconfiguring = true; } void Ssl::GlobalContextStorage::reconfigureFinish() { if (reconfiguring) { reconfiguring = false; // remove or change old local storages. for (std::map::iterator i = storage.begin(); i != storage.end();) { std::map::iterator conf_i = configureStorage.find(i->first); if (conf_i == configureStorage.end() || conf_i->second <= 0) { delete i->second; storage.erase(i++); } else { i->second->setMemLimit(conf_i->second); ++i; } } // add new local storages. for (std::map::iterator conf_i = configureStorage.begin(); conf_i != configureStorage.end(); ++conf_i ) { if (storage.find(conf_i->first) == storage.end() && conf_i->second > 0) { storage.insert(std::pair(conf_i->first, new LocalContextStorage(conf_i->second))); } } } } Ssl::GlobalContextStorage Ssl::TheGlobalContextStorage;