Kea  2.3.5-git
memfile_lease_limits.cc
Go to the documentation of this file.
1 // Copyright (C) 2022 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 
10 
11 using namespace isc::data;
12 
13 namespace isc {
14 namespace dhcp {
15 
16 size_t
17 ClassLeaseCounter::getClassCount(const ClientClass& client_class,
18  const Lease::Type& ltype) const {
19  const ClassCountMap& leases_by_class = getConstCountMap(ltype);
20  auto it = leases_by_class.find(client_class);
21  if (it == leases_by_class.end()) {
22  return (0);
23  }
24 
25  // Return the lease count for the class.
26  return(it->second);
27 }
28 
29 void
30 ClassLeaseCounter::setClassCount(const ClientClass& client_class, size_t count,
31  const Lease::Type& ltype) {
32  ClassCountMap& leases_by_class = getCountMap(ltype);
33  leases_by_class[client_class] = count;
34 }
35 
36 void
37 ClassLeaseCounter::adjustClassCount(const ClientClass& client_class, int offset,
38  const Lease::Type& ltype) {
39  ClassCountMap& leases_by_class = getCountMap(ltype);
40  auto it = leases_by_class.find(client_class);
41  if (it == leases_by_class.end()) {
42  // Not there yet, add it.
43  leases_by_class[client_class] = offset < 0 ? 0 : offset;
44  } else {
45  size_t new_count = it->second + offset;
46  if (offset < 0 && (new_count > it->second)) {
47  // We rolled over, set it zero. We should probably log this?
48  it->second = 0;
49  } else {
50  it->second = new_count;
51  }
52  }
53 }
54 
55 
57 ClassLeaseCounter::getLeaseClientClasses(LeasePtr lease) {
58  if (!lease) {
59  isc_throw(BadValue, "getLeaseClientCLasses - lease cannot be empty");
60  }
61 
62  ConstElementPtr classes;
63  auto ctx = lease->getContext();
64  try {
65  if (ctx) {
66  classes = ctx->find("ISC/client-classes");
67  if (classes && classes->getType() != Element::list) {
68  isc_throw(BadValue, "client-classes is not a list");
69  }
70  }
71  } catch (const std::exception& ex) {
72  isc_throw(BadValue, "getLeaseClientClasses - invalid context: "
73  << data::prettyPrint(ctx) << ", " << ex.what());
74  }
75 
76  return (classes);
77 }
78 
79 void
80 ClassLeaseCounter::adjustClassCounts(ConstElementPtr classes, int offset,
81  const Lease::Type& ltype) {
82  if (!classes) {
83  return;
84  }
85 
86  for (int i = 0; i < classes->size(); ++i) {
87  std::string class_name = classes->get(i)->stringValue();
88  adjustClassCount(class_name, offset, ltype);
89  }
90 }
91 
92 void
93 ClassLeaseCounter::addLease(LeasePtr lease) {
94  if (!lease) {
95  isc_throw(BadValue, "addLease - lease cannot be empty");
96  }
97 
98  ConstElementPtr classes = getLeaseClientClasses(lease);
99  if (!classes) {
100  return; // Lease limits isn't loaded.
101  }
102 
103  // Add the new lease to its classes.
104  if (lease->state_ == Lease::STATE_DEFAULT) {
105  adjustClassCounts(classes, 1, lease->getType());
106  }
107 }
108 
109 void
110 ClassLeaseCounter::updateLease(LeasePtr new_lease, LeasePtr old_lease) {
111  // Sanity checks.
112  if (!new_lease) {
113  isc_throw(BadValue, "updateLease - new_lease cannot be empty");
114  }
115 
116  if (!old_lease) {
117  isc_throw(BadValue, "updateLease - old_lease cannot be empty");
118  }
119 
120  ConstElementPtr new_classes = getLeaseClientClasses(new_lease);
121  uint32_t new_state = new_lease->state_;
122 
123  ConstElementPtr old_classes = getLeaseClientClasses(old_lease);
124  uint32_t old_state = old_lease->state_;
125 
126  // Did we change states or classes?
127  // Note we do not worry about lease type changes, because it makes no
128  // business sense to repurpose a lease as a different type. Other than
129  // some unit tests unrelated to this it never occurs in the code.
130  if ((old_state != new_state) || (old_classes != new_classes)) {
131  // Old classes are moving out of a counted state.
132  if (old_state == Lease::STATE_DEFAULT) {
133  adjustClassCounts(old_classes, -1, old_lease->getType());
134  }
135 
136  // New classes are moving into a counted state.
137  if (new_state == Lease::STATE_DEFAULT) {
138  adjustClassCounts(new_classes, 1, new_lease->getType());
139  }
140  }
141 }
142 
143 void
144 ClassLeaseCounter::removeLease(LeasePtr lease) {
145  if (!lease) {
146  isc_throw(BadValue, "removeLease - lease cannot be empty");
147  }
148 
149  ConstElementPtr classes = getLeaseClientClasses(lease);
150  if (!classes) {
151  return; // Lease limits isn't loaded.
152  }
153 
154  // Remove the new lease to its classes.
155  if (lease->state_ == Lease::STATE_DEFAULT) {
156  adjustClassCounts(classes, -1, lease->getType());
157  }
158 }
159 
160 } // end of isc::dhcp namespace
161 } // end of isc namespace
void prettyPrint(ConstElementPtr element, std::ostream &out, unsigned indent, unsigned step)
Pretty prints the data into stream.
Definition: data.cc:1487
std::unordered_map< ClientClass, size_t > ClassCountMap
Defines ClassCountMap as an unordered map of counts.
boost::shared_ptr< Lease > LeasePtr
Pointer to the lease object.
Definition: lease.h:22
#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...
boost::shared_ptr< const Element > ConstElementPtr
Definition: data.h:27
Defines the logger used by the top-level component of kea-lfc.
Type
Type of lease or pool.
Definition: lease.h:46
std::string ClientClass
Defines a single class name.
Definition: classify.h:42