Kea  1.9.9-git
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 
27 using namespace isc::asiolink;
28 using namespace isc::db;
29 using namespace std;
30 
31 namespace isc {
32 namespace dhcp {
33 
34 IOServicePtr LeaseMgr::io_service_ = IOServicePtr();
35 
36 LeasePageSize::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 
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 
66 void
68  using namespace stats;
69 
70  StatsMgr& stats_mgr = StatsMgr::instance();
71 
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 
162  : first_subnet_id_(0), last_subnet_id_(0), select_mode_(ALL_SUBNETS) {
163 }
164 
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 
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 
189  "LeaseStatsQuery: last_subnet_id_must be > first_subnet_id_");
190  }
191 }
192 
195  return(LeaseStatsQueryPtr());
196 }
197 
200  return(LeaseStatsQueryPtr());
201 }
202 
205  const SubnetID& /* last_subnet_id */) {
206  return(LeaseStatsQueryPtr());
207 }
208 
209 bool
211  return (false);
212 }
213 
214 void
216  using namespace stats;
217 
218  StatsMgr& stats_mgr = StatsMgr::instance();
219 
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 
339  return(LeaseStatsQueryPtr());
340 }
341 
344  return(LeaseStatsQueryPtr());
345 }
346 
349  const SubnetID& /* last_subnet_id */) {
350  return(LeaseStatsQueryPtr());
351 }
352 
353 std::string
355  isc_throw(NotImplemented, "LeaseMgr::getDBVersion() called");
356 }
357 
358 } // namespace isc::dhcp
359 } // namespace isc
virtual LeaseStatsQueryPtr startSubnetLeaseStatsQuery6(const SubnetID &subnet_id)
Creates and runs the IPv6 lease stats query for a single subnet.
Definition: lease_mgr.cc:343
boost::shared_ptr< LeaseStatsQuery > LeaseStatsQueryPtr
Defines a pointer to a LeaseStatsQuery.
Definition: lease_mgr.h:207
A generic exception that is thrown when a function is not implemented.
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
virtual LeaseStatsQueryPtr startLeaseStatsQuery4()
Creates and runs the IPv4 lease stats query for all subnets.
Definition: lease_mgr.cc:194
LeaseStatsQuery()
Default constructor The query created will return statistics for all subnets.
Definition: lease_mgr.cc:161
An abstract API for lease database.
static CfgMgr & instance()
returns a single instance of Configuration Manager
Definition: cfgmgr.cc:25
the lease contains IPv6 prefix (for prefix delegation)
Definition: lease.h:53
SrvConfigPtr getCurrentCfg()
Returns a pointer to the current configuration.
Definition: cfgmgr.cc:161
STL namespace.
Holds DUID (DHCPv6 Unique Identifier)
Definition: duid.h:27
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
Multiple lease records found where one expected.
Definition: db_exceptions.h:28
virtual LeaseStatsQueryPtr startSubnetLeaseStatsQuery4(const SubnetID &subnet_id)
Creates and runs the IPv4 lease stats query for a single subnet.
Definition: lease_mgr.cc:199
virtual Lease6Collection getLeases6() const =0
Returns all IPv6 leases.
#define isc_throw(type, stream)
A shortcut macro to insert known values into exception arguments.
A generic exception that is thrown if a parameter given to a method is considered invalid in that con...
const size_t page_size_
Holds page size.
Definition: lease_mgr.h:53
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:867
SubnetID last_subnet_id_
Last subnet_id in the selection criteria when a range is given.
Definition: lease_mgr.h:199
SubnetID subnet_id_
The subnet ID to which this data applies.
Definition: lease_mgr.h:114
void recountLeaseStats4()
Recalculates per-subnet and global stats for IPv4 leases.
Definition: lease_mgr.cc:67
std::vector< Lease6Ptr > Lease6Collection
A collection of IPv6 leases.
Definition: lease.h:640
virtual Lease6Ptr getLease6(Lease::Type type, const isc::asiolink::IOAddress &addr) const =0
Returns existing IPv6 lease for a given IPv6 address.
std::string toText() const
Returns textual representation of a DUID (e.g. 00:01:02:03:ff)
Definition: duid.cc:75
the lease contains non-temporary IPv6 address
Definition: lease.h:51
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:914
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
Defines the logger used by the top-level component of kea-dhcp-ddns.
virtual LeaseStatsQueryPtr startLeaseStatsQuery6()
Creates and runs the IPv6 lease stats query for all subnets.
Definition: lease_mgr.cc:338
uint32_t lease_state_
The lease_state to which the count applies.
Definition: lease_mgr.h:118
Type
Type of lease or pool.
Definition: lease.h:50
static const uint32_t STATE_DEFAULT
A lease in the default state.
Definition: lease.h:73
SubnetID first_subnet_id_
First (or only) subnet_id in the selection criteria.
Definition: lease_mgr.h:192
A generic exception that is thrown if a parameter given to a method would refer to or modify out-of-r...
int64_t state_count_
state_count The count of leases in the lease state
Definition: lease_mgr.h:120
void recountLeaseStats6()
Recalculates per-subnet and global stats for IPv6 leases.
Definition: lease_mgr.cc:215
static const uint32_t STATE_DECLINED
Declined lease.
Definition: lease.h:76
Contains a single row of lease statistical data.
Definition: lease_mgr.h:61
Lease::Type lease_type_
The lease_type to which the count applies.
Definition: lease_mgr.h:116
virtual bool getNextRow(LeaseStatsRow &row)
Fetches the next row of data.
Definition: lease_mgr.cc:210
boost::shared_ptr< Lease6 > Lease6Ptr
Pointer to a Lease6 structure.
Definition: lease.h:492
uint32_t SubnetID
Unique identifier for a subnet (both v4 and v6)
Definition: lease.h:24