]> git.ipfire.org Git - thirdparty/kea.git/commitdiff
[#2022] Checkpoint: last version of parking code
authorFrancis Dupont <fdupont@isc.org>
Thu, 8 Feb 2024 20:27:57 +0000 (21:27 +0100)
committerAndrei Pavel <andrei@isc.org>
Mon, 19 Feb 2024 15:49:45 +0000 (17:49 +0200)
src/bin/dhcp6/dhcp6_srv.cc
src/bin/dhcp6/dhcp6_srv.h

index 25e357103001e62920a0a323dda4c596018a3294..6f5574a1c67fadd437a1e1881833653c570bf2f7 100644 (file)
@@ -1004,6 +1004,23 @@ Dhcpv6Srv::processLocalizedQuery6AndSendResponse(Pkt6Ptr query,
     }
 }
 
+void
+Dhcpv6Srv::processLocalizedQuery6AndSendResponse(Pkt6Ptr query) {
+    // Initialize context.
+    AllocEngine::ClientContext6 ctx;
+    initContext0(query, ctx);
+
+    // Subnet is cached in the callout context associated to the query.
+    try {
+        CalloutHandlePtr callout_handle = getCalloutHandle(query);
+        callout_handle->getContext("subnet6", ctx.subnet_);
+    } catch (const Exception&) {
+        // No subnet, leave it to null...
+    }
+
+    processLocalizedQuery6AndSendResponse(query, ctx);
+}
+
 Pkt6Ptr
 Dhcpv6Srv::processLocalizedQuery6(AllocEngine::ClientContext6& ctx) {
     Pkt6Ptr query = ctx.query_;
@@ -1991,8 +2008,32 @@ Dhcpv6Srv::selectSubnet(const Pkt6Ptr& question, bool& drop) {
                                     CfgMgr::instance().getCurrentCfg()->
                                     getCfgSubnets6()->getAll());
 
+        // We proactively park the packet.
+        HooksManager::park("subnet6_select", question,
+                           [this, question] () {
+                               processLocalizedQuery6AndSendResponse(question);
+                           });
+
         // Call user (and server-side) callouts
-        HooksManager::callCallouts(Hooks.hook_index_subnet6_select_, *callout_handle);
+        try {
+            HooksManager::callCallouts(Hooks.hook_index_subnet6_select_,
+                                       *callout_handle);
+        } catch (...) {
+            // Make sure we don't orphan a parked packet.
+            HooksManager::drop("subnet6_select", question);
+            throw;
+        }
+
+        // Callouts parked the packet. Same as drop but callouts will resume
+        // processing or drop the packet later.
+        if (callout_handle->getStatus() == CalloutHandle::NEXT_STEP_PARK) {
+            LOG_DEBUG(hooks_logger, DBG_DHCP6_HOOKS, DHCP6_HOOK_SUBNET6_SELECT_PARK)
+                .arg(question->getLabel());
+            drop = true;
+            return (Subnet6Ptr());
+        } else {
+            HooksManager::drop("subnet6_select", question);
+        }
 
         // Callouts decided to skip this step. This means that no
         // subnet will be selected. Packet processing will continue,
@@ -2013,15 +2054,6 @@ Dhcpv6Srv::selectSubnet(const Pkt6Ptr& question, bool& drop) {
             return (Subnet6Ptr());
         }
 
-        // Callouts parked the packet. Same as drop but callouts will resume
-        // processing or drop the packet later.
-        if (callout_handle->getStatus() == CalloutHandle::NEXT_STEP_PARK) {
-            LOG_DEBUG(hooks_logger, DBG_DHCP6_HOOKS, DHCP6_HOOK_SUBNET6_SELECT_PARK)
-                .arg(question->getLabel());
-            drop = true;
-            return (Subnet6Ptr());
-        }
-
         // Use whatever subnet was specified by the callout
         callout_handle->getArgument("subnet6", subnet);
     }
index 9579804490b4c567f2eb21e08c4f1c3bbef2ea75..1a124151af33d74d0269d081b376d2cfb5de85a1 100644 (file)
@@ -217,6 +217,14 @@ public:
     void processLocalizedQuery6AndSendResponse(Pkt6Ptr query,
                                                AllocEngine::ClientContext6& ctx);
 
+    /// @brief Process a localized incoming DHCPv6 query.
+    ///
+    /// A variant of the precedent method used to resume processing
+    /// for packets parked in the subnet6_select callout.
+    ///
+    /// @param query A pointer to the unparked packet.
+    void processLocalizedQuery6AndSendResponse(Pkt6Ptr query);
+
     /// @brief Instructs the server to shut down.
     void shutdown() override;