Parcourir la source

[2862] Some error handling in the segment update

Michal 'vorner' Vaner il y a 11 ans
Parent
commit
7276a2eddf

+ 16 - 0
src/bin/auth/auth_messages.mes

@@ -145,6 +145,22 @@ reconfigure, and has now started this process.
 The thread for maintaining data source clients has finished reconfiguring
 the data source clients, and is now running with the new configuration.
 
+% AUTH_DATASRC_CLIENTS_BUILDER_SEGMENT_BAD_CLASS invalid RRclass %1 at segment update
+A memory segment update message was sent to the authoritative server. But the
+class contained there is no valid class, so the update is dropped. This is
+likely a bug in the code.
+
+% AUTH_DATASRC_CLIENTS_BUILDER_SEGMENT_ERROR error updating the memory segment: %1
+The authoritative server tried to update the memory segment. But the update
+failed. The update is dropped. This is likely a bug in the code.
+
+% AUTH_DATASRC_CLIENTS_BUILDER_SEGMENT_UNKNOWN_CLASS unknown class %1 at segment update
+A memory segment update message was sent to the authoritative server. The class
+name for which the update should happen is valid, but no client lists are
+configured for that class. The update is dropped. This may be caused by a bug
+in the code or by a temporary inconsistancy between the memory manager and the
+authoritative server after change of configuration.
+
 % AUTH_DATASRC_CLIENTS_BUILDER_STARTED data source builder thread started
 A separate thread for maintaining data source clients has been started.
 

+ 27 - 14
src/bin/auth/datasrc_clients_mgr.h

@@ -627,21 +627,34 @@ private:
     }
 
     void doSegmentUpdate(const isc::data::ConstElementPtr& arg) {
-        // TODO: Error handling. Invalid RRClass, non-existing stuff, exceptions
-        const isc::dns::RRClass
-            rrclass(arg->get("data-source-class")->stringValue());
-        const std::string& name(arg->get("data-source-name")->stringValue());
-        const isc::data::ConstElementPtr& segment_params =
-            arg->get("segment-params");
-        typename MutexType::Locker locker(*map_mutex_);
-        const boost::shared_ptr<isc::datasrc::ConfigurableClientList>& list =
-            (**clients_map_)[rrclass];
-        if (!list) {
-            // TODO: Log error
-            return;
+        try {
+            const isc::dns::RRClass
+                rrclass(arg->get("data-source-class")->stringValue());
+            const std::string&
+                name(arg->get("data-source-name")->stringValue());
+            const isc::data::ConstElementPtr& segment_params =
+                arg->get("segment-params");
+            typename MutexType::Locker locker(*map_mutex_);
+            const boost::shared_ptr<isc::datasrc::ConfigurableClientList>&
+                list = (**clients_map_)[rrclass];
+            if (!list) {
+                LOG_ERROR(auth_logger,
+                          AUTH_DATASRC_CLIENTS_BUILDER_SEGMENT_UNKNOWN_CLASS)
+                    .arg(rrclass);
+                return;
+            }
+            list->resetMemorySegment(name,
+                isc::datasrc::memory::ZoneTableSegment::READ_ONLY,
+                segment_params);
+        } catch (const isc::dns::InvalidRRClass& irce) {
+            LOG_ERROR(auth_logger,
+                      AUTH_DATASRC_CLIENTS_BUILDER_SEGMENT_BAD_CLASS)
+                .arg(arg->get("data-source-class"));
+        } catch (const isc::Exception& e) {
+            LOG_ERROR(auth_logger,
+                      AUTH_DATASRC_CLIENTS_BUILDER_SEGMENT_ERROR)
+                .arg(e.what());
         }
-        list->resetMemorySegment(name,
-            isc::datasrc::memory::ZoneTableSegment::READ_ONLY, segment_params);
     }
 
     void doLoadZone(const isc::data::ConstElementPtr& arg);

+ 29 - 0
src/bin/auth/tests/datasrc_clients_builder_unittest.cc

@@ -703,6 +703,35 @@ TEST_F(DataSrcClientsBuilderTest,
                                   FinishedCallback()));
     // The segment is now used.
     EXPECT_EQ(SEGMENT_INUSE, list->getStatus()[0].getSegmentState());
+
+    // Some invalid inputs (wrong class, different name of data source, etc).
+
+    // Copy the confing and modify
+    const ElementPtr bad_name = Element::fromJSON(command_args->toWire());
+    // Set bad name
+    bad_name->set("data-source-name", Element::create("bad"));
+    // Nothing breaks
+    builder.handleCommand(Command(SEGMENT_INFO_UPDATE, bad_name,
+                                  FinishedCallback()));
+
+    // Another copy with wrong class
+    const ElementPtr bad_class = Element::fromJSON(command_args->toWire());
+    // Set bad class
+    bad_class->set("data-source-class", Element::create("bad"));
+    // Nothing breaks
+    builder.handleCommand(Command(SEGMENT_INFO_UPDATE, bad_class,
+                                  FinishedCallback()));
+
+    // Class CH is valid, but not present.
+    bad_class->set("data-source-class", Element::create("CH"));
+    // Nothing breaks
+    builder.handleCommand(Command(SEGMENT_INFO_UPDATE, bad_class,
+                                  FinishedCallback()));
+
+    // And break the segment params
+    const ElementPtr bad_params = Element::fromJSON(command_args->toWire());
+    bad_params->set("segment-params",
+                    Element::fromJSON("{\"mapped-file\": \"/bad/file\"}"));
 }
 
 } // unnamed namespace