]> git.ipfire.org Git - thirdparty/kea.git/commitdiff
[#2869] Revamped set/getExtendedInfoTablesEnabled
authorFrancis Dupont <fdupont@isc.org>
Thu, 25 May 2023 22:41:50 +0000 (00:41 +0200)
committerFrancis Dupont <fdupont@isc.org>
Thu, 6 Jul 2023 20:11:32 +0000 (22:11 +0200)
src/lib/dhcpsrv/lease_mgr.h
src/lib/dhcpsrv/mysql_lease_mgr.cc
src/lib/dhcpsrv/mysql_lease_mgr.h
src/lib/dhcpsrv/pgsql_lease_mgr.cc
src/lib/dhcpsrv/pgsql_lease_mgr.h
src/lib/dhcpsrv/tests/memfile_lease_extended_info_unittest.cc
src/lib/dhcpsrv/tests/memfile_lease_mgr_unittest.cc

index ce60d3dff41a7e9782920273ee43a12a289e14fb..160639eedbe77ce197abda5b0796d5bb007c29a9 100644 (file)
@@ -1023,15 +1023,23 @@ public:
     /// @return The number of updates in the database.
     virtual size_t upgradeExtendedInfo4(const LeasePageSize& page_size) = 0;
 
-    /// @brief Returns the setting indicating if lease extended info tables
+    /// @brief Returns the setting indicating if lease6 extended info tables
     /// are enabled.
     ///
-    /// @return true if lease extended info tables are enabled or false
+    /// @return true if lease6 extended info tables are enabled or false
     /// if they are disabled.
     bool getExtendedInfoTablesEnabled() const {
         return (extended_info_tables_enabled_);
     }
 
+    /// @brief Modifies the setting whether the lease6 extended info tables
+    /// are enabled.
+    ///
+    /// @param enabled new setting.
+    void setExtendedInfoTablesEnabled(const bool enabled) {
+        extended_info_tables_enabled_ = enabled;
+    }
+
     /// @brief Build extended info v6 tables.
     ///
     /// @param update Update extended info in database.
@@ -1061,24 +1069,13 @@ protected:
 
     /// Extended information / Bulk Lease Query shared interface.
 
-    /// @brief Modifies the setting whether the lease extended info tables
-    /// are enabled.
-    ///
-    /// @note This method is virtual so backend doing specific action
-    /// on value changes can intercept it by redefining it.
-    ///
-    /// @param enabled new setting.
-    virtual void setExtendedInfoTablesEnabled(const bool enabled) {
-        extended_info_tables_enabled_ = enabled;
-    }
-
     /// @brief Decode parameters to set whether the lease extended info tables
     /// are enabled.
     ///
     /// @note: common code in constructors.
     ///
     /// @param parameters The parameter map.
-    virtual void setExtendedInfoTablesEnabled(const db::DatabaseConnection::ParameterMap& parameters);
+    void setExtendedInfoTablesEnabled(const db::DatabaseConnection::ParameterMap& parameters);
 
     /// @brief Extract extended info from a lease6 and add it into tables.
     ///
index 47203365691dbc1927e73b31b98e05f3dcfe1880..3a50a293f0a1473348b33d231cf4c007e4d0d921 100644 (file)
@@ -2183,18 +2183,13 @@ MySqlLeaseMgr::MySqlLeaseTrackingContextAlloc::~MySqlLeaseTrackingContextAlloc()
     // If running in single-threaded mode, there's nothing to do here.
 }
 
-void
-MySqlLeaseMgr::setExtendedInfoTablesEnabled(const db::DatabaseConnection::ParameterMap& /* parameters */) {
-    isc_throw(isc::NotImplemented, "extended info tables are not yet supported by mysql");
-}
-
 // MySqlLeaseMgr Constructor and Destructor
 
 MySqlLeaseMgr::MySqlLeaseMgr(const DatabaseConnection::ParameterMap& parameters)
     : TrackingLeaseMgr(), parameters_(parameters), timer_name_("") {
 
     // Check if the extended info tables are enabled.
-    LeaseMgr::setExtendedInfoTablesEnabled(parameters);
+    setExtendedInfoTablesEnabled(parameters);
 
     // Create unique timer name per instance.
     timer_name_ = "MySqlLeaseMgr[";
@@ -2397,6 +2392,8 @@ MySqlLeaseMgr::addLease(const Lease6Ptr& lease) {
         .arg(lease->addr_.toText())
         .arg(lease->type_);
 
+    lease->extended_info_action_ = Lease6::ACTION_IGNORE;
+
     // Get a context
     MySqlLeaseTrackingContextAlloc get_context(*this, lease);
     MySqlLeaseContextPtr ctx = get_context.ctx_;
@@ -2411,6 +2408,12 @@ MySqlLeaseMgr::addLease(const Lease6Ptr& lease) {
     // of the Lease up to the point of insertion in the database).
     lease->updateCurrentExpirationTime();
 
+    if (getExtendedInfoTablesEnabled()) {
+        // Expired leases can be removed leaving entries in extended info tables.
+        deleteExtendedInfo6(lease->addr_);
+        static_cast<void>(addExtendedInfo6(lease));
+    }
+
     // Run installed callbacks.
     if (hasCallbacks()) {
         trackAddLease(lease, false);
@@ -3301,6 +3304,10 @@ MySqlLeaseMgr::updateLease6(const Lease6Ptr& lease) {
         .arg(lease->addr_.toText())
         .arg(lease->type_);
 
+    // Get the recorded action and reset it.
+    Lease6::ExtendedInfoAction recorded_action = lease->extended_info_action_;
+    lease->extended_info_action_ = Lease6::ACTION_IGNORE;
+
     // Get a context
     MySqlLeaseTrackingContextAlloc get_context(*this, lease);
     MySqlLeaseContextPtr ctx = get_context.ctx_;
@@ -3347,6 +3354,23 @@ MySqlLeaseMgr::updateLease6(const Lease6Ptr& lease) {
     // Update lease current expiration time.
     lease->updateCurrentExpirationTime();
 
+    // Update extended info tables.
+    if (getExtendedInfoTablesEnabled()) {
+        switch (recorded_action) {
+        case Lease6::ACTION_IGNORE:
+            break;
+
+        case Lease6::ACTION_DELETE:
+            deleteExtendedInfo6(lease->addr_);
+            break;
+
+        case Lease6::ACTION_UPDATE:
+            deleteExtendedInfo6(lease->addr_);
+            static_cast<void>(addExtendedInfo6(lease));
+            break;
+        }
+    }
+
     // Run installed callbacks.
     if (hasCallbacks()) {
         trackUpdateLease(lease, false);
@@ -3436,6 +3460,8 @@ MySqlLeaseMgr::deleteLease(const Lease6Ptr& lease) {
               DHCPSRV_MYSQL_DELETE_ADDR)
         .arg(addr.toText());
 
+    lease->extended_info_action_ = Lease6::ACTION_IGNORE;
+
     // Set up the WHERE clause value
     MYSQL_BIND inbind[2];
     memset(inbind, 0, sizeof(inbind));
@@ -3473,6 +3499,12 @@ MySqlLeaseMgr::deleteLease(const Lease6Ptr& lease) {
 
     // Check success case first as it is the most likely outcome.
     if (affected_rows == 1) {
+        // Delete references from extended info tables.
+        if (getExtendedInfoTablesEnabled()) {
+            deleteExtendedInfo6(lease->addr_);
+        }
+
+        // Run installed callbacks.
         if (hasCallbacks()) {
             trackDeleteLease(lease, false);
         }
@@ -3911,7 +3943,7 @@ MySqlLeaseMgr::addRelayId6(const IOAddress& lease_addr,
     std::vector<uint8_t> lease_addr_data = lease_addr.toBytes();
     unsigned long lease_addr_length = lease_addr_data.size();
     if (lease_addr_length != 16) {
-        isc_throw(DbOperationError, "lease6 address is not 16 byte long");
+        isc_throw(DbOperationError, "lease6 address is not 16 bytes long");
     }
     bind[1].buffer_type = MYSQL_TYPE_BLOB;
     bind[1].buffer = reinterpret_cast<char*>(&lease_addr_data[0]);
@@ -3955,7 +3987,7 @@ MySqlLeaseMgr::addRemoteId6(const IOAddress& lease_addr,
     std::vector<uint8_t> lease_addr_data = lease_addr.toBytes();
     unsigned long lease_addr_length = lease_addr_data.size();
     if (lease_addr_length != 16) {
-        isc_throw(DbOperationError, "lease6 address is not 16 byte long");
+        isc_throw(DbOperationError, "lease6 address is not 16 bytes long");
     }
     bind[1].buffer_type = MYSQL_TYPE_BLOB;
     bind[1].buffer = reinterpret_cast<char*>(&lease_addr_data[0]);
@@ -4345,7 +4377,7 @@ MySqlLeaseMgr::getExtendedInfo6Common(MySqlLeaseContextPtr& ctx,
     std::list<IOAddress> result;
     while ((status = mysql_stmt_fetch(ctx->conn_.statements_[stindex])) == 0) {
         if (addr_size != 16) {
-            isc_throw(BadValue, "received lease6 address is not 16 byte long");
+            isc_throw(BadValue, "received lease6 address is not 16 bytes long");
         }
         result.push_back(IOAddress::fromBytes(AF_INET6, addr_data));
     }
@@ -4419,7 +4451,7 @@ MySqlLeaseMgr::getLeases6ByRelayId(const DUID& relay_id,
         std::vector<uint8_t> lb_addr_data = lower_bound_address.toBytes();
         unsigned long lb_addr_size = lb_addr_data.size();
         if (lb_addr_size != 16) {
-            isc_throw(DbOperationError, "lower bound address is not 16 byte long");
+            isc_throw(DbOperationError, "lower bound address is not 16 bytes long");
         }
         bind[1].buffer_type = MYSQL_TYPE_BLOB;
         bind[1].buffer = reinterpret_cast<char*>(&lb_addr_data[0]);
@@ -4462,7 +4494,7 @@ MySqlLeaseMgr::getLeases6ByRelayId(const DUID& relay_id,
         std::vector<uint8_t> start_addr_data = start_addr.toBytes();
         unsigned long start_addr_size = start_addr_data.size();
         if (start_addr_size != 16) {
-            isc_throw(DbOperationError, "start address is not 16 byte long");
+            isc_throw(DbOperationError, "start address is not 16 bytes long");
         }
         bind[1].buffer_type = MYSQL_TYPE_BLOB;
         bind[1].buffer = reinterpret_cast<char*>(&start_addr_data[0]);
@@ -4473,7 +4505,7 @@ MySqlLeaseMgr::getLeases6ByRelayId(const DUID& relay_id,
         std::vector<uint8_t> last_addr_data = last_addr.toBytes();
         unsigned long last_addr_size = last_addr_data.size();
         if (last_addr_size != 16) {
-            isc_throw(DbOperationError, "last address is not 16 byte long");
+            isc_throw(DbOperationError, "last address is not 16 bytes long");
         }
         bind[2].buffer_type = MYSQL_TYPE_BLOB;
         bind[2].buffer = reinterpret_cast<char*>(&last_addr_data[0]);
@@ -4585,7 +4617,7 @@ MySqlLeaseMgr::getLeases6ByRemoteId(const OptionBuffer& remote_id,
         std::vector<uint8_t> lb_addr_data = lower_bound_address.toBytes();
         unsigned long lb_addr_size = lb_addr_data.size();
         if (lb_addr_size != 16) {
-            isc_throw(DbOperationError, "lower bound address is not 16 byte long");
+            isc_throw(DbOperationError, "lower bound address is not 16 bytes long");
         }
         bind[1].buffer_type = MYSQL_TYPE_BLOB;
         bind[1].buffer = reinterpret_cast<char*>(&lb_addr_data[0]);
@@ -4628,7 +4660,7 @@ MySqlLeaseMgr::getLeases6ByRemoteId(const OptionBuffer& remote_id,
         std::vector<uint8_t> start_addr_data = start_addr.toBytes();
         unsigned long start_addr_size = start_addr_data.size();
         if (start_addr_size != 16) {
-            isc_throw(DbOperationError, "start address is not 16 byte long");
+            isc_throw(DbOperationError, "start address is not 16 bytes long");
         }
         bind[1].buffer_type = MYSQL_TYPE_BLOB;
         bind[1].buffer = reinterpret_cast<char*>(&start_addr_data[0]);
@@ -4639,7 +4671,7 @@ MySqlLeaseMgr::getLeases6ByRemoteId(const OptionBuffer& remote_id,
         std::vector<uint8_t> last_addr_data = last_addr.toBytes();
         unsigned long last_addr_size = last_addr_data.size();
         if (last_addr_size != 16) {
-            isc_throw(DbOperationError, "last address is not 16 byte long");
+            isc_throw(DbOperationError, "last address is not 16 bytes long");
         }
         bind[2].buffer_type = MYSQL_TYPE_BLOB;
         bind[2].buffer = reinterpret_cast<char*>(&last_addr_data[0]);
index afa18833d5b6eac94555e06761f6bd2059599ec3..c11328312163cc268e3336e80d67cc506a1b021a 100644 (file)
@@ -1262,26 +1262,6 @@ protected:
 
     /// Extended information / Bulk Lease Query shared interface.
 
-    /// @brief Modifies the setting whether the lease extended info tables
-    /// are enabled.
-    ///
-    /// Transient redefine to refuse the enable setting.
-    /// @param enabled new setting.
-    virtual void setExtendedInfoTablesEnabled(const bool enabled) override {
-        if (enabled) {
-            isc_throw(isc::NotImplemented,
-                      "extended info tables are not yet supported by mysql");
-        }
-    }
-
-    /// @brief Decode parameters to set whether the lease extended info tables
-    /// are enabled.
-    ///
-    /// @note: common code in constructors.
-    ///
-    /// @param parameters The parameter map.
-    virtual void setExtendedInfoTablesEnabled(const db::DatabaseConnection::ParameterMap& parameters) override;
-
     /// @brief Delete lease6 extended info from tables.
     ///
     /// @param addr The address of the lease.
index c852186e42492ab5af3516e6793d5d842f61b6f1..257913ab65880de6a8cc04bcbdb867971859ecaa 100644 (file)
@@ -1620,18 +1620,13 @@ PgSqlLeaseMgr::PgSqlLeaseTrackingContextAlloc::~PgSqlLeaseTrackingContextAlloc()
     // If running in single-threaded mode, there's nothing to do here.
 }
 
-void
-PgSqlLeaseMgr::setExtendedInfoTablesEnabled(const db::DatabaseConnection::ParameterMap& /* parameters */) {
-    isc_throw(isc::NotImplemented, "extended info tables are not yet supported by mysql");
-}
-
 // PgSqlLeaseMgr Constructor and Destructor
 
 PgSqlLeaseMgr::PgSqlLeaseMgr(const DatabaseConnection::ParameterMap& parameters)
     : TrackingLeaseMgr(), parameters_(parameters), timer_name_("") {
 
     // Check if the extended info tables are enabled.
-    LeaseMgr::setExtendedInfoTablesEnabled(parameters);
+    setExtendedInfoTablesEnabled(parameters);
 
     // Create unique timer name per instance.
     timer_name_ = "PgSqlLeaseMgr[";
@@ -1846,6 +1841,8 @@ PgSqlLeaseMgr::addLease(const Lease6Ptr& lease) {
         .arg(lease->addr_.toText())
         .arg(lease->type_);
 
+    lease->extended_info_action_ = Lease6::ACTION_IGNORE;
+
     // Get a context
     PgSqlLeaseTrackingContextAlloc get_context(*this, lease);
     PgSqlLeaseContextPtr ctx = get_context.ctx_;
@@ -1859,6 +1856,12 @@ PgSqlLeaseMgr::addLease(const Lease6Ptr& lease) {
     // of the Lease up to the point of insertion in the database).
     lease->updateCurrentExpirationTime();
 
+    if (getExtendedInfoTablesEnabled()) {
+        // Expired leases can be removed leaving entries in extended info tables.
+        deleteExtendedInfo6(lease->addr_);
+        static_cast<void>(addExtendedInfo6(lease));
+    }
+
     // Run installed callbacks.
     if (hasCallbacks()) {
         trackAddLease(lease, false);
@@ -2530,6 +2533,10 @@ PgSqlLeaseMgr::updateLease6(const Lease6Ptr& lease) {
         .arg(lease->addr_.toText())
         .arg(lease->type_);
 
+    // Get the recorded action and reset it.
+    Lease6::ExtendedInfoAction recorded_action = lease->extended_info_action_;
+    lease->extended_info_action_ = Lease6::ACTION_IGNORE;
+
     // Get a context
     PgSqlLeaseTrackingContextAlloc get_context(*this, lease);
     PgSqlLeaseContextPtr ctx = get_context.ctx_;
@@ -2558,6 +2565,23 @@ PgSqlLeaseMgr::updateLease6(const Lease6Ptr& lease) {
     // Update lease current expiration time.
     lease->updateCurrentExpirationTime();
 
+    // Update extended info tables.
+    if (getExtendedInfoTablesEnabled()) {
+        switch (recorded_action) {
+        case Lease6::ACTION_IGNORE:
+            break;
+
+        case Lease6::ACTION_DELETE:
+            deleteExtendedInfo6(lease->addr_);
+            break;
+
+        case Lease6::ACTION_UPDATE:
+            deleteExtendedInfo6(lease->addr_);
+            static_cast<void>(addExtendedInfo6(lease));
+            break;
+        }
+    }
+
     // Run installed callbacks.
     if (hasCallbacks()) {
         trackUpdateLease(lease, false);
@@ -2634,6 +2658,8 @@ PgSqlLeaseMgr::deleteLease(const Lease6Ptr& lease) {
               DHCPSRV_PGSQL_DELETE_ADDR)
         .arg(addr.toText());
 
+    lease->extended_info_action_ = Lease6::ACTION_IGNORE;
+
     // Set up the WHERE clause value
     PsqlBindArray bind_array;
 
@@ -2658,6 +2684,12 @@ PgSqlLeaseMgr::deleteLease(const Lease6Ptr& lease) {
 
     // Check success case first as it is the most likely outcome.
     if (affected_rows == 1) {
+        // Delete references from extended info tables.
+        if (getExtendedInfoTablesEnabled()) {
+            deleteExtendedInfo6(lease->addr_);
+        }
+
+        // Run installed callbacks.
         if (hasCallbacks()) {
             trackDeleteLease(lease, false);
         }
@@ -3067,7 +3099,7 @@ PgSqlLeaseMgr::addRelayId6(const IOAddress& lease_addr,
     // Bind the lease address.
     std::vector<uint8_t> lease_addr_data = lease_addr.toBytes();
     if (lease_addr_data.size() != 16) {
-        isc_throw(DbOperationError, "lease6 address is not 16 byte long");
+        isc_throw(DbOperationError, "lease6 address is not 16 bytes long");
     }
     bind_array.add(lease_addr_data);
 
@@ -3106,7 +3138,7 @@ PgSqlLeaseMgr::addRemoteId6(const IOAddress& lease_addr,
     // Bind the lease address.
     std::vector<uint8_t> lease_addr_data = lease_addr.toBytes();
     if (lease_addr_data.size() != 16) {
-        isc_throw(DbOperationError, "lease6 address is not 16 byte long");
+        isc_throw(DbOperationError, "lease6 address is not 16 bytes long");
     }
     bind_array.add(lease_addr_data);
 
@@ -3432,7 +3464,7 @@ PgSqlLeaseMgr::getExtendedInfo6Common(PgSqlLeaseContextPtr& ctx,
         std::vector<uint8_t> addr_data;
         PgSqlLeaseExchange::convertFromBytea(r, i, 0, addr_data);
         if (addr_data.size() != 16) {
-            isc_throw(BadValue, "received lease6 address is not 16 byte long");
+            isc_throw(BadValue, "received lease6 address is not 16 bytes long");
         }
         result.push_back(IOAddress::fromBytes(AF_INET6, &addr_data[0]));
     }
@@ -3491,7 +3523,7 @@ PgSqlLeaseMgr::getLeases6ByRelayId(const DUID& relay_id,
         // Bind the lower bound address.
         std::vector<uint8_t> lb_addr_data = lower_bound_address.toBytes();
         if (lb_addr_data.size() != 16) {
-            isc_throw(DbOperationError, "lower bound address is not 16 byte long");
+            isc_throw(DbOperationError, "lower bound address is not 16 bytes long");
         }
         bind_array.add(lb_addr_data);
 
@@ -3524,14 +3556,14 @@ PgSqlLeaseMgr::getLeases6ByRelayId(const DUID& relay_id,
         // Bind the start address.
         std::vector<uint8_t> start_addr_data = start_addr.toBytes();
         if (start_addr_data.size() != 16) {
-            isc_throw(DbOperationError, "start address is not 16 byte long");
+            isc_throw(DbOperationError, "start address is not 16 bytes long");
         }
         bind_array.add(start_addr_data);
 
         // Bind the last address.
         std::vector<uint8_t> last_addr_data = last_addr.toBytes();
         if (last_addr_data.size() != 16) {
-            isc_throw(DbOperationError, "last address is not 16 byte long");
+            isc_throw(DbOperationError, "last address is not 16 bytes long");
         }
         bind_array.add(last_addr_data);
 
@@ -3626,7 +3658,7 @@ PgSqlLeaseMgr::getLeases6ByRemoteId(const OptionBuffer& remote_id,
         // Bind the lower bound address.
         std::vector<uint8_t> lb_addr_data = lower_bound_address.toBytes();
         if (lb_addr_data.size() != 16) {
-            isc_throw(DbOperationError, "lower bound address is not 16 byte long");
+            isc_throw(DbOperationError, "lower bound address is not 16 bytes long");
         }
         bind_array.add(lb_addr_data);
 
@@ -3659,14 +3691,14 @@ PgSqlLeaseMgr::getLeases6ByRemoteId(const OptionBuffer& remote_id,
         // Bind the start address.
         std::vector<uint8_t> start_addr_data = start_addr.toBytes();
         if (start_addr_data.size() != 16) {
-            isc_throw(DbOperationError, "start address is not 16 byte long");
+            isc_throw(DbOperationError, "start address is not 16 bytes long");
         }
         bind_array.add(start_addr_data);
 
         // Bind the last address.
         std::vector<uint8_t> last_addr_data = last_addr.toBytes();
         if (last_addr_data.size() != 16) {
-            isc_throw(DbOperationError, "last address is not 16 byte long");
+            isc_throw(DbOperationError, "last address is not 16 bytes long");
         }
         bind_array.add(last_addr_data);
 
index b320a63ec987296176c92eb4a6ae53bf546b78ba..511d51e6540f4a037870ac52eedea860b8e51262 100644 (file)
@@ -1222,26 +1222,6 @@ protected:
 
     /// Extended information / Bulk Lease Query shared interface.
 
-    /// @brief Modifies the setting whether the lease extended info tables
-    /// are enabled.
-    ///
-    /// Transient redefine to refuse the enable setting.
-    /// @param enabled new setting.
-    virtual void setExtendedInfoTablesEnabled(const bool enabled) override {
-        if (enabled) {
-            isc_throw(isc::NotImplemented,
-                      "extended info tables are not yet supported by postgresql");
-        }
-    }
-
-    /// @brief Decode parameters to set whether the lease extended info tables
-    /// are enabled.
-    ///
-    /// @note: common code in constructors.
-    ///
-    /// @param parameters The parameter map.
-    virtual void setExtendedInfoTablesEnabled(const db::DatabaseConnection::ParameterMap& parameters) override;
-
     /// @brief Delete lease6 extended info from tables.
     ///
     /// @param addr The address of the lease.
index 4b1efcde6871b4f6a3332c610f5d20daa54239d2..b941cb02b54e8a6140195ce8ced57153e5c9c322 100644 (file)
@@ -61,7 +61,6 @@ public:
     }
 
     /// @brief Exposes protected methods and members.
-    using LeaseMgr::setExtendedInfoTablesEnabled;
     using Memfile_LeaseMgr::relay_id6_;
     using Memfile_LeaseMgr::remote_id6_;
     using Memfile_LeaseMgr::deleteExtendedInfo6;
index 111c2e4e73caa7d2d0bfb4b03466be29f907dd9f..dab857496993426dcd2eece481c7293443ddde55 100644 (file)
@@ -97,7 +97,6 @@ public:
     }
 
     using Memfile_LeaseMgr::lfcCallback;
-    using Memfile_LeaseMgr::setExtendedInfoTablesEnabled;
     using Memfile_LeaseMgr::relay_id6_;
     using Memfile_LeaseMgr::remote_id6_;
     using Memfile_LeaseMgr::buildExtendedInfoTables6;