/src/kea/src/lib/dhcpsrv/random_allocator.h
Line | Count | Source |
1 | | // Copyright (C) 2022-2023 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 RANDOM_ALLOCATOR_H |
8 | | #define RANDOM_ALLOCATOR_H |
9 | | |
10 | | #include <dhcpsrv/allocator.h> |
11 | | #include <dhcpsrv/random_allocation_state.h> |
12 | | #include <dhcpsrv/lease.h> |
13 | | #include <cstdint> |
14 | | #include <random> |
15 | | |
16 | | namespace isc { |
17 | | namespace dhcp { |
18 | | |
19 | | /// @brief An allocator offering addresses in a random order. |
20 | | /// |
21 | | /// This allocator uses @c IPRangePermutation to select random |
22 | | /// addresses or delegated prefixes from the pools. It guarantees |
23 | | /// that all offered addresses are unique (do not repeat). |
24 | | /// |
25 | | /// The allocator also randomly picks pools to ensure that the |
26 | | /// leases are offered uniformly from the entire subnet rather than |
27 | | /// from the same pool until it exhausts. When all pools exhaust, |
28 | | /// the allocator resets their permutations and begins offering |
29 | | /// leases from these pools again. |
30 | | class RandomAllocator : public Allocator { |
31 | | public: |
32 | | |
33 | | /// @brief Constructor. |
34 | | /// |
35 | | /// @param type specifies the type of allocated leases. |
36 | | /// @param subnet weak pointer to the subnet owning the allocator. |
37 | | RandomAllocator(Lease::Type type, const WeakSubnetPtr& subnet); |
38 | | |
39 | | /// @brief Returns the allocator type string. |
40 | | /// |
41 | | /// @return random string. |
42 | 0 | virtual std::string getType() const { |
43 | 0 | return ("random"); |
44 | 0 | } |
45 | | |
46 | | private: |
47 | | |
48 | | /// @brief Returns a random address from the pools in the subnet. |
49 | | /// |
50 | | /// Internal thread-unsafe implementation of the @c pickAddress. |
51 | | /// |
52 | | /// @param client_classes list of classes client belongs to. |
53 | | /// @param duid client DUID (ignored). |
54 | | /// @param hint client hint (ignored). |
55 | | /// |
56 | | /// @return next offered address. |
57 | | virtual asiolink::IOAddress pickAddressInternal(const ClientClasses& client_classes, |
58 | | const IdentifierBaseTypePtr& duid, |
59 | | const asiolink::IOAddress& hint); |
60 | | |
61 | | /// @brief Picks a delegated prefix. |
62 | | /// |
63 | | /// Internal thread-unsafe implementation of the @c pickPrefix. |
64 | | /// |
65 | | /// @param client_classes list of classes client belongs to. |
66 | | /// @param pool the selected pool satisfying all required conditions. |
67 | | /// @param duid Client's DUID. |
68 | | /// @param prefix_length_match type which indicates the selection criteria |
69 | | /// for the pools relative to the provided hint prefix length |
70 | | /// @param hint Client's hint. |
71 | | /// @param hint_prefix_length the hint prefix length that the client |
72 | | /// provided. The 0 value means that there is no hint and that any |
73 | | /// pool will suffice. |
74 | | /// |
75 | | /// @return the next prefix. |
76 | | virtual asiolink::IOAddress pickPrefixInternal(const ClientClasses& client_classes, |
77 | | Pool6Ptr& pool, |
78 | | const IdentifierBaseTypePtr& duid, |
79 | | PrefixLenMatchType prefix_length_match, |
80 | | const asiolink::IOAddress& hint, |
81 | | uint8_t hint_prefix_length); |
82 | | |
83 | | /// @brief Convenience function returning pool allocation state instance. |
84 | | /// |
85 | | /// It creates a new pool state instance and assigns it to the pool |
86 | | /// if it hasn't been initialized. |
87 | | /// |
88 | | /// @param pool pool instance. |
89 | | /// @return allocation state instance for the pool. |
90 | | PoolRandomAllocationStatePtr getPoolState(const PoolPtr& pool) const; |
91 | | |
92 | | /// @brief Convenience function returning a random number. |
93 | | /// |
94 | | /// It is used internally by the @c pickAddressInternal function to |
95 | | /// select a random pool. |
96 | | /// |
97 | | /// @param limit upper bound of the range. |
98 | | /// @returns random number between 0 and limit. |
99 | | uint64_t getRandomNumber(uint64_t limit); |
100 | | |
101 | | /// @brief Random generator used by this class. |
102 | | std::mt19937 generator_; |
103 | | }; |
104 | | |
105 | | } // end of namespace isc::dhcp |
106 | | } // end of namespace isc |
107 | | |
108 | | #endif // RANDOM_ALLOCATOR_H |