From: Tomek Mrugalski Date: Tue, 17 Feb 2015 15:37:34 +0000 (+0100) Subject: [3711] Pools now store maximum possible leases count. X-Git-Tag: trac3723_base~18^2~6 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=303c0d3e63628f0420bde8e25d2277fb6ec64ce4;p=thirdparty%2Fkea.git [3711] Pools now store maximum possible leases count. --- diff --git a/src/lib/dhcpsrv/pool.cc b/src/lib/dhcpsrv/pool.cc index d9c3da0e4d..c6e17ba316 100644 --- a/src/lib/dhcpsrv/pool.cc +++ b/src/lib/dhcpsrv/pool.cc @@ -50,6 +50,12 @@ Pool4::Pool4(const isc::asiolink::IOAddress& first, if (last < first) { isc_throw(BadValue, "Upper boundary is smaller than lower boundary."); } + + // This is IPv4 pool, which only has one type. We can calculate + // the number of theoretically possible leases in it. As there's 2^32 + // possible IPv4 addresses, we'll be able to accurately store that + // info. + leases_count_ = addrsInRange(first, last); } Pool4::Pool4( const isc::asiolink::IOAddress& prefix, uint8_t prefix_len) @@ -67,8 +73,13 @@ Pool4::Pool4( const isc::asiolink::IOAddress& prefix, uint8_t prefix_len) // Let's now calculate the last address in defined pool last_ = lastAddrInPrefix(prefix, prefix_len); -} + // This is IPv4 pool, which only has one type. We can calculate + // the number of theoretically possible leases in it. As there's 2^32 + // possible IPv4 addresses, we'll be able to accurately store that + // info. + leases_count_ = addrsInRange(prefix, last_); +} Pool6::Pool6(Lease::Type type, const isc::asiolink::IOAddress& first, const isc::asiolink::IOAddress& last) @@ -105,6 +116,11 @@ Pool6::Pool6(Lease::Type type, const isc::asiolink::IOAddress& first, isc_throw(BadValue, "Invalid Pool6 type specified:" << static_cast(type)); } + + // Let's calculate the theoretical number of leases in this pool. + // If the pool is extremely large (i.e. contains more than 2^64 addresses, + // we'll just cap it at max value of uint64_t). + leases_count_ = addrsInRange(first, last); } Pool6::Pool6(Lease::Type type, const isc::asiolink::IOAddress& prefix, @@ -123,7 +139,7 @@ Pool6::Pool6(Lease::Type type, const isc::asiolink::IOAddress& prefix, if (prefix_len > delegated_len) { isc_throw(BadValue, "Delegated length (" << static_cast(delegated_len) - << ") must be longer than prefix length (" + << ") must be longer than or equal to prefix length (" << static_cast(prefix_len) << ")"); } @@ -138,6 +154,11 @@ Pool6::Pool6(Lease::Type type, const isc::asiolink::IOAddress& prefix, // Let's now calculate the last address in defined pool last_ = lastAddrInPrefix(prefix, prefix_len); + + // Let's calculate the theoretical number of leases in this pool. + // For addresses, we could use addrsInRange(prefix, last_), but it's + // much faster to do calculations on prefix lengths. + leases_count_ = prefixesInRange(prefix_len, delegated_len); } std::string @@ -149,6 +170,5 @@ Pool6::toText() const { return (tmp.str()); } - }; // end of isc::dhcp namespace }; // end of isc namespace diff --git a/src/lib/dhcpsrv/pool.h b/src/lib/dhcpsrv/pool.h index ae8cb58e69..388032db16 100644 --- a/src/lib/dhcpsrv/pool.h +++ b/src/lib/dhcpsrv/pool.h @@ -79,6 +79,14 @@ public: 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 getLeasesCount() const { + return (leases_count_); + } protected: /// @brief protected constructor @@ -120,6 +128,14 @@ protected: /// @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 leases_count_; }; /// @brief Pool information for IPv4 addresses diff --git a/src/lib/dhcpsrv/tests/pool_unittest.cc b/src/lib/dhcpsrv/tests/pool_unittest.cc index 402ca2acef..f7d4fdd2b3 100644 --- a/src/lib/dhcpsrv/tests/pool_unittest.cc +++ b/src/lib/dhcpsrv/tests/pool_unittest.cc @@ -81,6 +81,21 @@ TEST(Pool4Test, in_range) { EXPECT_FALSE(pool1.inRange(IOAddress("0.0.0.0"))); } +// Checks if the number of possible leases in range is reported correctly. +TEST(Pool4Test, leasesCount) { + Pool4 pool1(IOAddress("192.0.2.10"), IOAddress("192.0.2.20")); + EXPECT_EQ(11, pool1.getLeasesCount()); + + Pool4 pool2(IOAddress("192.0.2.0"), IOAddress("192.0.2.255")); + EXPECT_EQ(256, pool2.getLeasesCount()); + + Pool4 pool3(IOAddress("192.168.0.0"), IOAddress("192.168.255.255")); + EXPECT_EQ(65536, pool3.getLeasesCount()); + + Pool4 pool4(IOAddress("10.0.0.0"), IOAddress("10.255.255.255")); + EXPECT_EQ(16777216, pool4.getLeasesCount()); +} + // This test creates 100 pools and verifies that their IDs are unique. TEST(Pool4Test, unique_id) { @@ -263,4 +278,16 @@ TEST(Poo6Test,toText) { pool2.toText()); } +// Checks if the number of possible leases in range is reported correctly. +TEST(Pool6Test, leasesCount) { + Pool6 pool1(Lease::TYPE_NA, IOAddress("2001:db8::1"), + IOAddress("2001:db8::2")); + EXPECT_EQ(2, pool1.getLeasesCount()); + + Pool6 pool2(Lease::TYPE_PD, IOAddress("2001:db8:1::"), 96, 112); + EXPECT_EQ(65536, pool2.getLeasesCount()); +} + + + }; // end of anonymous namespace