16 #include <boost/lexical_cast.hpp>
17 #include <boost/make_shared.hpp>
35 return (prefix < pool->getFirstAddress());
47 comparePoolFirstAddress(
const PoolPtr& pool1,
const PoolPtr& pool2) {
48 return (pool1->getFirstAddress() < pool2->getFirstAddress());
61 : id_(id == 0 ? generateNextID() : id), prefix_(prefix),
66 last_allocated_time_(),
67 shared_network_name_(),
68 mutex_(new
std::mutex) {
69 if ((prefix.
isV6() && len > 128) ||
70 (prefix.
isV4() && len > 32)) {
72 "Invalid prefix length specified for subnet: " << len);
87 return ((first <= addr) && (addr <= last));
91 if (MultiThreadingMgr::instance().getMode()) {
92 std::lock_guard<std::mutex> lock(*mutex_);
93 return (getLastAllocatedInternal(type));
95 return (getLastAllocatedInternal(type));
116 boost::posix_time::ptime
118 if (MultiThreadingMgr::instance().getMode()) {
119 std::lock_guard<std::mutex> lock(*mutex_);
120 return (getLastAllocatedTimeInternal(lease_type));
122 return (getLastAllocatedTimeInternal(lease_type));
126 boost::posix_time::ptime
127 Subnet::getLastAllocatedTimeInternal(
const Lease::Type& lease_type)
const {
135 return (boost::posix_time::neg_infin);
140 if (MultiThreadingMgr::instance().getMode()) {
141 std::lock_guard<std::mutex> lock(*mutex_);
142 setLastAllocatedInternal(type, addr);
144 setLastAllocatedInternal(type, addr);
148 void Subnet::setLastAllocatedInternal(
Lease::Type type,
175 std::stringstream tmp;
192 << static_cast<int>(type));
209 << static_cast<int>(type));
216 for (PoolCollection::const_iterator p = pools.begin(); p != pools.end(); ++p) {
217 uint64_t x = (*p)->getCapacity();
221 if (x > std::numeric_limits<uint64_t>::max() - sum) {
222 return (std::numeric_limits<uint64_t>::max());
235 for (PoolCollection::const_iterator p = pools.begin(); p != pools.end(); ++p) {
236 if (!(*p)->clientSupported(client_classes)) {
239 uint64_t x = (*p)->getCapacity();
243 if (x > std::numeric_limits<uint64_t>::max() - sum) {
244 return (std::numeric_limits<uint64_t>::max());
253 std::pair<IOAddress, uint8_t>
255 auto pos = prefix.find(
'/');
256 if ((pos == std::string::npos) ||
257 (pos == prefix.size() - 1) ||
263 IOAddress address(prefix.substr(0, pos));
264 int length = boost::lexical_cast<
int>(prefix.substr(pos + 1));
265 return (std::make_pair(address, static_cast<int>(length)));
285 if (!prefix.
isV4()) {
287 <<
" specified in subnet4");
302 Subnet4Ptr subnet = boost::make_shared<Subnet4>
303 (prefix, length, t1, t2, valid_lifetime, id);
312 return (network->getNextSubnet(first_subnet,
getID()));
332 subnet = network->getNextSubnet(first_subnet, subnet_id);
335 if (subnet && subnet->clientSupported(client_classes)) {
350 if (network && !network->clientSupported(client_classes)) {
371 << static_cast<int>(type));
389 << static_cast<int>(type));
394 bool anypool )
const {
402 if (!pools.empty()) {
411 PoolCollection::const_iterator ub =
412 std::upper_bound(pools.begin(), pools.end(), hint,
413 prefixLessThanFirstAddress);
415 if (ub != pools.begin()) {
417 if ((*ub)->inRange(hint)) {
423 if (!candidate && anypool) {
424 candidate = *pools.begin();
442 if (!pools.empty()) {
443 PoolCollection::const_iterator ub =
444 std::upper_bound(pools.begin(), pools.end(), hint,
445 prefixLessThanFirstAddress);
447 if (ub != pools.begin()) {
449 if ((*ub)->inRange(hint) &&
450 (*ub)->clientSupported(client_classes)) {
470 if (!
inRange(pool->getFirstAddress()) || !
inRange(pool->getLastAddress())) {
473 <<
", with the following address range: "
474 << pool->getFirstAddress() <<
"-"
475 << pool->getLastAddress() <<
" does not match"
476 <<
" the prefix of a subnet: "
478 <<
" to which it is being added");
483 bool overlaps =
false;
497 <<
", with the following address range: "
498 << pool->getFirstAddress() <<
"-"
499 << pool->getLastAddress() <<
" overlaps with "
500 "an existing pool in the subnet: "
502 <<
" to which it is being added");
508 pools_writable.push_back(pool);
511 std::sort(pools_writable.begin(), pools_writable.end(),
512 comparePoolFirstAddress);
530 for (PoolCollection::const_iterator pool = pools.begin();
531 pool != pools.end(); ++pool) {
532 if ((*pool)->inRange(addr)) {
552 for (PoolCollection::const_iterator pool = pools.begin();
553 pool != pools.end(); ++pool) {
554 if (!(*pool)->clientSupported(client_classes)) {
557 if ((*pool)->inRange(addr)) {
588 PoolCollection::const_iterator pool3_it =
589 std::upper_bound(pools.begin(), pools.end(), pool->getFirstAddress(),
590 prefixLessThanFirstAddress);
598 if (pool3_it != pools.begin()) {
600 PoolPtr pool3 = *(pool3_it - 1);
601 if (pool3->getFirstAddress() == pool->getFirstAddress()) {
608 if (pool3_it != pools.end()) {
612 if (pool3->getFirstAddress() <= pool->getLastAddress()) {
619 if (pool3_it != pools.begin()) {
620 PoolPtr pool1 = *(pool3_it - 1);
622 if (pool->getFirstAddress() <= pool1->getLastAddress()) {
638 if (!prefix.
isV6()) {
640 <<
" specified in subnet6");
657 Subnet6Ptr subnet = boost::make_shared<Subnet6>
658 (prefix, length, t1, t2, preferred_lifetime, valid_lifetime, id);
666 <<
"(" << static_cast<int>(type)
667 <<
"), must be TYPE_NA, TYPE_TA or TYPE_PD for Subnet6");
676 return (network->getNextSubnet(first_subnet,
getID()));
696 subnet = network->getNextSubnet(first_subnet, subnet_id);
699 if (subnet && subnet->clientSupported(client_classes)) {
713 if (network && !network->clientSupported(client_classes)) {
729 map->set(
"id", Element::create(static_cast<long long>(
id)));
732 map->set(
"subnet", Element::create(
toText()));
743 merge(map, network_map);
752 for (PoolCollection::const_iterator pool = pools.cbegin();
753 pool != pools.cend(); ++pool) {
755 pool_list->add((*pool)->toElement());
757 map->set(
"pools", pool_list);
762 std::pair<IOAddress, uint8_t>
765 if (!parsed.first.isV4() || parsed.first.isV4Zero() ||
766 (parsed.second > 32) || (parsed.second == 0)) {
778 merge(map, network_map);
783 for (PoolCollection::const_iterator pool = pools.cbegin();
784 pool != pools.cend(); ++pool) {
786 pool_list->add((*pool)->toElement());
788 map->set(
"pools", pool_list);
792 ElementPtr pdpool_list = Element::createList();
793 for (PoolCollection::const_iterator pool = pdpools.cbegin();
794 pool != pdpools.cend(); ++pool) {
796 pdpool_list->add((*pool)->toElement());
798 map->set(
"pd-pools", pdpool_list);
803 std::pair<IOAddress, uint8_t>
806 if (!parsed.first.isV6() || parsed.first.isV6Zero() ||
807 (parsed.second > 128) || (parsed.second == 0)) {
virtual isc::data::ElementPtr toElement() const
Unparse a configuration object.
static Subnet4Ptr create(const isc::asiolink::IOAddress &prefix, uint8_t length, const Triplet< uint32_t > &t1, const Triplet< uint32_t > &t2, const Triplet< uint32_t > &valid_lifetime, const SubnetID id=0)
Factory function creating an instance of the Subnet4.
Subnet6Ptr getNextSubnet(const Subnet6Ptr &first_subnet) const
Returns next subnet within shared network.
boost::shared_ptr< Network > NetworkPtr
Pointer to the Network object.
static Subnet6Ptr create(const isc::asiolink::IOAddress &prefix, uint8_t length, const Triplet< uint32_t > &t1, const Triplet< uint32_t > &t2, const Triplet< uint32_t > &preferred_lifetime, const Triplet< uint32_t > &valid_lifetime, const SubnetID id=0)
Factory function creating an instance of the Subnet4.
virtual bool clientSupported(const isc::dhcp::ClientClasses &client_classes) const
Checks whether this network supports client that belongs to specified classes.
Cfg4o6 & get4o6()
Returns DHCP4o6 configuration parameters.
static std::string typeToText(Type type)
returns text representation of a lease type
virtual data::ElementPtr toElement() const
Unparse a subnet object.
virtual data::ElementPtr toElement() const
Unparses network object.
Subnet6(const isc::asiolink::IOAddress &prefix, uint8_t length, const Triplet< uint32_t > &t1, const Triplet< uint32_t > &t2, const Triplet< uint32_t > &preferred_lifetime, const Triplet< uint32_t > &valid_lifetime, const SubnetID id=0)
Constructor with all parameters.
std::map< Lease::Type, boost::posix_time::ptime > last_allocated_time_
Timestamp indicating when a lease of a specified type has been last allocated from this subnet...
void setValid(const Triplet< uint32_t > &valid)
Sets new valid lifetime for a network.
bool inRange(const isc::asiolink::IOAddress &addr) const
checks if specified address is in range.
virtual data::ElementPtr toElement() const
Unparse a subnet object.
virtual data::ElementPtr toElement() const
Unparses network object.
boost::shared_ptr< Subnet4 > Subnet4Ptr
A pointer to a Subnet4 object.
void addPool(const PoolPtr &pool)
Adds a new pool for the subnet.
the lease contains IPv6 prefix (for prefix delegation)
boost::shared_ptr< Element > ElementPtr
std::vector< PoolPtr > PoolCollection
a container for either IPv4 or IPv6 Pools
isc::asiolink::IOAddress last_allocated_pd_
last allocated IPv6 prefix.
boost::shared_ptr< Pool > PoolPtr
a pointer to either IPv4 or IPv6 Pool
uint8_t prefix_len_
a prefix length of the subnet.
void contextToElement(data::ElementPtr map) const
Merge unparse a user_context object.
static std::pair< asiolink::IOAddress, uint8_t > parsePrefix(const std::string &prefix)
Converts subnet prefix to a pair of prefix/length pair.
bool isV4() const
Convenience function to check for an IPv4 address.
Subnet4(const isc::asiolink::IOAddress &prefix, uint8_t length, const Triplet< uint32_t > &t1, const Triplet< uint32_t > &t2, const Triplet< uint32_t > &valid_lifetime, const SubnetID id=0)
Constructor with all parameters.
Specialization of the Network object for DHCPv6 case.
IOAddress firstAddrInPrefix(const IOAddress &prefix, uint8_t len)
This code is based on similar code from the Dibbler project.
#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 PoolPtr getPool(Lease::Type type, const isc::asiolink::IOAddress &addr, bool anypool=true) const
Returns a pool that specified address belongs to.
void getSharedNetwork(SharedNetworkPtrType &shared_network) const
Retrieves pointer to a shared network associated with a subnet.
SubnetID getID() const
Returns unique ID for that subnet.
This structure contains information about DHCP4o6 (RFC7341)
virtual bool clientSupported(const isc::dhcp::ClientClasses &client_classes) const
Checks whether this subnet and parent shared network supports the client that belongs to specified cl...
virtual std::string toText() const
Returns textual representation of the subnet (e.g.
virtual data::ElementPtr toElement() const
Unparse a subnet object.
isc::asiolink::IOAddress last_allocated_ia_
last allocated address.
static std::pair< asiolink::IOAddress, uint8_t > parsePrefixCommon(const std::string &prefix)
Converts subnet prefix to a pair of prefix/length pair.
void setPreferred(const Triplet< uint32_t > &preferred)
Sets new preferred lifetime for a network.
bool poolOverlaps(const Lease::Type &pool_type, const PoolPtr &pool) const
Checks if the specified pool overlaps with an existing pool.
isc::asiolink::IOAddress prefix_
a prefix of the subnet.
PoolCollection pools_
collection of IPv4 or non-temporary IPv6 pools in that subnet.
the lease contains temporary IPv6 address
boost::shared_ptr< SharedNetwork6 > SharedNetwork6Ptr
Pointer to SharedNetwork6 object.
the lease contains non-temporary IPv6 address
boost::shared_ptr< SharedNetwork4 > SharedNetwork4Ptr
Pointer to SharedNetwork4 object.
isc::asiolink::IOAddress getLastAllocated(Lease::Type type) const
returns the last address that was tried from this subnet.
Defines the logger used by the top-level component of kea-dhcp-ddns.
const PoolCollection & getPools(Lease::Type type) const
Returns all pools (const variant).
virtual bool clientSupported(const isc::dhcp::ClientClasses &client_classes) const
Checks whether this subnet and parent shared network supports the client that belongs to specified cl...
Subnet4Ptr getNextSubnet(const Subnet4Ptr &first_subnet) const
Returns next subnet within shared network.
void merge(ElementPtr element, ConstElementPtr other)
Merges the data from other into element.
void setLastAllocated(Lease::Type type, const isc::asiolink::IOAddress &addr)
sets the last address that was tried from this subnet.
PoolCollection & getPoolsWritable(Lease::Type type)
Returns all pools (non-const variant).
uint64_t getPoolCapacity(Lease::Type type) const
Returns the number of possible leases for specified lease type.
Type
Type of lease or pool.
IOAddress lastAddrInPrefix(const IOAddress &prefix, uint8_t len)
returns a last address in a given prefix
static std::pair< asiolink::IOAddress, uint8_t > parsePrefix(const std::string &prefix)
Converts subnet prefix to a pair of prefix/length pair.
virtual void checkType(Lease::Type type) const =0
Checks if used pool type is valid.
std::string toText() const
Convert the address to a string.
Specialization of the Network object for DHCPv4 case.
void delPools(Lease::Type type)
Deletes all pools of specified type.
bool isV6() const
Convenience function to check for an IPv6 address.
isc::asiolink::IOAddress last_allocated_ta_
last allocated temporary address.
boost::shared_ptr< Subnet6 > Subnet6Ptr
A pointer to a Subnet6 object.
bool inPool(Lease::Type type, const isc::asiolink::IOAddress &addr) const
checks if the specified address is in pools.
PoolCollection pools_ta_
collection of IPv6 temporary address pools in that subnet.
The IOAddress class represents an IP addresses (version agnostic)
PoolCollection pools_pd_
collection of IPv6 prefix pools in that subnet.
Container for storing client class names.
void setT1(const Triplet< uint32_t > &t1)
Sets new renew timer for a network.
uint64_t sumPoolCapacity(const PoolCollection &pools) const
Returns a sum of possible leases in all pools.
void setT2(const Triplet< uint32_t > &t2)
Sets new rebind timer for a network.
boost::posix_time::ptime getLastAllocatedTime(const Lease::Type &lease_type) const
Returns the timestamp when the setLastAllocated function was called.
uint32_t SubnetID
Unique identifier for a subnet (both v4 and v6)