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 #ifndef POOL_H 8 #define POOL_H 9 10 #include <asiolink/io_address.h> 11 #include <cc/data.h> 12 #include <cc/user_context.h> 13 #include <dhcp/classify.h> 14 #include <dhcp/option6_pdexclude.h> 15 #include <dhcpsrv/cfg_option.h> 16 #include <dhcpsrv/lease.h> 17 #include <dhcpsrv/ip_range_permutation.h> 18 19 #include <boost/shared_ptr.hpp> 20 21 #include <vector> 22 23 namespace isc { 24 namespace dhcp { 25 26 /// @brief base class for Pool4 and Pool6 27 /// 28 /// Stores information about pool of IPv4 or IPv6 addresses. 29 /// That is a basic component of a configuration. 30 class Pool : public isc::data::UserContext, public isc::data::CfgToElement { 31 32 public: 33 /// @note: 34 /// PoolType enum was removed. Please use Lease::Type instead 35 36 /// @brief returns Pool-id 37 /// 38 /// @return pool-id value 39 /// Pool-id is an unique value that can be used to identify a pool. getId()40 uint32_t getId() const { 41 return (id_); 42 } 43 44 /// @brief Returns the first address in a pool. 45 /// 46 /// @return first address in a pool getFirstAddress()47 const isc::asiolink::IOAddress& getFirstAddress() const { 48 return (first_); 49 } 50 51 /// @brief Returns the last address in a pool. 52 /// @return last address in a pool getLastAddress()53 const isc::asiolink::IOAddress& getLastAddress() const { 54 return (last_); 55 } 56 57 /// @brief Checks if a given address is in the range. 58 /// 59 /// @return true, if the address is in pool 60 bool inRange(const isc::asiolink::IOAddress& addr) const; 61 62 /// @brief Returns pool type (v4, v6 non-temporary, v6 temp, v6 prefix) 63 /// @return returns pool type getType()64 Lease::Type getType() const { 65 return (type_); 66 } 67 68 /// @brief returns textual representation of the pool 69 /// 70 /// @return textual representation 71 virtual std::string toText() const; 72 73 /// @brief virtual destructor 74 /// 75 /// We need Pool to be a polymorphic class, so we could dynamic cast 76 /// from PoolPtr to Pool6Ptr if we need to. A class becomes polymorphic, 77 /// when there is at least one virtual method. ~Pool()78 virtual ~Pool() { 79 } 80 81 /// @brief Returns the number of all leases in this pool. 82 /// 83 /// Note that this is the upper bound, assuming that no leases are used 84 /// and there are no host reservations. This is just a theoretical calculation. 85 /// @return number of possible leases in this pool getCapacity()86 uint64_t getCapacity() const { 87 return (capacity_); 88 } 89 90 /// @brief Returns pointer to the option data configuration for this pool. getCfgOption()91 CfgOptionPtr getCfgOption() { 92 return (cfg_option_); 93 } 94 95 /// @brief Returns const pointer to the option data configuration for 96 /// this pool. getCfgOption()97 ConstCfgOptionPtr getCfgOption() const { 98 return (cfg_option_); 99 } 100 101 /// @brief Checks whether this pool supports client that belongs to 102 /// specified classes. 103 /// 104 /// @todo: currently doing the same as network which needs improving. 105 /// 106 /// @param client_classes list of all classes the client belongs to 107 /// @return true if client can be supported, false otherwise 108 bool clientSupported(const ClientClasses& client_classes) const; 109 110 /// @brief Sets the supported class to class class_name 111 /// 112 /// @param class_name client class to be supported by this pool 113 void allowClientClass(const ClientClass& class_name); 114 115 /// @brief returns the client class 116 /// 117 /// @note The returned reference is only valid as long as the object 118 /// returned is valid. 119 /// 120 /// @return client class @ref client_class_ getClientClass()121 const ClientClass& getClientClass() const { 122 return (client_class_); 123 } 124 125 /// @brief Adds class class_name to classes required to be evaluated 126 /// 127 /// @param class_name client class required to be evaluated requireClientClass(const ClientClass & class_name)128 void requireClientClass(const ClientClass& class_name) { 129 if (!required_classes_.contains(class_name)) { 130 required_classes_.insert(class_name); 131 } 132 } 133 134 /// @brief Returns classes which are required to be evaluated getRequiredClasses()135 const ClientClasses& getRequiredClasses() const { 136 return (required_classes_); 137 } 138 139 /// @brief returns the last address that was tried from this pool 140 /// 141 /// @return address/prefix that was last tried from this pool getLastAllocated()142 isc::asiolink::IOAddress getLastAllocated() const { 143 return last_allocated_; 144 } 145 146 /// @brief checks if the last address is valid 147 /// @return true if the last address is valid isLastAllocatedValid()148 bool isLastAllocatedValid() const { 149 return last_allocated_valid_; 150 } 151 152 /// @brief sets the last address that was tried from this pool 153 /// 154 /// @param addr address/prefix to that was tried last setLastAllocated(const isc::asiolink::IOAddress & addr)155 void setLastAllocated(const isc::asiolink::IOAddress& addr) { 156 last_allocated_ = addr; 157 last_allocated_valid_ = true; 158 } 159 160 /// @brief resets the last address to invalid resetLastAllocated()161 void resetLastAllocated() { 162 last_allocated_valid_ = false; 163 } 164 165 /// @brief Unparse a pool object. 166 /// 167 /// @return A pointer to unparsed pool configuration. 168 virtual data::ElementPtr toElement() const; 169 170 /// @brief Returns pointer to the permutation associated with the pool. 171 /// 172 /// @return Pointer to the address range permutation. getPermutation()173 IPRangePermutationPtr getPermutation() const { 174 return (permutation_); 175 } 176 177 protected: 178 179 /// @brief protected constructor 180 /// 181 /// This constructor is protected to prevent anyone from instantiating 182 /// Pool class directly. Instances of Pool4 and Pool6 should be created 183 /// instead. 184 /// 185 /// @param type type of lease that will be served from this pool 186 /// @param first first address of a range 187 /// @param last last address of a range 188 Pool(Lease::Type type, 189 const isc::asiolink::IOAddress& first, 190 const isc::asiolink::IOAddress& last); 191 192 /// @brief returns the next unique Pool-ID 193 /// 194 /// @return the next unique Pool-ID getNextID()195 static uint32_t getNextID() { 196 static uint32_t id = 0; 197 return (id++); 198 } 199 200 /// @brief pool-id 201 /// 202 /// This ID is used to identify this specific pool. 203 uint32_t id_; 204 205 /// @brief The first address in a pool 206 isc::asiolink::IOAddress first_; 207 208 /// @brief The last address in a pool 209 isc::asiolink::IOAddress last_; 210 211 /// @brief defines a lease type that will be served from this pool 212 Lease::Type type_; 213 214 /// @brief Stores number of possible leases. 215 /// 216 /// This could be calculated on the fly, but the calculations are somewhat 217 /// involved, so it is more efficient to calculate it once and just store 218 /// the result. Note that for very large pools, the number is capped at 219 /// max value of uint64_t. 220 uint64_t capacity_; 221 222 /// @brief Pointer to the option data configuration for this pool. 223 CfgOptionPtr cfg_option_; 224 225 /// @brief Optional definition of a client class 226 /// 227 /// @ref Network::client_class_ 228 ClientClass client_class_; 229 230 /// @brief Required classes 231 /// 232 /// @ref isc::dhcp::Network::required_classes_ 233 ClientClasses required_classes_; 234 235 /// @brief Pointer to the user context (may be NULL) 236 data::ConstElementPtr user_context_; 237 238 /// @brief Last allocated address 239 /// See @ref isc::dhcp::Subnet::last_allocated_ia_ 240 /// Initialized and reset to first 241 isc::asiolink::IOAddress last_allocated_; 242 243 /// @brief Status of last allocated address 244 bool last_allocated_valid_; 245 246 /// @brief Pointer to the permutation object. 247 /// 248 /// It may be initialized for some pools to provide address 249 /// or delegated prefix randomization capabilities. 250 IPRangePermutationPtr permutation_; 251 }; 252 253 class Pool4; 254 255 /// @brief a pointer an IPv4 Pool 256 typedef boost::shared_ptr<Pool4> Pool4Ptr; 257 258 /// @brief Pool information for IPv4 addresses 259 /// 260 /// It holds information about pool4, i.e. a range of IPv4 address space that 261 /// is configured for DHCP allocation. 262 class Pool4 : public Pool { 263 public: 264 /// @brief the constructor for Pool4 "min-max" style definition 265 /// 266 /// @param first the first address in a pool 267 /// @param last the last address in a pool 268 Pool4(const isc::asiolink::IOAddress& first, 269 const isc::asiolink::IOAddress& last); 270 271 /// @brief the constructor for Pool4 "prefix/len" style definition 272 /// 273 /// @param prefix specifies prefix of the pool 274 /// @param prefix_len specifies length of the prefix of the pool 275 Pool4(const isc::asiolink::IOAddress& prefix, 276 uint8_t prefix_len); 277 278 /// @brief Factory function for creating an instance of the @c Pool4. 279 /// 280 /// This function should be used to create an instance of the pool 281 /// within a hooks library in cases when the library may be unloaded 282 /// before the object is destroyed. This ensures that the ownership 283 /// of the object by the Kea process is retained. 284 /// 285 /// @param first the first address in a pool 286 /// @param last the last address in a pool 287 /// 288 /// @return Pointer to the @c Pool4 instance. 289 static Pool4Ptr create(const isc::asiolink::IOAddress& first, 290 const isc::asiolink::IOAddress& last); 291 292 /// @brief Factory function for creating an instance of the @c Pool4. 293 /// 294 /// This function should be used to create an instance of the pool 295 /// within a hooks library in cases when the library may be unloaded 296 /// before the object is destroyed. This ensures that the ownership 297 /// of the object by the Kea process is retained. 298 /// 299 /// @param prefix specifies prefix of the pool. 300 /// @param prefix_len specifies length of the prefix of the pool. 301 /// 302 /// @return Pointer to the @c Pool4 instance. 303 static Pool4Ptr create(const isc::asiolink::IOAddress& prefix, 304 uint8_t prefix_len); 305 306 /// @brief Unparse a Pool4 object. 307 /// 308 /// @return A pointer to unparsed Pool4 configuration. 309 virtual data::ElementPtr toElement() const; 310 }; 311 312 class Pool6; 313 314 /// @brief a pointer an IPv6 Pool 315 typedef boost::shared_ptr<Pool6> Pool6Ptr; 316 317 /// @brief Pool information for IPv6 addresses and prefixes 318 /// 319 /// It holds information about pool6, i.e. a range of IPv6 address space that 320 /// is configured for DHCP allocation. 321 class Pool6 : public Pool { 322 public: 323 324 /// @brief the constructor for Pool6 "min-max" style definition 325 /// 326 /// @throw BadValue if PD is define (PD can be only prefix/len) 327 /// 328 /// @param type type of the pool (IA or TA) 329 /// @param first the first address in a pool 330 /// @param last the last address in a pool 331 Pool6(Lease::Type type, const isc::asiolink::IOAddress& first, 332 const isc::asiolink::IOAddress& last); 333 334 /// @brief the constructor for Pool6 "prefix/len" style definition 335 /// 336 /// For addressed, this is just a prefix/len definition. For prefixes, 337 /// there is one extra additional parameter delegated_len. It specifies 338 /// a size of delegated prefixes that the pool will be split into. For 339 /// example pool 2001:db8::/56, delegated_len=64 means that there is a 340 /// pool 2001:db8::/56. It will be split into 256 prefixes of length /64, 341 /// e.g. 2001:db8:0:1::/64, 2001:db8:0:2::/64 etc. 342 /// 343 /// Naming convention: 344 /// A smaller prefix length yields a shorter prefix which describes a larger 345 /// set of addresses. A larger length yields a longer prefix which describes 346 /// a smaller set of addresses. 347 /// 348 /// Obviously, prefix_len must define shorter or equal prefix length than 349 /// delegated_len, so prefix_len <= delegated_len. Note that it is slightly 350 /// confusing: bigger (larger) prefix actually has smaller prefix length, 351 /// e.g. /56 is a bigger prefix than /64, but has shorter (smaller) prefix 352 /// length. 353 /// 354 /// @throw BadValue if delegated_len is defined for non-PD types or 355 /// when delegated_len < prefix_len 356 /// 357 /// @param type type of the pool (IA, TA or PD) 358 /// @param prefix specifies prefix of the pool 359 /// @param prefix_len specifies prefix length of the pool 360 /// @param delegated_len specifies length of the delegated prefixes 361 Pool6(Lease::Type type, const isc::asiolink::IOAddress& prefix, 362 uint8_t prefix_len, uint8_t delegated_len = 128); 363 364 /// @brief Constructor for DHCPv6 prefix pool with an excluded prefix. 365 /// 366 /// If @c excluded_prefix is equal to '::' and the @c excluded_prefix_len 367 /// is equal to 0, the excluded prefix is assumed to be unspecified for 368 /// the pool. In this case, the server will not send the Prefix Exclude 369 /// option to a client. 370 /// 371 /// @param prefix specified a prefix of the pool. 372 /// @param prefix_len specifies prefix length of the pool. 373 /// @param delegated_len specifies length of the delegated prefixes. 374 /// @param excluded_prefix specifies an excluded prefix as per RFC6603. 375 /// @param excluded_prefix_len specifies length of an excluded prefix. 376 Pool6(const asiolink::IOAddress& prefix, const uint8_t prefix_len, 377 const uint8_t delegated_len, 378 const asiolink::IOAddress& excluded_prefix, 379 const uint8_t excluded_prefix_len); 380 381 /// @brief Factory function for creating an instance of the @c Pool6. 382 /// 383 /// This function should be used to create an instance of the pool 384 /// within a hooks library in cases when the library may be unloaded 385 /// before the object is destroyed. This ensures that the ownership 386 /// of the object by the Kea process is retained. 387 /// 388 /// @param type type of the pool (IA or TA) 389 /// @param first the first address in a pool 390 /// @param last the last address in a pool 391 /// 392 /// @return Pointer to the @c Pool6 instance. 393 static Pool6Ptr create(Lease::Type type, 394 const isc::asiolink::IOAddress& first, 395 const isc::asiolink::IOAddress& last); 396 397 /// @brief Factory function for creating an instance of the @c Pool6. 398 /// 399 /// This function should be used to create an instance of the pool 400 /// within a hooks library in cases when the library may be unloaded 401 /// before the object is destroyed. This ensures that the ownership 402 /// of the object by the Kea process is retained. 403 /// 404 /// @param type type of the pool (IA, TA or PD) 405 /// @param prefix specifies prefix of the pool 406 /// @param prefix_len specifies prefix length of the pool 407 /// @param delegated_len specifies length of the delegated prefixes 408 /// 409 /// @return Pointer to the @c Pool6 instance. 410 static Pool6Ptr create(Lease::Type type, 411 const isc::asiolink::IOAddress& prefix, 412 uint8_t prefix_len, 413 uint8_t delegated_len = 128); 414 415 /// @brief Factory function for creating an instance of the @c Pool6. 416 /// 417 /// If @c excluded_prefix is equal to '::' and the @c excluded_prefix_len 418 /// is equal to 0, the excluded prefix is assumed to be unspecified for 419 /// the pool. In this case, the server will not send the Prefix Exclude 420 /// option to a client. 421 /// 422 /// @param prefix specifies a prefix of the pool. 423 /// @param prefix_len specifies prefix length of the pool. 424 /// @param delegated_len specifies length of the delegated prefixes. 425 /// @param excluded_prefix specifies an excluded prefix as per RFC6603. 426 /// @param excluded_prefix_len specifies length of an excluded prefix. 427 /// 428 /// @return Pointer to the @c Pool6 instance. 429 static Pool6Ptr create(const asiolink::IOAddress& prefix, 430 const uint8_t prefix_len, 431 const uint8_t delegated_len, 432 const asiolink::IOAddress& excluded_prefix, 433 const uint8_t excluded_prefix_len); 434 435 /// @brief returns pool type 436 /// 437 /// @return pool type getType()438 Lease::Type getType() const { 439 return (type_); 440 } 441 442 /// @brief returns delegated prefix length 443 /// 444 /// This may be useful for "prefix/len" style definition for 445 /// addresses, but is mostly useful for prefix pools. 446 /// @return prefix length (1-128) getLength()447 uint8_t getLength() const { 448 return (prefix_len_); 449 } 450 451 /// @brief Returns instance of the pool specific Prefix Exclude option. 452 /// 453 /// @return An instance of the Prefix Exclude option (RFC 6603) or NULL 454 /// if such option hasn't been specified for the pool. getPrefixExcludeOption()455 Option6PDExcludePtr getPrefixExcludeOption() const { 456 return (pd_exclude_option_); 457 } 458 459 /// @brief Unparse a Pool6 object. 460 /// 461 /// @return A pointer to unparsed Pool6 configuration. 462 virtual data::ElementPtr toElement() const; 463 464 /// @brief returns textual representation of the pool 465 /// 466 /// @return textual representation 467 virtual std::string toText() const; 468 469 private: 470 471 /// @brief Generic method initializing a DHCPv6 pool. 472 /// 473 /// This method should be called by the constructors to initialize 474 /// DHCPv6 pools. 475 /// 476 /// @param Lease/pool type. 477 /// @param prefix An address or delegated prefix (depending on the 478 /// pool type specified as @c type). 479 /// @param prefix_len Prefix length. If a pool is an address pool, 480 /// this value should be set to 128. 481 /// @param delegated_len Length of the delegated prefixes. If a pool 482 /// is an address pool, this value should be set to 128. 483 /// @param excluded_prefix An excluded prefix as per RFC6603. This 484 /// value should only be specified for prefix pools. The value of 485 /// '::' means "unspecified". 486 /// @param excluded_prefix_len Length of the excluded prefix. This 487 /// is only specified for prefix pools. The value of 0 should be 488 /// used when @c excluded_prefix is not specified. 489 void init(const Lease::Type& type, 490 const asiolink::IOAddress& prefix, 491 const uint8_t prefix_len, 492 const uint8_t delegated_len, 493 const asiolink::IOAddress& excluded_prefix, 494 const uint8_t excluded_prefix_len); 495 496 /// @brief Defines prefix length (for TYPE_PD only) 497 uint8_t prefix_len_; 498 499 /// @brief A pointer to the Prefix Exclude option (RFC 6603). 500 Option6PDExcludePtr pd_exclude_option_; 501 502 }; 503 504 /// @brief a pointer to either IPv4 or IPv6 Pool 505 typedef boost::shared_ptr<Pool> PoolPtr; 506 507 /// @brief a container for either IPv4 or IPv6 Pools 508 typedef std::vector<PoolPtr> PoolCollection; 509 510 511 } // end of isc::dhcp namespace 512 } // end of isc namespace 513 514 515 #endif // POOL_H 516