@@ -20,24 +20,24 @@ namespace dhcp {
2020
2121// / @brief Random IP address/prefix permutation based on Fisher-Yates shuffle.
2222// /
23- // / This class is used to shuffle IP addresses within the specified address
24- // / range. It is following the Fisher-Yates shuffle algorithm described in
25- // / https://en.wikipedia.org/wiki/Fisher–Yates_shuffle.
23+ // / This class is used to shuffle IP addresses or delegated prefixes within
24+ // / the specified range. It is following the Fisher-Yates shuffle algorithm
25+ // / described in https://en.wikipedia.org/wiki/Fisher–Yates_shuffle.
2626// /
2727// / The original algorithm is modified to keep the minimal information about
2828// / the current state of the permutation and relies on the caller to collect
2929// / and store the next available value. In other words, the generated and
3030// / already returned random values are not stored by this class.
3131// /
32- // / The class assumes that initially the IP addresses in the specified range
33- // / are in increasing order. Suppose we're dealing with the following address
34- // / range: 192.0.2.1-192.0.2.5. Therefore our addresses are initially ordered
35- // / like this: a[0]=192.0.2.1, a[1]=192.0.2.2 ..., a[4]=192.0.2.5. The
36- // / algorithm starts from the end of that range, i.e. i=4, so a[i]=192.0.2.5.
37- // / A random value from the range of [0..i-1] is picked, i.e. a value from the
38- // / range of [0..3]. Let's say it is 1. This value initially corresponds to the
39- // / address a[1]=192.0.2.2. In the original algorithm the value of a[1] is
40- // / swapped with a[4], yelding the following partial permutation:
32+ // / The class assumes that initially the IP addresses or delegated prefixes
33+ // / in the specified range are in increasing order. Suppose we're dealing with
34+ // / the following address range: 192.0.2.1-192.0.2.5. Therefore our addresses
35+ // / are initially ordered like this: a[0]=192.0.2.1, a[1]=192.0.2.2 ...,
36+ // / a[4]=192.0.2.5. The algorithm starts from the end of that range, i.e. i=4,
37+ // / so a[i]=192.0.2.5. A random value from the range of [0..i-1] is picked,
38+ // / i.e. a value from the range of [0..3]. Let's say it is 1. This value initially
39+ // / corresponds to the address a[1]=192.0.2.2. In the original algorithm the
40+ // / value of a[1] is swapped with a[4], yelding the following partial permutation:
4141// / 192.0.2.1, 192.0.2.5, 192.0.2.3, 192.0.2.4, 192.0.2.2. In our case, we simply
4242// / return the value of 192.0.2.2 to the caller and remember that
4343// / a[1]=192.0.2.5. At this point we don't store the values of a[0], a[2] and
@@ -57,58 +57,73 @@ namespace dhcp {
5757// / start and the position. The other two have been already returned to the
5858// / caller so we forget them.
5959// /
60- // / This algorithm guarantees that all IP addresses beloging to the given
61- // / address range are returned and no duplicates are returned. The addresses
62- // / are returned in a random order.
60+ // / This algorithm guarantees that all IP addresses or delegated prefixes
61+ // / beloging to the given range are returned and no duplicates are returned.
62+ // / The addresses or delegated prefixes are returned in a random order.
6363class IPRangePermutation {
6464public:
6565
6666 // / Address range.
6767 typedef AddressRange Range;
6868
69- // / @brief Constructor.
69+ // / Prefix range.
70+ typedef PrefixRange PrefixRange;
71+
72+ // / @brief Constructor for address ranges.
7073 // /
7174 // / @param range address range for which the permutation will be generated.
7275 IPRangePermutation (const Range& range);
7376
74- // / @brief Checks if the address range has been exhausted.
77+ // / @brief Constructor for prefix ranges.
78+ // /
79+ // / @param range range of delegated prefixes for which the permutation will
80+ // / be generated.
81+ IPRangePermutation (const PrefixRange& range);
82+
83+ // / @brief Checks if the range has been exhausted.
7584 // /
76- // / @return false if the algorithm went over all addresses in the
77- // / range, true otherwise.
85+ // / @return false if the algorithm went over all addresses or prefixes in
86+ // / the range, true otherwise.
7887 bool exhausted () const {
7988 return (done_);
8089 }
8190
82- // / @brief Returns next random address from the permutation.
91+ // / @brief Returns next random address or prefix from the permutation.
8392 // /
84- // / This method will returns all addresses belonging to the specified
85- // / address range in random order. For the first number of calls equal
86- // / to the size of the address range it guarantees to return a non-zero
87- // / IP address from that range without duplicates.
93+ // / This method returns all addresses or prefixes belonging to the specified
94+ // / range in random order. For the first number of calls equal to the size of
95+ // / the range it guarantees to return a non-zero IP address from that range
96+ // / without duplicates.
8897 // /
8998 // / @param [out] done this parameter is set to true if no more addresses
90- // / can be returned for this permutation.
91- // / @return next available IP address. It returns IPv4 zero or IPv6 zero
92- // / address after this method walked over all available IP addresses in
93- // / the range.
99+ // / or prefixes can be returned for this permutation.
100+ // / @return next available IP address or prefix . It returns IPv4 zero or IPv6
101+ // / zero address after this method walked over all available IP addresses or
102+ // / prefixes in the range.
94103 asiolink::IOAddress next (bool & done);
95104
96105private:
97106
98- // / Address range used in this permutation and specified in the
99- // / constructor.
100- Range range_;
107+ // / Beginning of the range.
108+ asiolink::IOAddress range_start_;
109+
110+ // / Distance between two neighboring addresses or delegated prefixes,
111+ // / i.e. 1 for address range and delegated prefix size for delegated
112+ // / prefixes.
113+ uint64_t step_;
101114
102- // / Keeps the possition of the next address to be swapped with a
103- // / randomly picked address from the range of 0..cursor-1. The
104- // / cursor value is decreased every time a new IP address is returned.
115+ // / Keeps the position of the next address or prefix to be swapped with
116+ // / a randomly picked address or prefix from the range of 0..cursor-1. The
117+ // / cursor value is decreased every time a new IP address or prefix
118+ // / is returned.
105119 uint64_t cursor_;
106120
107121 // / Keeps the current permutation state. The state associates the
108- // / swapped IP addresses with their positions in the permutation.
122+ // / swapped IP addresses or delegated prefixes with their positions in
123+ // / the permutation.
109124 std::map<uint64_t , asiolink::IOAddress> state_;
110125
111- // / Indicates if the addresses are exhausted.
126+ // / Indicates if the addresses or delegated prefixes are exhausted.
112127 bool done_;
113128
114129 // / Random generator.
@@ -121,4 +136,4 @@ typedef boost::shared_ptr<IPRangePermutation> IPRangePermutationPtr;
121136} // end of namespace isc::dhcp
122137} // end of namespace isc
123138
124- #endif // ADDRESS_RANGE_PERMUTATION_H
139+ #endif // IP_RANGE_PERMUTATION_H
0 commit comments