Kea: lease_mgr.cc Source File

| Kea 2.2.0

lease_mgr.cc
Go to the documentation of this file.
1// Copyright (C) 2012-2020 Internet Systems Consortium, Inc. ("ISC")
2//
3// This Source Code Form is subject to the terms of the Mozilla Public
4// License, v. 2.0. If a copy of the MPL was not distributed with this
5// file, You can obtain one at http://mozilla.org/MPL/2.0/.
6
7#include <config.h>
8
9#include <dhcpsrv/cfgmgr.h>
10#include <dhcpsrv/dhcpsrv_log.h>
11#include <dhcpsrv/lease_mgr.h>
12#include <exceptions/exceptions.h>
13#include <stats/stats_mgr.h>
14
15#include <boost/foreach.hpp>
16#include <boost/algorithm/string.hpp>
17
18#include <algorithm>
19#include <iostream>
20#include <iterator>
21#include <map>
22#include <sstream>
23#include <string>
24
25#include <time.h>
26
27using namespace isc::asiolink;
28using namespace isc::db;
29using namespace std;
30
31namespace isc {
32namespace dhcp {
33
34 IOServicePtr LeaseMgr::io_service_ = IOServicePtr();
35
36LeasePageSize::LeasePageSize(const size_t page_size)
37 : page_size_(page_size) {
38
39 if (page_size_ == 0) {
40 isc_throw(OutOfRange, "page size of retrieved leases must not be 0");
41 }
42
43 if (page_size_ > std::numeric_limits<uint32_t>::max()) {
44 isc_throw(OutOfRange, "page size of retrieved leases must not be greater than "
45 << std::numeric_limits<uint32_t>::max());
46 }
47}
48
49 Lease6Ptr
50 LeaseMgr::getLease6(Lease::Type type, const DUID& duid,
51 uint32_t iaid, SubnetID subnet_id) const {
52 Lease6Collection col = getLeases6(type, duid, iaid, subnet_id);
53
54 if (col.size() > 1) {
55 isc_throw(MultipleRecords, "More than one lease found for type "
56 << static_cast<int>(type) << ", duid "
57 << duid.toText() << ", iaid " << iaid
58 << " and subnet-id " << subnet_id);
59 }
60 if (col.empty()) {
61 return (Lease6Ptr());
62 }
63 return (*col.begin());
64}
65
66void
67LeaseMgr::recountLeaseStats4() {
68 using namespace stats;
69
70 StatsMgr& stats_mgr = StatsMgr::instance();
71
72 LeaseStatsQueryPtr query = startLeaseStatsQuery4();
73 if (!query) {
75 return;
76 }
77
78 // Zero out the global stats.
79 // Cumulative counters ("reclaimed-declined-addresses", "reclaimed-leases",
80 // "cumulative-assigned-addresses") never get zeroed.
81 int64_t zero = 0;
82 stats_mgr.setValue("declined-addresses", zero);
83
84 // Create if it does not exit reclaimed declined leases global stats.
85 if (!stats_mgr.getObservation("reclaimed-declined-addresses")) {
86 stats_mgr.setValue("reclaimed-declined-addresses", zero);
87 }
88
89 // Create if it does not exit reclaimed leases global stats.
90 if (!stats_mgr.getObservation("reclaimed-leases")) {
91 stats_mgr.setValue("reclaimed-leases", zero);
92 }
93
94 // Create if it does not exit cumulative global stats.
95 if (!stats_mgr.getObservation("cumulative-assigned-addresses")) {
96 stats_mgr.setValue("cumulative-assigned-addresses", zero);
97 }
98
99 // Clear subnet level stats. This ensures we don't end up with corner
100 // cases that leave stale values in place.
101 const Subnet4Collection* subnets =
102 CfgMgr::instance().getCurrentCfg()->getCfgSubnets4()->getAll();
103
104 for (Subnet4Collection::const_iterator subnet = subnets->begin();
105 subnet != subnets->end(); ++subnet) {
106 SubnetID subnet_id = (*subnet)->getID();
107 stats_mgr.setValue(StatsMgr::generateName("subnet", subnet_id,
108 "assigned-addresses"),
109 zero);
110
111 stats_mgr.setValue(StatsMgr::generateName("subnet", subnet_id,
112 "declined-addresses"),
113 zero);
114
115 if (!stats_mgr.getObservation(
116 StatsMgr::generateName("subnet", subnet_id,
117 "reclaimed-declined-addresses"))) {
118 stats_mgr.setValue(
119 StatsMgr::generateName("subnet", subnet_id,
120 "reclaimed-declined-addresses"),
121 zero);
122 }
123
124 if (!stats_mgr.getObservation(
125 StatsMgr::generateName("subnet", subnet_id,
126 "reclaimed-leases"))) {
127 stats_mgr.setValue(
128 StatsMgr::generateName("subnet", subnet_id,
129 "reclaimed-leases"),
130 zero);
131 }
132 }
133
134 // Get counts per state per subnet. Iterate over the result set
135 // updating the subnet and global values.
136 LeaseStatsRow row;
137 while (query->getNextRow(row)) {
138 if (row.lease_state_ == Lease::STATE_DEFAULT) {
139 // Add to subnet level value.
140 stats_mgr.addValue(StatsMgr::generateName("subnet", row.subnet_id_,
141 "assigned-addresses"),
142 row.state_count_);
143 } else if (row.lease_state_ == Lease::STATE_DECLINED) {
144 // Set subnet level value.
145 stats_mgr.setValue(StatsMgr::generateName("subnet", row.subnet_id_,
146 "declined-addresses"),
147 row.state_count_);
148
149 // Add to the global value.
150 stats_mgr.addValue("declined-addresses", row.state_count_);
151
152 // Add to subnet level value.
153 // Declined leases also count as assigned.
154 stats_mgr.addValue(StatsMgr::generateName("subnet", row.subnet_id_,
155 "assigned-addresses"),
156 row.state_count_);
157 }
158 }
159}
160
161LeaseStatsQuery::LeaseStatsQuery()
162 : first_subnet_id_(0), last_subnet_id_(0), select_mode_(ALL_SUBNETS) {
163}
164
165 LeaseStatsQuery::LeaseStatsQuery(const SubnetID& subnet_id)
166 : first_subnet_id_(subnet_id), last_subnet_id_(0),
167 select_mode_(SINGLE_SUBNET) {
168
169 if (first_subnet_id_ == 0) {
170 isc_throw(BadValue, "LeaseStatsQuery: subnet_id_ must be > 0");
171 }
172}
173
174 LeaseStatsQuery::LeaseStatsQuery(const SubnetID& first_subnet_id,
175 const SubnetID& last_subnet_id)
176 : first_subnet_id_(first_subnet_id), last_subnet_id_(last_subnet_id),
177 select_mode_(SUBNET_RANGE) {
178
179 if (first_subnet_id_ == 0) {
180 isc_throw(BadValue, "LeaseStatsQuery: first_subnet_id_ must be > 0");
181 }
182
183 if (last_subnet_id_ == 0) {
184 isc_throw(BadValue, "LeaseStatsQuery: last_subnet_id_ must be > 0");
185 }
186
187 if (last_subnet_id_ <= first_subnet_id_) {
188 isc_throw(BadValue,
189 "LeaseStatsQuery: last_subnet_id_must be > first_subnet_id_");
190 }
191}
192
193 LeaseStatsQueryPtr
194LeaseMgr::startLeaseStatsQuery4() {
195 return(LeaseStatsQueryPtr());
196}
197
198 LeaseStatsQueryPtr
199LeaseMgr::startSubnetLeaseStatsQuery4(const SubnetID& /* subnet_id */) {
200 return(LeaseStatsQueryPtr());
201}
202
203 LeaseStatsQueryPtr
204LeaseMgr::startSubnetRangeLeaseStatsQuery4(const SubnetID& /* first_subnet_id */,
205 const SubnetID& /* last_subnet_id */) {
206 return(LeaseStatsQueryPtr());
207}
208
209bool
210LeaseStatsQuery::getNextRow(LeaseStatsRow& /*row*/) {
211 return (false);
212}
213
214void
215LeaseMgr::recountLeaseStats6() {
216 using namespace stats;
217
218 StatsMgr& stats_mgr = StatsMgr::instance();
219
220 LeaseStatsQueryPtr query = startLeaseStatsQuery6();
221 if (!query) {
223 return;
224 }
225
226 // Zero out the global stats.
227 // Cumulative counters ("reclaimed-declined-addresses", "reclaimed-leases",
228 // "cumulative-assigned-nas", "cumulative-assigned-pds") never get zeroed.
229 int64_t zero = 0;
230 stats_mgr.setValue("declined-addresses", zero);
231
232 if (!stats_mgr.getObservation("reclaimed-declined-addresses")) {
233 stats_mgr.setValue("reclaimed-declined-addresses", zero);
234 }
235
236 if (!stats_mgr.getObservation("reclaimed-leases")) {
237 stats_mgr.setValue("reclaimed-leases", zero);
238 }
239
240 // Create if it does not exit cumulative nas global stats.
241 if (!stats_mgr.getObservation("cumulative-assigned-nas")) {
242 stats_mgr.setValue("cumulative-assigned-nas", zero);
243 }
244
245 // Create if it does not exit cumulative pds global stats.
246 if (!stats_mgr.getObservation("cumulative-assigned-pds")) {
247 stats_mgr.setValue("cumulative-assigned-pds", zero);
248 }
249
250 // Clear subnet level stats. This ensures we don't end up with corner
251 // cases that leave stale values in place.
252 const Subnet6Collection* subnets =
253 CfgMgr::instance().getCurrentCfg()->getCfgSubnets6()->getAll();
254
255 for (Subnet6Collection::const_iterator subnet = subnets->begin();
256 subnet != subnets->end(); ++subnet) {
257 SubnetID subnet_id = (*subnet)->getID();
258 stats_mgr.setValue(StatsMgr::generateName("subnet", subnet_id,
259 "assigned-nas"),
260 zero);
261
262 stats_mgr.setValue(StatsMgr::generateName("subnet", subnet_id,
263 "declined-addresses"),
264 zero);
265
266 if (!stats_mgr.getObservation(
267 StatsMgr::generateName("subnet", subnet_id,
268 "reclaimed-declined-addresses"))) {
269 stats_mgr.setValue(
270 StatsMgr::generateName("subnet", subnet_id,
271 "reclaimed-declined-addresses"),
272 zero);
273 }
274
275 stats_mgr.setValue(StatsMgr::generateName("subnet", subnet_id,
276 "assigned-pds"),
277 zero);
278
279 if (!stats_mgr.getObservation(
280 StatsMgr::generateName("subnet", subnet_id,
281 "reclaimed-leases"))) {
282 stats_mgr.setValue(
283 StatsMgr::generateName("subnet", subnet_id,
284 "reclaimed-leases"),
285 zero);
286 }
287 }
288
289 // Get counts per state per subnet. Iterate over the result set
290 // updating the subnet and global values.
291 LeaseStatsRow row;
292 while (query->getNextRow(row)) {
293 switch(row.lease_type_) {
294 case Lease::TYPE_NA:
295 if (row.lease_state_ == Lease::STATE_DEFAULT) {
296 // Add to subnet level value.
297 stats_mgr.addValue(StatsMgr::
298 generateName("subnet", row.subnet_id_,
299 "assigned-nas"),
300 row.state_count_);
301 } else if (row.lease_state_ == Lease::STATE_DECLINED) {
302 // Set subnet level value.
303 stats_mgr.setValue(StatsMgr::
304 generateName("subnet", row.subnet_id_,
305 "declined-addresses"),
306 row.state_count_);
307
308 // Add to the global value.
309 stats_mgr.addValue("declined-addresses", row.state_count_);
310
311 // Add to subnet level value.
312 // Declined leases also count as assigned.
313 stats_mgr.addValue(StatsMgr::
314 generateName("subnet", row.subnet_id_,
315 "assigned-nas"),
316 row.state_count_);
317 }
318 break;
319
320 case Lease::TYPE_PD:
321 if (row.lease_state_ == Lease::STATE_DEFAULT) {
322 // Set subnet level value.
323 stats_mgr.setValue(StatsMgr::
324 generateName("subnet", row.subnet_id_,
325 "assigned-pds"),
326 row.state_count_);
327 }
328 break;
329
330 default:
331 // We dont' support TYPE_TAs yet
332 break;
333 }
334 }
335}
336
337 LeaseStatsQueryPtr
338LeaseMgr::startLeaseStatsQuery6() {
339 return(LeaseStatsQueryPtr());
340}
341
342 LeaseStatsQueryPtr
343LeaseMgr::startSubnetLeaseStatsQuery6(const SubnetID& /* subnet_id */) {
344 return(LeaseStatsQueryPtr());
345}
346
347 LeaseStatsQueryPtr
348LeaseMgr::startSubnetRangeLeaseStatsQuery6(const SubnetID& /* first_subnet_id */,
349 const SubnetID& /* last_subnet_id */) {
350 return(LeaseStatsQueryPtr());
351}
352
353std::string
354LeaseMgr::getDBVersion() {
355 isc_throw(NotImplemented, "LeaseMgr::getDBVersion() called");
356}
357
358} // namespace isc::dhcp
359} // namespace isc
cfgmgr.h
isc::BadValue
A generic exception that is thrown if a parameter given to a method is considered invalid in that con...
Definition: exceptions/exceptions.h:132
isc::NotImplemented
A generic exception that is thrown when a function is not implemented.
Definition: exceptions/exceptions.h:166
isc::OutOfRange
A generic exception that is thrown if a parameter given to a method would refer to or modify out-of-r...
Definition: exceptions/exceptions.h:115
isc::db::MultipleRecords
Multiple lease records found where one expected.
Definition: db_exceptions.h:16
isc::dhcp::CfgMgr::instance
static CfgMgr & instance()
returns a single instance of Configuration Manager
Definition: cfgmgr.cc:25
isc::dhcp::CfgMgr::getCurrentCfg
SrvConfigPtr getCurrentCfg()
Returns a pointer to the current configuration.
Definition: cfgmgr.cc:161
isc::dhcp::DUID
Holds DUID (DHCPv6 Unique Identifier)
Definition: duid.h:27
isc::dhcp::DUID::toText
std::string toText() const
Returns textual representation of a DUID (e.g. 00:01:02:03:ff)
Definition: duid.cc:75
isc::dhcp::LeaseMgr::startSubnetLeaseStatsQuery6
virtual LeaseStatsQueryPtr startSubnetLeaseStatsQuery6(const SubnetID &subnet_id)
Creates and runs the IPv6 lease stats query for a single subnet.
Definition: lease_mgr.cc:343
isc::dhcp::LeaseMgr::getLeases6
virtual Lease6Collection getLeases6() const =0
Returns all IPv6 leases.
isc::dhcp::LeaseMgr::recountLeaseStats6
void recountLeaseStats6()
Recalculates per-subnet and global stats for IPv6 leases.
Definition: lease_mgr.cc:215
isc::dhcp::LeaseMgr::startSubnetRangeLeaseStatsQuery4
virtual LeaseStatsQueryPtr startSubnetRangeLeaseStatsQuery4(const SubnetID &first_subnet_id, const SubnetID &last_subnet_id)
Creates and runs the IPv4 lease stats query for a single subnet.
Definition: lease_mgr.cc:204
isc::dhcp::LeaseMgr::recountLeaseStats4
void recountLeaseStats4()
Recalculates per-subnet and global stats for IPv4 leases.
Definition: lease_mgr.cc:67
isc::dhcp::LeaseMgr::getDBVersion
static std::string getDBVersion()
Class method to return extended version info This class method must be redeclared and redefined in de...
Definition: lease_mgr.cc:354
isc::dhcp::LeaseMgr::startSubnetRangeLeaseStatsQuery6
virtual LeaseStatsQueryPtr startSubnetRangeLeaseStatsQuery6(const SubnetID &first_subnet_id, const SubnetID &last_subnet_id)
Creates and runs the IPv6 lease stats query for a single subnet.
Definition: lease_mgr.cc:348
isc::dhcp::LeaseMgr::startSubnetLeaseStatsQuery4
virtual LeaseStatsQueryPtr startSubnetLeaseStatsQuery4(const SubnetID &subnet_id)
Creates and runs the IPv4 lease stats query for a single subnet.
Definition: lease_mgr.cc:199
isc::dhcp::LeaseMgr::getLease6
virtual Lease6Ptr getLease6(Lease::Type type, const isc::asiolink::IOAddress &addr) const =0
Returns existing IPv6 lease for a given IPv6 address.
isc::dhcp::LeaseMgr::startLeaseStatsQuery4
virtual LeaseStatsQueryPtr startLeaseStatsQuery4()
Creates and runs the IPv4 lease stats query for all subnets.
Definition: lease_mgr.cc:194
isc::dhcp::LeaseMgr::startLeaseStatsQuery6
virtual LeaseStatsQueryPtr startLeaseStatsQuery6()
Creates and runs the IPv6 lease stats query for all subnets.
Definition: lease_mgr.cc:338
isc::dhcp::LeasePageSize::page_size_
const size_t page_size_
Holds page size.
Definition: lease_mgr.h:54
isc::dhcp::LeasePageSize::LeasePageSize
LeasePageSize(const size_t page_size)
Constructor.
Definition: lease_mgr.cc:36
isc::dhcp::LeaseStatsQuery::first_subnet_id_
SubnetID first_subnet_id_
First (or only) subnet_id in the selection criteria.
Definition: lease_mgr.h:193
isc::dhcp::LeaseStatsQuery::last_subnet_id_
SubnetID last_subnet_id_
Last subnet_id in the selection criteria when a range is given.
Definition: lease_mgr.h:200
isc::dhcp::LeaseStatsQuery::getNextRow
virtual bool getNextRow(LeaseStatsRow &row)
Fetches the next row of data.
Definition: lease_mgr.cc:210
isc::dhcp::LeaseStatsQuery::LeaseStatsQuery
LeaseStatsQuery()
Default constructor The query created will return statistics for all subnets.
Definition: lease_mgr.cc:161
dhcpsrv_log.h
exceptions.h
isc_throw
#define isc_throw(type, stream)
A shortcut macro to insert known values into exception arguments.
Definition: exceptions/exceptions.h:210
lease_mgr.h
An abstract API for lease database.
stats_mgr.h
isc::asiolink
Definition: addr_utilities.cc:170
isc::asiolink::IOServicePtr
boost::shared_ptr< IOService > IOServicePtr
Defines a smart pointer to an IOService instance.
Definition: io_service.h:110
isc::db
Definition: audit_entry.cc:14
isc::dhcp::Lease6Ptr
boost::shared_ptr< Lease6 > Lease6Ptr
Pointer to a Lease6 structure.
Definition: lease.h:503
isc::dhcp::Lease6Collection
std::vector< Lease6Ptr > Lease6Collection
A collection of IPv6 leases.
Definition: lease.h:661
isc::dhcp::LeaseStatsQueryPtr
boost::shared_ptr< LeaseStatsQuery > LeaseStatsQueryPtr
Defines a pointer to a LeaseStatsQuery.
Definition: lease_mgr.h:208
isc::dhcp::Subnet6Collection
boost::multi_index_container< Subnet6Ptr, boost::multi_index::indexed_by< boost::multi_index::ordered_unique< boost::multi_index::tag< SubnetSubnetIdIndexTag >, boost::multi_index::const_mem_fun< Subnet, SubnetID, &Subnet::getID > >, boost::multi_index::ordered_unique< boost::multi_index::tag< SubnetPrefixIndexTag >, boost::multi_index::const_mem_fun< Subnet, std::string, &Subnet::toText > >, boost::multi_index::ordered_non_unique< boost::multi_index::tag< SubnetModificationTimeIndexTag >, boost::multi_index::const_mem_fun< data::BaseStampedElement, boost::posix_time::ptime, &data::BaseStampedElement::getModificationTime > > > > Subnet6Collection
A collection of Subnet6 objects.
Definition: subnet.h:964
isc::dhcp::Subnet4Collection
boost::multi_index_container< Subnet4Ptr, boost::multi_index::indexed_by< boost::multi_index::ordered_unique< boost::multi_index::tag< SubnetSubnetIdIndexTag >, boost::multi_index::const_mem_fun< Subnet, SubnetID, &Subnet::getID > >, boost::multi_index::ordered_unique< boost::multi_index::tag< SubnetPrefixIndexTag >, boost::multi_index::const_mem_fun< Subnet, std::string, &Subnet::toText > >, boost::multi_index::ordered_non_unique< boost::multi_index::tag< SubnetServerIdIndexTag >, boost::multi_index::const_mem_fun< Network4, asiolink::IOAddress, &Network4::getServerId > >, boost::multi_index::ordered_non_unique< boost::multi_index::tag< SubnetModificationTimeIndexTag >, boost::multi_index::const_mem_fun< data::BaseStampedElement, boost::posix_time::ptime, &data::BaseStampedElement::getModificationTime > > > > Subnet4Collection
A collection of Subnet4 objects.
Definition: subnet.h:893
isc::dhcp::SubnetID
uint32_t SubnetID
Defines unique IPv4 or IPv6 subnet identifier.
Definition: subnet_id.h:24
isc
Defines the logger used by the top-level component of kea-lfc.
Definition: agent_parser.cc:143
isc::dhcp::LeaseStatsRow
Contains a single row of lease statistical data.
Definition: lease_mgr.h:62
isc::dhcp::LeaseStatsRow::state_count_
int64_t state_count_
state_count The count of leases in the lease state
Definition: lease_mgr.h:121
isc::dhcp::LeaseStatsRow::lease_state_
uint32_t lease_state_
The lease_state to which the count applies.
Definition: lease_mgr.h:119
isc::dhcp::LeaseStatsRow::subnet_id_
SubnetID subnet_id_
The subnet ID to which this data applies.
Definition: lease_mgr.h:115
isc::dhcp::LeaseStatsRow::lease_type_
Lease::Type lease_type_
The lease_type to which the count applies.
Definition: lease_mgr.h:117
isc::dhcp::Lease::STATE_DEFAULT
static const uint32_t STATE_DEFAULT
A lease in the default state.
Definition: lease.h:69
isc::dhcp::Lease::STATE_DECLINED
static const uint32_t STATE_DECLINED
Declined lease.
Definition: lease.h:72
isc::dhcp::Lease::Type
Type
Type of lease or pool.
Definition: lease.h:46
isc::dhcp::Lease::TYPE_PD
@ TYPE_PD
the lease contains IPv6 prefix (for prefix delegation)
Definition: lease.h:49
isc::dhcp::Lease::TYPE_NA
@ TYPE_NA
the lease contains non-temporary IPv6 address
Definition: lease.h:47