]>
Commit | Line | Data |
---|---|---|
1 | /* | |
2 | * Copyright (C) 1996-2025 The Squid Software Foundation and contributors | |
3 | * | |
4 | * Squid software is distributed under GPLv2+ license and includes | |
5 | * contributions from numerous individuals and organizations. | |
6 | * Please see the COPYING and CONTRIBUTORS files for details. | |
7 | */ | |
8 | ||
9 | #include "squid.h" | |
10 | #include "base/PackableStream.h" | |
11 | #include "mgr/Registration.h" | |
12 | #include "ssl/context_storage.h" | |
13 | #include "Store.h" | |
14 | ||
15 | #include <limits> | |
16 | #if USE_OPENSSL | |
17 | #include "compat/openssl.h" | |
18 | #if HAVE_OPENSSL_SSL_H | |
19 | #include <openssl/ssl.h> | |
20 | #endif | |
21 | #endif | |
22 | ||
23 | Ssl::CertificateStorageAction::CertificateStorageAction(const Mgr::Command::Pointer &aCmd) | |
24 | : Mgr::Action(aCmd) | |
25 | {} | |
26 | ||
27 | Ssl::CertificateStorageAction::Pointer | |
28 | Ssl::CertificateStorageAction::Create(const Mgr::Command::Pointer &aCmd) | |
29 | { | |
30 | return new CertificateStorageAction(aCmd); | |
31 | } | |
32 | ||
33 | void Ssl::CertificateStorageAction::dump (StoreEntry *sentry) | |
34 | { | |
35 | PackableStream stream(*sentry); | |
36 | const char delimiter = '\t'; | |
37 | const char endString = '\n'; | |
38 | // Page title. | |
39 | stream << "Cached ssl certificates statistic.\n"; | |
40 | // Title of statistic table. | |
41 | stream << "Port" << delimiter << "Max mem(KB)" << delimiter << "Cert number" << delimiter << "KB/cert" << delimiter << "Mem used(KB)" << delimiter << "Mem free(KB)" << endString; | |
42 | ||
43 | // Add info for each port. | |
44 | for (const auto &i: TheGlobalContextStorage().storage) { | |
45 | stream << i.first << delimiter; | |
46 | const auto &ssl_store_policy = *i.second; | |
47 | const auto memoryPerEntry = ssl_store_policy.entries() ? | |
48 | ssl_store_policy.memoryUsed() / ssl_store_policy.entries() : 0; | |
49 | stream << ssl_store_policy.memLimit() / 1024 << delimiter; | |
50 | stream << ssl_store_policy.entries() << delimiter; | |
51 | stream << memoryPerEntry / 1024 << delimiter; | |
52 | stream << ssl_store_policy.memoryUsed() / 1024 << delimiter; | |
53 | stream << ssl_store_policy.freeMem() / 1024 << endString; | |
54 | } | |
55 | stream << endString; | |
56 | stream.flush(); | |
57 | } | |
58 | ||
59 | /////////////////////////////////////////////////////// | |
60 | ||
61 | Ssl::GlobalContextStorage::GlobalContextStorage() | |
62 | : reconfiguring(true) | |
63 | { | |
64 | RegisterAction("cached_ssl_cert", "Statistic of cached generated ssl certificates", &CertificateStorageAction::Create, 0, 1); | |
65 | } | |
66 | ||
67 | Ssl::GlobalContextStorage::~GlobalContextStorage() | |
68 | { | |
69 | for (std::map<Ip::Address, LocalContextStorage *>::iterator i = storage.begin(); i != storage.end(); ++i) { | |
70 | delete i->second; | |
71 | } | |
72 | } | |
73 | ||
74 | void Ssl::GlobalContextStorage::addLocalStorage(Ip::Address const & address, size_t size_of_store) | |
75 | { | |
76 | assert(reconfiguring); | |
77 | configureStorage.insert(std::pair<Ip::Address, size_t>(address, size_of_store)); | |
78 | } | |
79 | ||
80 | Ssl::LocalContextStorage *Ssl::GlobalContextStorage::getLocalStorage(Ip::Address const & address) | |
81 | { | |
82 | reconfigureFinish(); | |
83 | std::map<Ip::Address, LocalContextStorage *>::iterator i = storage.find(address); | |
84 | ||
85 | if (i == storage.end()) | |
86 | return nullptr; | |
87 | else | |
88 | return i->second; | |
89 | } | |
90 | ||
91 | void Ssl::GlobalContextStorage::reconfigureStart() | |
92 | { | |
93 | configureStorage.clear(); | |
94 | reconfiguring = true; | |
95 | } | |
96 | ||
97 | void Ssl::GlobalContextStorage::reconfigureFinish() | |
98 | { | |
99 | if (reconfiguring) { | |
100 | reconfiguring = false; | |
101 | ||
102 | // remove or change old local storages. | |
103 | for (std::map<Ip::Address, LocalContextStorage *>::iterator i = storage.begin(); i != storage.end();) { | |
104 | std::map<Ip::Address, size_t>::iterator conf_i = configureStorage.find(i->first); | |
105 | if (conf_i == configureStorage.end() || conf_i->second <= 0) { | |
106 | delete i->second; | |
107 | storage.erase(i++); | |
108 | } else { | |
109 | i->second->setMemLimit(conf_i->second); | |
110 | ++i; | |
111 | } | |
112 | } | |
113 | ||
114 | // add new local storages. | |
115 | for (std::map<Ip::Address, size_t>::iterator conf_i = configureStorage.begin(); conf_i != configureStorage.end(); ++conf_i ) { | |
116 | if (storage.find(conf_i->first) == storage.end() && conf_i->second > 0) { | |
117 | storage.insert(std::pair<Ip::Address, LocalContextStorage *>(conf_i->first, new LocalContextStorage(conf_i->second))); | |
118 | } | |
119 | } | |
120 | } | |
121 | } | |
122 | ||
123 | Ssl::GlobalContextStorage & | |
124 | Ssl::TheGlobalContextStorage() | |
125 | { | |
126 | static const auto storage = new GlobalContextStorage(); | |
127 | return *storage; | |
128 | } | |
129 |