Browse Source

[3711] Pools now store maximum possible leases count.

Tomek Mrugalski 10 years ago
parent
commit
303c0d3e63
3 changed files with 66 additions and 3 deletions
  1. 23 3
      src/lib/dhcpsrv/pool.cc
  2. 16 0
      src/lib/dhcpsrv/pool.h
  3. 27 0
      src/lib/dhcpsrv/tests/pool_unittest.cc

+ 23 - 3
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<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

+ 16 - 0
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

+ 27 - 0
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