Kea  1.9.9-git
free_lease_queue.h
Go to the documentation of this file.
1 // Copyright (C) 2020-2021 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 #ifndef FREE_LEASE_QUEUE_H
8 #define FREE_LEASE_QUEUE_H
9 
10 #include <asiolink/io_address.h>
11 #include <dhcpsrv/ip_range.h>
12 #include <exceptions/exceptions.h>
13 
14 #include <boost/multi_index_container.hpp>
15 #include <boost/multi_index/hashed_index.hpp>
16 #include <boost/multi_index/identity.hpp>
17 #include <boost/multi_index/indexed_by.hpp>
18 #include <boost/multi_index/member.hpp>
19 #include <boost/multi_index/ordered_index.hpp>
20 #include <boost/multi_index/random_access_index.hpp>
21 #include <boost/multi_index/sequenced_index.hpp>
22 #include <boost/shared_ptr.hpp>
23 
24 #include <iterator>
25 #include <map>
26 
27 namespace isc {
28 namespace dhcp {
29 
83 public:
84 
87 
94  void addRange(const AddressRange& range);
95 
104  void addRange(const asiolink::IOAddress& start, const asiolink::IOAddress& end);
105 
112  void addRange(const PrefixRange& range);
113 
123  void addRange(const asiolink::IOAddress& prefix, const uint8_t prefix_length,
124  const uint8_t delegated_length);
125 
133  template<typename RangeType>
134  bool removeRange(const RangeType& range) {
135  return (ranges_.get<1>().erase(range.start_) > 0);
136  }
137 
147  bool append(const asiolink::IOAddress& address);
148 
159  bool append(const asiolink::IOAddress& prefix, const uint8_t delegated_length);
160 
173  void append(const AddressRange& range, const asiolink::IOAddress& address);
174 
187  void append(const PrefixRange& range, const asiolink::IOAddress& prefix);
188 
202  void append(const uint64_t range_index, const asiolink::IOAddress& ip);
203 
214  bool use(const AddressRange& range, const asiolink::IOAddress& address);
215 
226  bool use(const PrefixRange& range, const asiolink::IOAddress& prefix);
227 
237  template<typename RangeType>
238  asiolink::IOAddress next(const RangeType& range) {
239  return (popNextInternal(range, true));
240  }
241 
252  template<typename RangeType>
253  asiolink::IOAddress pop(const RangeType& range) {
254  return (popNextInternal(range, false));
255  }
256 
267  template<typename RangeType>
268  uint64_t getRangeIndex(const RangeType& range) const {
269  auto cont = ranges_.get<1>().find(range.start_);
270  if (cont == ranges_.get<1>().end()) {
271  isc_throw(BadValue, "container for the specified range " << range.start_
272  << ":" << range.end_ << " does not exist");
273  }
274  return (std::distance(ranges_.get<2>().begin(), ranges_.project<2>(cont)));
275  }
276 
277 private:
278 
285  typedef boost::multi_index_container<
287  boost::multi_index::indexed_by<
288  boost::multi_index::ordered_unique<
289  boost::multi_index::identity<asiolink::IOAddress>
290  >,
291  boost::multi_index::sequenced<>
292  >
293  > Leases;
294 
296  typedef boost::shared_ptr<Leases> LeasesPtr;
297 
300  struct RangeDescriptor {
302  asiolink::IOAddress range_start_;
304  asiolink::IOAddress range_end_;
306  uint8_t delegated_length_;
308  LeasesPtr leases_;
309  };
310 
317  typedef boost::multi_index_container<
318  RangeDescriptor,
319  boost::multi_index::indexed_by<
320  boost::multi_index::ordered_unique<
321  boost::multi_index::member<RangeDescriptor, asiolink::IOAddress,
322  &RangeDescriptor::range_start_>
323  >,
324  boost::multi_index::hashed_unique<
325  boost::multi_index::member<RangeDescriptor, asiolink::IOAddress,
326  &RangeDescriptor::range_start_>
327  >,
328  boost::multi_index::random_access<>
329  >
330  > Ranges;
331 
341  template<typename RangeType>
342  void checkRangeBoundaries(const RangeType& range, const asiolink::IOAddress& ip,
343  const bool prefix = false) const;
344 
351  void checkRangeOverlaps(const asiolink::IOAddress& start,
352  const asiolink::IOAddress& end) const;
353 
359  LeasesPtr getLeases(const AddressRange& range) const;
360 
366  LeasesPtr getLeases(const PrefixRange& range) const;
367 
377  RangeDescriptor getRangeDescriptor(const uint64_t range_index) const;
378 
388  template<typename RangeType>
389  asiolink::IOAddress popNextInternal(const RangeType& range, const bool push) {
390  auto cont = getLeases(range);
391  if (cont->empty()) {
392  return (range.start_.isV4() ? asiolink::IOAddress::IPV4_ZERO_ADDRESS() :
393  asiolink::IOAddress::IPV6_ZERO_ADDRESS());
394  }
395  auto& idx = cont->template get<1>();
396  auto next = idx.front();
397  idx.pop_front();
398  if (push) {
399  idx.push_back(next);
400  }
401  return (next);
402  }
403 
406  Ranges ranges_;
407 };
408 
409 } // end of namespace isc::dhcp
410 } // end of namespace isc
411 
412 #endif // FREE_LEASE_QUEUE_H
uint64_t getRangeIndex(const RangeType &range) const
Returns range index.
Structure representing delegated prefix range.
Definition: ip_range.h:32
asiolink::IOAddress pop(const RangeType &range)
Pops and returns next free address or delegated prefix in the range.
asiolink::IOAddress next(const RangeType &range)
Returns next free address or delegated prefix in the range.
void addRange(const AddressRange &range)
Adds new address range to the queue.
bool use(const AddressRange &range, const asiolink::IOAddress &address)
Removes the specified address from the free addresses.
#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...
Defines the logger used by the top-level component of kea-dhcp-ddns.
bool append(const asiolink::IOAddress &address)
Appends an address to the end of the queue for a range.
Structure representing IP address range.
Definition: ip_range.h:16
bool removeRange(const RangeType &range)
Removes the range from the queue.
Queue holding free leases for various address and prefix ranges.