]> git.ipfire.org Git - thirdparty/kea.git/commitdiff
[#3140] [4133] Checkpoint: made dhcpv6 server
authorFrancis Dupont <fdupont@isc.org>
Thu, 16 Oct 2025 00:29:23 +0000 (02:29 +0200)
committerFrancis Dupont <fdupont@isc.org>
Wed, 5 Nov 2025 21:46:18 +0000 (22:46 +0100)
src/bin/dhcp6/dhcp6_srv.cc
src/bin/dhcp6/tests/classify_unittest.cc

index 4aaf71120cb7e788fe6c83898694d903dd0699a7..691f05a8e7953e1f5339d621b50c6695660118e8 100644 (file)
@@ -311,7 +311,7 @@ Dhcpv6Srv::Dhcpv6Srv(uint16_t server_port, uint16_t client_port)
 }
 
 void Dhcpv6Srv::setPacketStatisticsDefaults() {
-    isc::stats::StatsMgr& stats_mgr = isc::stats::StatsMgr::instance();
+    StatsMgr& stats_mgr = StatsMgr::instance();
 
     // Iterate over set of observed statistics
     for (auto const& it : dhcp6_statistics) {
@@ -790,7 +790,7 @@ Dhcpv6Srv::runOne() {
                 LOG_DEBUG(dhcp6_logger, DBG_DHCP6_BASIC, DHCP6_PACKET_QUEUE_FULL);
             }
         } else {
-            processPacketAndSendResponse(query);
+            processPacketAndSendResponseNoThrow(query);
         }
     }
 }
@@ -811,7 +811,16 @@ Dhcpv6Srv::processPacketAndSendResponseNoThrow(Pkt6Ptr query) {
 
 void
 Dhcpv6Srv::processPacketAndSendResponse(Pkt6Ptr query) {
-    Pkt6Ptr rsp = processPacket(query);
+    Pkt6Ptr rsp;
+    try {
+        rsp = processPacket(query);
+    } catch (...) {
+        StatsMgr::instance().addValue("pkt6-processing-failed",
+                                      static_cast<int64_t>(1));
+        StatsMgr::instance().addValue("pkt6-receive-drop",
+                                      static_cast<int64_t>(1));
+        throw;
+    }
     if (!rsp) {
         return;
     }
@@ -1020,9 +1029,18 @@ Dhcpv6Srv::processPacket(Pkt6Ptr query) {
 void
 Dhcpv6Srv::processDhcp6QueryAndSendResponse(Pkt6Ptr query) {
     try {
-        Pkt6Ptr rsp = processDhcp6Query(query);
-        if (!rsp) {
-            return;
+        Pkt6Ptr rsp;
+        try {
+            rsp = processDhcp6Query(query);
+            if (!rsp) {
+                return;
+            }
+        } catch (...) {
+            StatsMgr::instance().addValue("pkt6-processing-failed",
+                                          static_cast<int64_t>(1));
+            StatsMgr::instance().addValue("pkt6-receive-drop",
+                                          static_cast<int64_t>(1));
+            throw;
         }
 
         CalloutHandlePtr callout_handle = getCalloutHandle(query);
@@ -1083,14 +1101,22 @@ Dhcpv6Srv::processDhcp6Query(Pkt6Ptr query) {
     return (processLocalizedQuery6(ctx));
 }
 
-
 void
 Dhcpv6Srv::processLocalizedQuery6AndSendResponse(Pkt6Ptr query,
                                                  AllocEngine::ClientContext6& ctx) {
     try {
-        Pkt6Ptr rsp = processLocalizedQuery6(ctx);
-        if (!rsp) {
-            return;
+        Pkt6Ptr rsp;
+        try {
+            rsp = processLocalizedQuery6(ctx);
+            if (!rsp) {
+                return;
+            }
+        } catch (...) {
+            StatsMgr::instance().addValue("pkt6-processing-failed",
+                                          static_cast<int64_t>(1));
+            StatsMgr::instance().addValue("pkt6-receive-drop",
+                                          static_cast<int64_t>(1));
+            throw;
         }
 
         CalloutHandlePtr callout_handle = getCalloutHandle(query);
@@ -1133,48 +1159,53 @@ Dhcpv6Srv::processLocalizedQuery6(AllocEngine::ClientContext6& ctx) {
     }
 
     Pkt6Ptr rsp;
+    bool rfc_violation = false;
     try {
-        switch (query->getType()) {
-        case DHCPV6_SOLICIT:
-            rsp = processSolicit(ctx);
-            break;
+        try {
+            switch (query->getType()) {
+            case DHCPV6_SOLICIT:
+                rsp = processSolicit(ctx);
+                break;
 
-        case DHCPV6_REQUEST:
-            rsp = processRequest(ctx);
-            break;
+            case DHCPV6_REQUEST:
+                rsp = processRequest(ctx);
+                break;
 
-        case DHCPV6_RENEW:
-            rsp = processRenew(ctx);
-            break;
+            case DHCPV6_RENEW:
+                rsp = processRenew(ctx);
+                break;
 
-        case DHCPV6_REBIND:
-            rsp = processRebind(ctx);
-            break;
+            case DHCPV6_REBIND:
+                rsp = processRebind(ctx);
+                break;
 
-        case DHCPV6_CONFIRM:
-            rsp = processConfirm(ctx);
-            break;
+            case DHCPV6_CONFIRM:
+                rsp = processConfirm(ctx);
+                break;
 
-        case DHCPV6_RELEASE:
-            rsp = processRelease(ctx);
-            break;
+            case DHCPV6_RELEASE:
+                rsp = processRelease(ctx);
+                break;
 
-        case DHCPV6_DECLINE:
-            rsp = processDecline(ctx);
-            break;
+            case DHCPV6_DECLINE:
+                rsp = processDecline(ctx);
+                break;
 
-        case DHCPV6_INFORMATION_REQUEST:
-            rsp = processInfRequest(ctx);
-            break;
+            case DHCPV6_INFORMATION_REQUEST:
+                rsp = processInfRequest(ctx);
+                break;
 
-        case DHCPV6_ADDR_REG_INFORM:
-            rsp = processAddrRegInform(ctx);
-            break;
+            case DHCPV6_ADDR_REG_INFORM:
+                rsp = processAddrRegInform(ctx);
+                break;
 
-        default:
-            return (rsp);
+            default:
+                return (rsp);
+            }
+        } catch (const RFCViolation&) {
+            rfc_violation = true;
+            throw;
         }
-
     } catch (const std::exception& e) {
 
         // Catch-all exception (at least for ones based on the isc Exception
@@ -1191,7 +1222,12 @@ Dhcpv6Srv::processLocalizedQuery6(AllocEngine::ClientContext6& ctx) {
             .arg(e.what());
 
         // Increase the statistic of dropped packets.
-        StatsMgr::instance().addValue("pkt6-receive-drop", static_cast<int64_t>(1));
+        if (!rfc_violation) {
+            StatsMgr::instance().addValue("pkt6-processing-failed",
+                                          static_cast<int64_t>(1));
+        }
+        StatsMgr::instance().addValue("pkt6-receive-drop",
+                                      static_cast<int64_t>(1));
     }
 
     if (!rsp) {
@@ -1327,10 +1363,10 @@ Dhcpv6Srv::processLocalizedQuery6(AllocEngine::ClientContext6& ctx) {
                           DHCP6_HOOK_LEASES6_PARKING_LOT_FULL)
                           .arg(parked_packet_limit)
                           .arg(query->getLabel());
-                isc::stats::StatsMgr::instance().addValue("pkt6-queue-full",
-                                                          static_cast<int64_t>(1));
-                isc::stats::StatsMgr::instance().addValue("pkt6-receive-drop",
-                                                          static_cast<int64_t>(1));
+                StatsMgr::instance().addValue("pkt6-queue-full",
+                                              static_cast<int64_t>(1));
+                StatsMgr::instance().addValue("pkt6-receive-drop",
+                                              static_cast<int64_t>(1));
                 rsp.reset();
                 return (rsp);
             }
@@ -2442,7 +2478,7 @@ Dhcpv6Srv::createNameChangeRequests(const Pkt6Ptr& answer,
     // holds the Client Identifier. It is a programming error if supplied
     // message is NULL.
     if (!answer) {
-        isc_throw(isc::Unexpected, "an instance of the object"
+        isc_throw(Unexpected, "an instance of the object"
                   << " encapsulating server's message must not be"
                   << " NULL when creating DNS NameChangeRequest");
     }
@@ -2467,7 +2503,7 @@ Dhcpv6Srv::createNameChangeRequests(const Pkt6Ptr& answer,
     // Unexpected if it is missing as it is a programming error.
     OptionPtr opt_duid = answer->getOption(D6O_CLIENTID);
     if (!opt_duid) {
-        isc_throw(isc::Unexpected,
+        isc_throw(Unexpected,
                   "client identifier is required when creating a new"
                   " DNS NameChangeRequest");
     }
index 5f329cf79fbbc0bd9b00b9614d1b3df276e6445e..ac07f4065c80ef6d6360c4d89fa8c2782db5174f 100644 (file)
@@ -3367,7 +3367,7 @@ TEST_F(ClassifyTest, classTaggingAndNeverSend) {
 TEST_F(ClassifyTest, classTaggingList) {
     IfaceMgrTestConfig test_config(true);
     // Define a client-str option for classification, and server-str
-    // option to send in response.  Then define 3 possible values in 
+    // option to send in response.  Then define 3 possible values in
     // a subnet for sever-str based on class membership.
     string config = R"^(
     {
@@ -3427,8 +3427,8 @@ TEST_F(ClassifyTest, classTaggingList) {
     };
 
     std::list<Scenario> scenarios {
-        { __LINE__, "one",     "class-one",     "string.one" }, 
-        { __LINE__, "two",     "class-two",     "string.two" }, 
+        { __LINE__, "one",     "class-one",     "string.one" },
+        { __LINE__, "two",     "class-two",     "string.two" },
         { __LINE__, "neither", "class-neither", "string.other" }
     };