Browse Source

[3555] Changes after review:

 - Comments updated
 - getRawHWAddr renamed to getHWAddrVector and moved to Lease class
 - HWAddr object is now copied in copy ctor and = operator
Tomek Mrugalski 10 years ago
parent
commit
cb2fc012c6

+ 1 - 0
src/lib/dhcpsrv/csv_lease_file6.h

@@ -106,6 +106,7 @@ private:
     /// - fqdn_fwd
     /// - fqdn_fwd
     /// - fqdn_rev
     /// - fqdn_rev
     /// - hostname
     /// - hostname
+    /// - hwaddr
     void initColumns();
     void initColumns();
 
 
     ///
     ///

+ 1 - 1
src/lib/dhcpsrv/dhcpsrv_messages.mes

@@ -313,7 +313,7 @@ testing but should not be enabled in normal circumstances. Non-persistence
 mode is enabled when 'persist4=no persist6=no' parameters are specified
 mode is enabled when 'persist4=no persist6=no' parameters are specified
 in the database access string.
 in the database access string.
 
 
-% DHCPSRV_MEMFILE_READ_HWADDR_FAIL failed to read hardware address from disk: %1
+% DHCPSRV_MEMFILE_READ_HWADDR_FAIL failed to read hardware address from lease file: %1
 A warning message issued when read attempt of the hardware address stored in
 A warning message issued when read attempt of the hardware address stored in
 a disk file failed. The parameter should provide the exact nature of the failure.
 a disk file failed. The parameter should provide the exact nature of the failure.
 The database read will continue, but that particular lease will no longer
 The database read will continue, but that particular lease will no longer

+ 27 - 10
src/lib/dhcpsrv/lease.cc

@@ -72,6 +72,11 @@ Lease4::Lease4(const Lease4& other)
     fixed_ = other.fixed_;
     fixed_ = other.fixed_;
     comments_ = other.comments_;
     comments_ = other.comments_;
 
 
+    // Copy the hardware address if it is defined.
+    if (other.hwaddr_) {
+        hwaddr_.reset(new HWAddr(*other.hwaddr_));
+    }
+
     if (other.client_id_) {
     if (other.client_id_) {
         client_id_.reset(new ClientId(other.client_id_->getClientId()));
         client_id_.reset(new ClientId(other.client_id_->getClientId()));
 
 
@@ -92,12 +97,10 @@ Lease4::getClientIdVector() const {
 }
 }
 
 
 const std::vector<uint8_t>&
 const std::vector<uint8_t>&
-Lease4::getRawHWAddr() const {
+Lease::getHWAddrVector() const {
     if (!hwaddr_) {
     if (!hwaddr_) {
-        // something is wrong, very wrong. Hardware address must always
-        // be present for all IPv4 leases.
-        isc_throw(BadValue, "Lease4 for address " << addr_.toText()
-                  << " is missing a hardware address");
+        static std::vector<uint8_t> empty_vec;
+        return (empty_vec);
     }
     }
     return (hwaddr_->hwaddr_);
     return (hwaddr_->hwaddr_);
 }
 }
@@ -118,12 +121,20 @@ Lease4::matches(const Lease4& other) const {
 
 
     // Note that hwaddr_ is now a poiner to the HWAddr structure.
     // Note that hwaddr_ is now a poiner to the HWAddr structure.
     // We can't simply compare smart pointers, we need to compare the
     // We can't simply compare smart pointers, we need to compare the
-    // actual objects they point to. It is ok to not check whether they
-    // are non-NULL, as every Lease4 must have hardware address.
+    // actual objects they point to. If one of the leases had a hardware address
+    // and the other doesn't, they clearly don't match.
+    if ( (!hwaddr_ && other.hwaddr_) ||
+         (hwaddr_ && !other.hwaddr_) ) {
+        return (false);
+    }
+
+    // The lease is equal if addresses and extensions match and there is
+    // either the same hardware address on both or neither have hardware address
+    // specified.
     return (addr_ == other.addr_ &&
     return (addr_ == other.addr_ &&
             ext_ == other.ext_ &&
             ext_ == other.ext_ &&
-            *hwaddr_ == *other.hwaddr_);
-
+            (!hwaddr_ ||
+             *hwaddr_ == *other.hwaddr_) );
 }
 }
 
 
 Lease4&
 Lease4&
@@ -141,7 +152,11 @@ Lease4::operator=(const Lease4& other) {
         fqdn_rev_ = other.fqdn_rev_;
         fqdn_rev_ = other.fqdn_rev_;
         comments_ = other.comments_;
         comments_ = other.comments_;
         ext_ = other.ext_;
         ext_ = other.ext_;
-        hwaddr_ = other.hwaddr_;
+
+        // Copy the hardware address if it is defined.
+        if (other.hwaddr_) {
+            hwaddr_.reset(new HWAddr(*other.hwaddr_));
+        }
 
 
         if (other.client_id_) {
         if (other.client_id_) {
             client_id_.reset(new ClientId(other.client_id_->getClientId()));
             client_id_.reset(new ClientId(other.client_id_->getClientId()));
@@ -211,6 +226,7 @@ Lease6::toText() const {
            << "Pref life:     " << preferred_lft_ << "\n"
            << "Pref life:     " << preferred_lft_ << "\n"
            << "Valid life:    " << valid_lft_ << "\n"
            << "Valid life:    " << valid_lft_ << "\n"
            << "Cltt:          " << cltt_ << "\n"
            << "Cltt:          " << cltt_ << "\n"
+           << "Hardware addr: " << (hwaddr_?hwaddr_->toText(false):"(none)")
            << "Subnet ID:     " << subnet_id_ << "\n";
            << "Subnet ID:     " << subnet_id_ << "\n";
 
 
     return (stream.str());
     return (stream.str());
@@ -225,6 +241,7 @@ Lease4::toText() const {
            << "T1:            " << t1_ << "\n"
            << "T1:            " << t1_ << "\n"
            << "T2:            " << t2_ << "\n"
            << "T2:            " << t2_ << "\n"
            << "Cltt:          " << cltt_ << "\n"
            << "Cltt:          " << cltt_ << "\n"
+           << "Hardware addr: " << (hwaddr_?hwaddr_->toText(false):"(none)")
            << "Subnet ID:     " << subnet_id_ << "\n";
            << "Subnet ID:     " << subnet_id_ << "\n";
 
 
     return (stream.str());
     return (stream.str());

+ 9 - 8
src/lib/dhcpsrv/lease.h

@@ -156,6 +156,15 @@ struct Lease {
     /// lease is equal to the FQDN data of our lease (true) or not (false).
     /// lease is equal to the FQDN data of our lease (true) or not (false).
     bool hasIdenticalFqdn(const Lease& other) const;
     bool hasIdenticalFqdn(const Lease& other) const;
 
 
+    /// @brief Returns raw (as vector) hardware address
+    ///
+    /// This method is needed in multi-index container as key extractor.
+    /// The const reference is only valid as long as the object that returned it.
+    /// In the unlikely case when Lease4 does not have a hardware address,
+    /// the function will return an empty vector.
+    ///
+    /// @return const reference to the hardware address
+    const std::vector<uint8_t>& getHWAddrVector() const;
 };
 };
 
 
 /// @brief Structure that holds a lease for IPv4 address
 /// @brief Structure that holds a lease for IPv4 address
@@ -230,14 +239,6 @@ struct Lease4 : public Lease {
     /// or an empty vector if client identifier is NULL.
     /// or an empty vector if client identifier is NULL.
     const std::vector<uint8_t>& getClientIdVector() const;
     const std::vector<uint8_t>& getClientIdVector() const;
 
 
-    /// @brief Returns raw (as vector) hardware address
-    ///
-    /// This method is needed in multi-index container as key extractor.
-    /// The const reference is only valid as long as the object that returned it.
-    ///
-    /// @return const reference to the hardware address
-    const std::vector<uint8_t>& getRawHWAddr() const;
-
     /// @brief Check if two objects encapsulate the lease for the same
     /// @brief Check if two objects encapsulate the lease for the same
     /// client.
     /// client.
     ///
     ///

+ 4 - 4
src/lib/dhcpsrv/memfile_lease_mgr.h

@@ -454,8 +454,8 @@ protected:
                     // Lease4 object, which is a HWAddr object. Boost does not
                     // Lease4 object, which is a HWAddr object. Boost does not
                     // provide a key extractor for getting a member of a member,
                     // provide a key extractor for getting a member of a member,
                     // so we need a simple method for that.
                     // so we need a simple method for that.
-                    boost::multi_index::const_mem_fun<Lease4, const std::vector<uint8_t>&,
-                                               &Lease4::getRawHWAddr>,
+                    boost::multi_index::const_mem_fun<Lease, const std::vector<uint8_t>&,
+                                               &Lease::getHWAddrVector>,
                     // The subnet id is held in the subnet_id_ member of Lease4
                     // The subnet id is held in the subnet_id_ member of Lease4
                     // class. Note that the subnet_id_ is defined in the base
                     // class. Note that the subnet_id_ is defined in the base
                     // class (Lease) so we have to point to this class rather
                     // class (Lease) so we have to point to this class rather
@@ -493,8 +493,8 @@ protected:
                     // access the raw data using lease->hwaddr_->hwaddr_, but Boost
                     // access the raw data using lease->hwaddr_->hwaddr_, but Boost
                     // doesn't seem to provide a way to use member of a member for this,
                     // doesn't seem to provide a way to use member of a member for this,
                     // so we need a simple key extractor method (getRawHWAddr).
                     // so we need a simple key extractor method (getRawHWAddr).
-                    boost::multi_index::const_mem_fun<Lease4, const std::vector<uint8_t>&,
-                                            &Lease4::getRawHWAddr>,
+                    boost::multi_index::const_mem_fun<Lease, const std::vector<uint8_t>&,
+                                            &Lease::getHWAddrVector>,
                     // The subnet id is accessed through the subnet_id_ member.
                     // The subnet id is accessed through the subnet_id_ member.
                     boost::multi_index::member<Lease, SubnetID, &Lease::subnet_id_>
                     boost::multi_index::member<Lease, SubnetID, &Lease::subnet_id_>
                 >
                 >

+ 14 - 0
src/lib/dhcpsrv/tests/lease_unittest.cc

@@ -141,6 +141,13 @@ TEST_F(Lease4Test, copyConstructor) {
     EXPECT_TRUE(lease == copied_lease);
     EXPECT_TRUE(lease == copied_lease);
     // Client IDs are equal, but they should be in two distinct pointers.
     // Client IDs are equal, but they should be in two distinct pointers.
     EXPECT_FALSE(lease.client_id_ == copied_lease.client_id_);
     EXPECT_FALSE(lease.client_id_ == copied_lease.client_id_);
+
+    // Hardware addresses are equal, but they should point to two objects,
+    // each holding the same data. The content should be equal...
+    EXPECT_TRUE(*lease.hwaddr_ == *copied_lease.hwaddr_);
+
+    // ... but it should point to different objects.
+    EXPECT_FALSE(lease.hwaddr_ == copied_lease.hwaddr_);
 }
 }
 
 
 // This test verfies that the assignment operator copies all Lease4 fields
 // This test verfies that the assignment operator copies all Lease4 fields
@@ -172,6 +179,13 @@ TEST_F(Lease4Test, operatorAssign) {
     EXPECT_TRUE(lease == copied_lease);
     EXPECT_TRUE(lease == copied_lease);
     // Client IDs are equal, but they should be in two distinct pointers.
     // Client IDs are equal, but they should be in two distinct pointers.
     EXPECT_FALSE(lease.client_id_ == copied_lease.client_id_);
     EXPECT_FALSE(lease.client_id_ == copied_lease.client_id_);
+
+    // Hardware addresses are equal, but they should point to two objects,
+    // each holding the same data. The content should be equal...
+    EXPECT_TRUE(*lease.hwaddr_ == *copied_lease.hwaddr_);
+
+    // ... but it should point to different objects.
+    EXPECT_FALSE(lease.hwaddr_ == copied_lease.hwaddr_);
 }
 }
 
 
 // This test verifies that the matches() returns true if two leases differ
 // This test verifies that the matches() returns true if two leases differ