]> git.ipfire.org Git - thirdparty/kea.git/commitdiff
[3711] Pools now store maximum possible leases count.
authorTomek Mrugalski <tomasz@isc.org>
Tue, 17 Feb 2015 15:37:34 +0000 (16:37 +0100)
committerTomek Mrugalski <tomasz@isc.org>
Tue, 17 Feb 2015 15:37:34 +0000 (16:37 +0100)
src/lib/dhcpsrv/pool.cc
src/lib/dhcpsrv/pool.h
src/lib/dhcpsrv/tests/pool_unittest.cc

index d9c3da0e4d7a7e47541862bbc8a7d26acdd7ab79..c6e17ba316e4e684d742cc98cb08fb762f690a89 100644 (file)
@@ -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<int>(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<int>(delegated_len)
-                  << ") must be longer than prefix length ("
+                  << ") must be longer than or equal to prefix length ("
                   << static_cast<int>(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
index ae8cb58e69b7df0f626e43c31de553e0b47824b8..388032db165f16d3fc454c678b127559c844be77 100644 (file)
@@ -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
index 402ca2acef5478c9677cdb5adc2ab790b898b79c..f7d4fdd2b37563bcd0ecc05ffdbadf899dffb4aa 100644 (file)
@@ -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