// Copyright (C) 2012-2020 Internet Systems Consortium, Inc. ("ISC") // // This Source Code Form is subject to the terms of the Mozilla Public // License, v. 2.0. If a copy of the MPL was not distributed with this // file, You can obtain one at http://mozilla.org/MPL/2.0/. #ifndef POOL_H #define POOL_H #include #include #include #include #include #include #include #include #include #include namespace isc { namespace dhcp { /// @brief base class for Pool4 and Pool6 /// /// Stores information about pool of IPv4 or IPv6 addresses. /// That is a basic component of a configuration. class Pool : public isc::data::UserContext, public isc::data::CfgToElement { public: /// @note: /// PoolType enum was removed. Please use Lease::Type instead /// @brief returns Pool-id /// /// @return pool-id value /// Pool-id is an unique value that can be used to identify a pool. uint32_t getId() const { return (id_); } /// @brief Returns the first address in a pool. /// /// @return first address in a pool const isc::asiolink::IOAddress& getFirstAddress() const { return (first_); } /// @brief Returns the last address in a pool. /// @return last address in a pool const isc::asiolink::IOAddress& getLastAddress() const { return (last_); } /// @brief Checks if a given address is in the range. /// /// @return true, if the address is in pool bool inRange(const isc::asiolink::IOAddress& addr) const; /// @brief Returns pool type (v4, v6 non-temporary, v6 temp, v6 prefix) /// @return returns pool type Lease::Type getType() const { return (type_); } /// @brief returns textual representation of the pool /// /// @return textual representation virtual std::string toText() const; /// @brief virtual destructor /// /// We need Pool to be a polymorphic class, so we could dynamic cast /// from PoolPtr to Pool6Ptr if we need to. A class becomes polymorphic, /// when there is at least one virtual method. virtual ~Pool() { } /// @brief Returns the number of all leases in this pool. /// /// Note that this is the upper bound, assuming that no leases are used /// and there are no host reservations. This is just a theoretical calculation. /// @return number of possible leases in this pool uint64_t getCapacity() const { return (capacity_); } /// @brief Returns pointer to the option data configuration for this pool. CfgOptionPtr getCfgOption() { return (cfg_option_); } /// @brief Returns const pointer to the option data configuration for /// this pool. ConstCfgOptionPtr getCfgOption() const { return (cfg_option_); } /// @brief Checks whether this pool supports client that belongs to /// specified classes. /// /// @todo: currently doing the same as network which needs improving. /// /// @param client_classes list of all classes the client belongs to /// @return true if client can be supported, false otherwise bool clientSupported(const ClientClasses& client_classes) const; /// @brief Sets the supported class to class class_name /// /// @param class_name client class to be supported by this pool void allowClientClass(const ClientClass& class_name); /// @brief returns the client class /// /// @note The returned reference is only valid as long as the object /// returned is valid. /// /// @return client class @ref client_class_ const ClientClass& getClientClass() const { return (client_class_); } /// @brief Adds class class_name to classes required to be evaluated /// /// @param class_name client class required to be evaluated void requireClientClass(const ClientClass& class_name) { if (!required_classes_.contains(class_name)) { required_classes_.insert(class_name); } } /// @brief Returns classes which are required to be evaluated const ClientClasses& getRequiredClasses() const { return (required_classes_); } /// @brief returns the last address that was tried from this pool /// /// @return address/prefix that was last tried from this pool isc::asiolink::IOAddress getLastAllocated() const { return last_allocated_; } /// @brief checks if the last address is valid /// @return true if the last address is valid bool isLastAllocatedValid() const { return last_allocated_valid_; } /// @brief sets the last address that was tried from this pool /// /// @param addr address/prefix to that was tried last void setLastAllocated(const isc::asiolink::IOAddress& addr) { last_allocated_ = addr; last_allocated_valid_ = true; } /// @brief resets the last address to invalid void resetLastAllocated() { last_allocated_valid_ = false; } /// @brief Unparse a pool object. /// /// @return A pointer to unparsed pool configuration. virtual data::ElementPtr toElement() const; /// @brief Returns pointer to the permutation associated with the pool. /// /// @return Pointer to the address range permutation. IPRangePermutationPtr getPermutation() const { return (permutation_); } protected: /// @brief protected constructor /// /// This constructor is protected to prevent anyone from instantiating /// Pool class directly. Instances of Pool4 and Pool6 should be created /// instead. /// /// @param type type of lease that will be served from this pool /// @param first first address of a range /// @param last last address of a range Pool(Lease::Type type, const isc::asiolink::IOAddress& first, const isc::asiolink::IOAddress& last); /// @brief returns the next unique Pool-ID /// /// @return the next unique Pool-ID static uint32_t getNextID() { static uint32_t id = 0; return (id++); } /// @brief pool-id /// /// This ID is used to identify this specific pool. uint32_t id_; /// @brief The first address in a pool isc::asiolink::IOAddress first_; /// @brief The last address in a pool isc::asiolink::IOAddress last_; /// @brief defines a lease type that will be served from this pool Lease::Type type_; /// @brief Stores number of possible leases. /// /// This could be calculated on the fly, but the calculations are somewhat /// involved, so it is more efficient to calculate it once and just store /// the result. Note that for very large pools, the number is capped at /// max value of uint64_t. uint64_t capacity_; /// @brief Pointer to the option data configuration for this pool. CfgOptionPtr cfg_option_; /// @brief Optional definition of a client class /// /// @ref Network::client_class_ ClientClass client_class_; /// @brief Required classes /// /// @ref isc::dhcp::Network::required_classes_ ClientClasses required_classes_; /// @brief Pointer to the user context (may be NULL) data::ConstElementPtr user_context_; /// @brief Last allocated address /// See @ref isc::dhcp::Subnet::last_allocated_ia_ /// Initialized and reset to first isc::asiolink::IOAddress last_allocated_; /// @brief Status of last allocated address bool last_allocated_valid_; /// @brief Pointer to the permutation object. /// /// It may be initialized for some pools to provide address /// or delegated prefix randomization capabilities. IPRangePermutationPtr permutation_; }; class Pool4; /// @brief a pointer an IPv4 Pool typedef boost::shared_ptr Pool4Ptr; /// @brief Pool information for IPv4 addresses /// /// It holds information about pool4, i.e. a range of IPv4 address space that /// is configured for DHCP allocation. class Pool4 : public Pool { public: /// @brief the constructor for Pool4 "min-max" style definition /// /// @param first the first address in a pool /// @param last the last address in a pool Pool4(const isc::asiolink::IOAddress& first, const isc::asiolink::IOAddress& last); /// @brief the constructor for Pool4 "prefix/len" style definition /// /// @param prefix specifies prefix of the pool /// @param prefix_len specifies length of the prefix of the pool Pool4(const isc::asiolink::IOAddress& prefix, uint8_t prefix_len); /// @brief Factory function for creating an instance of the @c Pool4. /// /// This function should be used to create an instance of the pool /// within a hooks library in cases when the library may be unloaded /// before the object is destroyed. This ensures that the ownership /// of the object by the Kea process is retained. /// /// @param first the first address in a pool /// @param last the last address in a pool /// /// @return Pointer to the @c Pool4 instance. static Pool4Ptr create(const isc::asiolink::IOAddress& first, const isc::asiolink::IOAddress& last); /// @brief Factory function for creating an instance of the @c Pool4. /// /// This function should be used to create an instance of the pool /// within a hooks library in cases when the library may be unloaded /// before the object is destroyed. This ensures that the ownership /// of the object by the Kea process is retained. /// /// @param prefix specifies prefix of the pool. /// @param prefix_len specifies length of the prefix of the pool. /// /// @return Pointer to the @c Pool4 instance. static Pool4Ptr create(const isc::asiolink::IOAddress& prefix, uint8_t prefix_len); /// @brief Unparse a Pool4 object. /// /// @return A pointer to unparsed Pool4 configuration. virtual data::ElementPtr toElement() const; }; class Pool6; /// @brief a pointer an IPv6 Pool typedef boost::shared_ptr Pool6Ptr; /// @brief Pool information for IPv6 addresses and prefixes /// /// It holds information about pool6, i.e. a range of IPv6 address space that /// is configured for DHCP allocation. class Pool6 : public Pool { public: /// @brief the constructor for Pool6 "min-max" style definition /// /// @throw BadValue if PD is define (PD can be only prefix/len) /// /// @param type type of the pool (IA or TA) /// @param first the first address in a pool /// @param last the last address in a pool Pool6(Lease::Type type, const isc::asiolink::IOAddress& first, const isc::asiolink::IOAddress& last); /// @brief the constructor for Pool6 "prefix/len" style definition /// /// For addressed, this is just a prefix/len definition. For prefixes, /// there is one extra additional parameter delegated_len. It specifies /// a size of delegated prefixes that the pool will be split into. For /// example pool 2001:db8::/56, delegated_len=64 means that there is a /// pool 2001:db8::/56. It will be split into 256 prefixes of length /64, /// e.g. 2001:db8:0:1::/64, 2001:db8:0:2::/64 etc. /// /// Naming convention: /// A smaller prefix length yields a shorter prefix which describes a larger /// set of addresses. A larger length yields a longer prefix which describes /// a smaller set of addresses. /// /// Obviously, prefix_len must define shorter or equal prefix length than /// delegated_len, so prefix_len <= delegated_len. Note that it is slightly /// confusing: bigger (larger) prefix actually has smaller prefix length, /// e.g. /56 is a bigger prefix than /64, but has shorter (smaller) prefix /// length. /// /// @throw BadValue if delegated_len is defined for non-PD types or /// when delegated_len < prefix_len /// /// @param type type of the pool (IA, TA or PD) /// @param prefix specifies prefix of the pool /// @param prefix_len specifies prefix length of the pool /// @param delegated_len specifies length of the delegated prefixes Pool6(Lease::Type type, const isc::asiolink::IOAddress& prefix, uint8_t prefix_len, uint8_t delegated_len = 128); /// @brief Constructor for DHCPv6 prefix pool with an excluded prefix. /// /// If @c excluded_prefix is equal to '::' and the @c excluded_prefix_len /// is equal to 0, the excluded prefix is assumed to be unspecified for /// the pool. In this case, the server will not send the Prefix Exclude /// option to a client. /// /// @param prefix specified a prefix of the pool. /// @param prefix_len specifies prefix length of the pool. /// @param delegated_len specifies length of the delegated prefixes. /// @param excluded_prefix specifies an excluded prefix as per RFC6603. /// @param excluded_prefix_len specifies length of an excluded prefix. Pool6(const asiolink::IOAddress& prefix, const uint8_t prefix_len, const uint8_t delegated_len, const asiolink::IOAddress& excluded_prefix, const uint8_t excluded_prefix_len); /// @brief Factory function for creating an instance of the @c Pool6. /// /// This function should be used to create an instance of the pool /// within a hooks library in cases when the library may be unloaded /// before the object is destroyed. This ensures that the ownership /// of the object by the Kea process is retained. /// /// @param type type of the pool (IA or TA) /// @param first the first address in a pool /// @param last the last address in a pool /// /// @return Pointer to the @c Pool6 instance. static Pool6Ptr create(Lease::Type type, const isc::asiolink::IOAddress& first, const isc::asiolink::IOAddress& last); /// @brief Factory function for creating an instance of the @c Pool6. /// /// This function should be used to create an instance of the pool /// within a hooks library in cases when the library may be unloaded /// before the object is destroyed. This ensures that the ownership /// of the object by the Kea process is retained. /// /// @param type type of the pool (IA, TA or PD) /// @param prefix specifies prefix of the pool /// @param prefix_len specifies prefix length of the pool /// @param delegated_len specifies length of the delegated prefixes /// /// @return Pointer to the @c Pool6 instance. static Pool6Ptr create(Lease::Type type, const isc::asiolink::IOAddress& prefix, uint8_t prefix_len, uint8_t delegated_len = 128); /// @brief Factory function for creating an instance of the @c Pool6. /// /// If @c excluded_prefix is equal to '::' and the @c excluded_prefix_len /// is equal to 0, the excluded prefix is assumed to be unspecified for /// the pool. In this case, the server will not send the Prefix Exclude /// option to a client. /// /// @param prefix specifies a prefix of the pool. /// @param prefix_len specifies prefix length of the pool. /// @param delegated_len specifies length of the delegated prefixes. /// @param excluded_prefix specifies an excluded prefix as per RFC6603. /// @param excluded_prefix_len specifies length of an excluded prefix. /// /// @return Pointer to the @c Pool6 instance. static Pool6Ptr create(const asiolink::IOAddress& prefix, const uint8_t prefix_len, const uint8_t delegated_len, const asiolink::IOAddress& excluded_prefix, const uint8_t excluded_prefix_len); /// @brief returns pool type /// /// @return pool type Lease::Type getType() const { return (type_); } /// @brief returns delegated prefix length /// /// This may be useful for "prefix/len" style definition for /// addresses, but is mostly useful for prefix pools. /// @return prefix length (1-128) uint8_t getLength() const { return (prefix_len_); } /// @brief Returns instance of the pool specific Prefix Exclude option. /// /// @return An instance of the Prefix Exclude option (RFC 6603) or NULL /// if such option hasn't been specified for the pool. Option6PDExcludePtr getPrefixExcludeOption() const { return (pd_exclude_option_); } /// @brief Unparse a Pool6 object. /// /// @return A pointer to unparsed Pool6 configuration. virtual data::ElementPtr toElement() const; /// @brief returns textual representation of the pool /// /// @return textual representation virtual std::string toText() const; private: /// @brief Generic method initializing a DHCPv6 pool. /// /// This method should be called by the constructors to initialize /// DHCPv6 pools. /// /// @param Lease/pool type. /// @param prefix An address or delegated prefix (depending on the /// pool type specified as @c type). /// @param prefix_len Prefix length. If a pool is an address pool, /// this value should be set to 128. /// @param delegated_len Length of the delegated prefixes. If a pool /// is an address pool, this value should be set to 128. /// @param excluded_prefix An excluded prefix as per RFC6603. This /// value should only be specified for prefix pools. The value of /// '::' means "unspecified". /// @param excluded_prefix_len Length of the excluded prefix. This /// is only specified for prefix pools. The value of 0 should be /// used when @c excluded_prefix is not specified. void init(const Lease::Type& type, const asiolink::IOAddress& prefix, const uint8_t prefix_len, const uint8_t delegated_len, const asiolink::IOAddress& excluded_prefix, const uint8_t excluded_prefix_len); /// @brief Defines prefix length (for TYPE_PD only) uint8_t prefix_len_; /// @brief A pointer to the Prefix Exclude option (RFC 6603). Option6PDExcludePtr pd_exclude_option_; }; /// @brief a pointer to either IPv4 or IPv6 Pool typedef boost::shared_ptr PoolPtr; /// @brief a container for either IPv4 or IPv6 Pools typedef std::vector PoolCollection; } // end of isc::dhcp namespace } // end of isc namespace #endif // POOL_H