]> git.ipfire.org Git - thirdparty/kea.git/commitdiff
[#3276] Check invalid server name during sync
authorMarcin Siodelski <marcin@isc.org>
Tue, 16 Apr 2024 09:31:02 +0000 (11:31 +0200)
committerMarcin Siodelski <marcin@isc.org>
Tue, 16 Apr 2024 13:42:32 +0000 (15:42 +0200)
src/hooks/dhcp/high_availability/ha_service.cc
src/hooks/dhcp/high_availability/ha_service.h
src/hooks/dhcp/high_availability/tests/ha_mt_unittest.cc
src/hooks/dhcp/high_availability/tests/ha_service_unittest.cc

index f5b04cf34d751d8dc7c4dd72162f4b93a2ef3f99..5a11eab71e2382fa8ee379bdd5b00d4311dfb321 100644 (file)
@@ -771,7 +771,7 @@ HAService::syncingStateHandler() {
         // Perform synchronous leases update.
         std::string status_message;
         int sync_status = synchronize(status_message,
-                                      config_->getFailoverPeerConfig()->getName(),
+                                      config_->getFailoverPeerConfig(),
                                       dhcp_disable_timeout);
 
         // If the leases synchronization was successful, let's transition
@@ -1908,11 +1908,9 @@ HAService::startHeartbeat() {
 
 void
 HAService::asyncDisableDHCPService(HttpClient& http_client,
-                                   const std::string& server_name,
+                                   const HAConfig::PeerConfigPtr& remote_config,
                                    const unsigned int max_period,
                                    PostRequestCallback post_request_action) {
-    HAConfig::PeerConfigPtr remote_config = config_->getPeerConfig(server_name);
-
     // Create HTTP/1.1 request including our command.
     PostHttpRequestJsonPtr request = boost::make_shared<PostHttpRequestJson>
         (HttpRequest::Method::HTTP_POST, "/", HttpVersion::HTTP_11(),
@@ -1991,10 +1989,8 @@ HAService::asyncDisableDHCPService(HttpClient& http_client,
 
 void
 HAService::asyncEnableDHCPService(HttpClient& http_client,
-                                  const std::string& server_name,
+                                  const HAConfig::PeerConfigPtr& remote_config,
                                   PostRequestCallback post_request_action) {
-    HAConfig::PeerConfigPtr remote_config = config_->getPeerConfig(server_name);
-
     // Create HTTP/1.1 request including our command.
     PostHttpRequestJsonPtr request = boost::make_shared<PostHttpRequestJson>
         (HttpRequest::Method::HTTP_POST, "/", HttpVersion::HTTP_11(),
@@ -2092,13 +2088,13 @@ HAService::asyncSyncLeases() {
     }
 
     lease_sync_filter_.apply();
-    asyncSyncLeases(*client_, config_->getFailoverPeerConfig()->getName(),
+    asyncSyncLeases(*client_, config_->getFailoverPeerConfig(),
                     dhcp_disable_timeout, LeasePtr(), null_action);
 }
 
 void
 HAService::asyncSyncLeases(http::HttpClient& http_client,
-                           const std::string& server_name,
+                           const HAConfig::PeerConfigPtr& remote_config,
                            const unsigned int max_period,
                            const dhcp::LeasePtr& last_lease,
                            PostSyncCallback post_sync_action,
@@ -2108,8 +2104,8 @@ HAService::asyncSyncLeases(http::HttpClient& http_client,
     // to allocate new leases while we fetch from it. The DHCP service will
     // be disabled for a certain amount of time and will be automatically
     // re-enabled if we die during the synchronization.
-    asyncDisableDHCPService(http_client, server_name, max_period,
-                            [this, &http_client, server_name, max_period, last_lease,
+    asyncDisableDHCPService(http_client, remote_config, max_period,
+                            [this, &http_client, remote_config, max_period, last_lease,
                              post_sync_action, dhcp_disabled]
                             (const bool success, const std::string& error_message, const int) {
 
@@ -2118,7 +2114,7 @@ HAService::asyncSyncLeases(http::HttpClient& http_client,
         if (success) {
             // The last argument indicates that disabling the DHCP
             // service on the partner server was successful.
-            asyncSyncLeasesInternal(http_client, server_name, max_period,
+            asyncSyncLeasesInternal(http_client, remote_config, max_period,
                                     last_lease, post_sync_action, true);
 
         } else {
@@ -2129,19 +2125,16 @@ HAService::asyncSyncLeases(http::HttpClient& http_client,
 
 void
 HAService::asyncSyncLeasesInternal(http::HttpClient& http_client,
-                                   const std::string& server_name,
+                                   const HAConfig::PeerConfigPtr& remote_config,
                                    const unsigned int max_period,
                                    const dhcp::LeasePtr& last_lease,
                                    PostSyncCallback post_sync_action,
                                    const bool dhcp_disabled) {
-
-    HAConfig::PeerConfigPtr partner_config = config_->getPeerConfig(server_name);
-
     // Create HTTP/1.1 request including our command.
     PostHttpRequestJsonPtr request = boost::make_shared<PostHttpRequestJson>
         (HttpRequest::Method::HTTP_POST, "/", HttpVersion::HTTP_11(),
-         HostHttpHeader(partner_config->getUrl().getStrippedHostname()));
-    partner_config->addBasicAuthHttpHeader(request);
+         HostHttpHeader(remote_config->getUrl().getStrippedHostname()));
+    remote_config->addBasicAuthHttpHeader(request);
     if (server_type_ == HAServerType::DHCPv4) {
         request->setBodyAsJson(CommandCreator::createLease4GetPage(
             boost::dynamic_pointer_cast<Lease4>(last_lease), config_->getSyncPageLimit()));
@@ -2157,11 +2150,10 @@ HAService::asyncSyncLeasesInternal(http::HttpClient& http_client,
     HttpResponseJsonPtr response = boost::make_shared<HttpResponseJson>();
 
     // Schedule asynchronous HTTP request.
-    http_client.asyncSendRequest(partner_config->getUrl(),
-                                 partner_config->getTlsContext(),
+    http_client.asyncSendRequest(remote_config->getUrl(),
+                                 remote_config->getTlsContext(),
                                  request, response,
-        [this, partner_config, post_sync_action, &http_client, server_name,
-         max_period, dhcp_disabled]
+        [this, remote_config, post_sync_action, &http_client, max_period, dhcp_disabled]
             (const boost::system::error_code& ec,
              const HttpResponsePtr& response,
              const std::string& error_str) {
@@ -2183,7 +2175,7 @@ HAService::asyncSyncLeasesInternal(http::HttpClient& http_client,
                 error_message = (ec ? ec.message() : error_str);
                 LOG_ERROR(ha_logger, HA_LEASES_SYNC_COMMUNICATIONS_FAILED)
                     .arg(config_->getThisServerName())
-                    .arg(partner_config->getLogLabel())
+                    .arg(remote_config->getLogLabel())
                     .arg(error_message);
 
             } else {
@@ -2211,7 +2203,7 @@ HAService::asyncSyncLeasesInternal(http::HttpClient& http_client,
                     LOG_INFO(ha_logger, HA_LEASES_SYNC_LEASE_PAGE_RECEIVED)
                         .arg(config_->getThisServerName())
                         .arg(leases_element.size())
-                        .arg(server_name);
+                        .arg(remote_config->getLogLabel());
 
                     // Count actually applied leases.
                     uint64_t applied_lease_count = 0;
@@ -2314,7 +2306,7 @@ HAService::asyncSyncLeasesInternal(http::HttpClient& http_client,
                     error_message = ex.what();
                     LOG_ERROR(ha_logger, HA_LEASES_SYNC_FAILED)
                         .arg(config_->getThisServerName())
-                        .arg(partner_config->getLogLabel())
+                        .arg(remote_config->getLogLabel())
                         .arg(error_message);
                 }
             }
@@ -2327,7 +2319,7 @@ HAService::asyncSyncLeasesInternal(http::HttpClient& http_client,
              } else if (last_lease) {
                  // This indicates that there are more leases to be fetched.
                  // Therefore, we have to send another leaseX-get-page command.
-                 asyncSyncLeases(http_client, server_name, max_period, last_lease,
+                 asyncSyncLeases(http_client, remote_config, max_period, last_lease,
                                  post_sync_action, dhcp_disabled);
                  return;
              }
@@ -2350,20 +2342,32 @@ HAService::asyncSyncLeasesInternal(http::HttpClient& http_client,
 ConstElementPtr
 HAService::processSynchronize(const std::string& server_name,
                               const unsigned int max_period) {
+    HAConfig::PeerConfigPtr remote_config;
+    try {
+        remote_config = config_->getPeerConfig(server_name);
+    } catch (const std::exception& ex) {
+        return (createAnswer(CONTROL_RESULT_ERROR, ex.what()));
+    }
+    // We must not synchronize with self.
+    if (remote_config->getName() == config_->getThisServerName()) {
+        return (createAnswer(CONTROL_RESULT_ERROR, "'" + remote_config->getName()
+            + "' points to local server but should point to a partner"));
+    }
     std::string answer_message;
-    int sync_status = synchronize(answer_message, server_name, max_period);
+    int sync_status = synchronize(answer_message, remote_config, max_period);
     return (createAnswer(sync_status, answer_message));
 }
 
 int
-HAService::synchronize(std::string& status_message, const std::string& server_name,
+HAService::synchronize(std::string& status_message,
+                       const HAConfig::PeerConfigPtr& remote_config,
                        const unsigned int max_period) {
     lease_sync_filter_.apply();
 
     IOServicePtr io_service(new IOService());
     HttpClient client(io_service, false);
 
-    asyncSyncLeases(client, server_name, max_period, Lease4Ptr(),
+    asyncSyncLeases(client, remote_config, max_period, Lease4Ptr(),
                     [&](const bool success, const std::string& error_message,
                         const bool dhcp_disabled) {
         // If there was a fatal error while fetching the leases, let's
@@ -2381,7 +2385,7 @@ HAService::synchronize(std::string& status_message, const std::string& server_na
             // try to send the ha-sync-complete-notify command to the
             // partner.
             if (success) {
-                asyncSyncCompleteNotify(client, server_name,
+                asyncSyncCompleteNotify(client, remote_config,
                                         [&](const bool success,
                                             const std::string& error_message,
                                             const int rcode) {
@@ -2389,7 +2393,7 @@ HAService::synchronize(std::string& status_message, const std::string& server_na
                     // runs an older Kea version. In that case, send the dhcp-enable
                     // command as in previous Kea version.
                     if (rcode == CONTROL_RESULT_COMMAND_UNSUPPORTED) {
-                        asyncEnableDHCPService(client, server_name,
+                        asyncEnableDHCPService(client, remote_config,
                                                [&](const bool success,
                                                    const std::string& error_message,
                                                    const int) {
@@ -2422,7 +2426,7 @@ HAService::synchronize(std::string& status_message, const std::string& server_na
                 //  re-enable the DHCP service. Note, that we don't send the
                 // ha-sync-complete-notify command in this case. It is only sent in
                 // the case when synchronization ends successfully.
-                asyncEnableDHCPService(client, server_name,
+                asyncEnableDHCPService(client, remote_config,
                                        [&](const bool success,
                                            const std::string& error_message,
                                            const int) {
@@ -2447,7 +2451,7 @@ HAService::synchronize(std::string& status_message, const std::string& server_na
 
     LOG_INFO(ha_logger, HA_SYNC_START)
         .arg(config_->getThisServerName())
-        .arg(server_name);
+        .arg(remote_config->getLogLabel());
 
     // Measure duration of the synchronization.
     Stopwatch stopwatch;
@@ -2475,7 +2479,7 @@ HAService::synchronize(std::string& status_message, const std::string& server_na
 
         LOG_ERROR(ha_logger, HA_SYNC_FAILED)
             .arg(config_->getThisServerName())
-            .arg(server_name)
+            .arg(remote_config->getLogLabel())
             .arg(status_message);
 
         return (CONTROL_RESULT_ERROR);
@@ -2488,7 +2492,7 @@ HAService::synchronize(std::string& status_message, const std::string& server_na
 
     LOG_INFO(ha_logger, HA_SYNC_SUCCESSFUL)
         .arg(config_->getThisServerName())
-        .arg(server_name)
+        .arg(remote_config->getLogLabel())
         .arg(stopwatch.logFormatLastDuration());
 
     return (CONTROL_RESULT_SUCCESS);
@@ -3015,10 +3019,8 @@ HAService::processMaintenanceCancel() {
 
 void
 HAService::asyncSyncCompleteNotify(HttpClient& http_client,
-                                   const std::string& server_name,
+                                   const HAConfig::PeerConfigPtr& remote_config,
                                    PostRequestCallback post_request_action) {
-    HAConfig::PeerConfigPtr remote_config = config_->getPeerConfig(server_name);
-
     // Create HTTP/1.1 request including our command.
     PostHttpRequestJsonPtr request = boost::make_shared<PostHttpRequestJson>
         (HttpRequest::Method::HTTP_POST, "/", HttpVersion::HTTP_11(),
index 8d677bdc635f8c50d15a72953824293aba1a68db..a6de2a622739c2b153360935112fbe987ddd6039 100644 (file)
@@ -768,14 +768,14 @@ protected:
     ///
     /// @param http_client reference to the client to be used to communicate
     /// with the other server.
-    /// @param server_name name of the server to which the command should be
-    /// sent.
+    /// @param remote_config config of the partner to which the command should
+    /// be sent.
     /// @param max_period maximum number of seconds for which the DHCP service
     /// should be disabled.
     /// @param post_request_action pointer to the function to be executed when
     /// the request is completed.
     void asyncDisableDHCPService(http::HttpClient& http_client,
-                                 const std::string& server_name,
+                                 const HAConfig::PeerConfigPtr& remote_config,
                                  const unsigned int max_period,
                                  PostRequestCallback post_request_action);
 
@@ -784,12 +784,12 @@ protected:
     ///
     /// @param http_client reference to the client to be used to communicate
     /// with the other server.
-    /// @param server_name name of the server to which the command should be
-    /// sent.
+    /// @param remote_config config of the partner to which the command should
+    /// be sent.
     /// @param post_request_action pointer to the function to be executed when
     /// the request is completed.
     void asyncEnableDHCPService(http::HttpClient& http_client,
-                                const std::string& server_name,
+                                const HAConfig::PeerConfigPtr& remote_config,
                                 PostRequestCallback post_request_action);
 
     /// @brief Disables local DHCP service.
@@ -851,7 +851,7 @@ protected:
     ///
     /// @param http_client reference to the client to be used to communicate
     /// with the other server.
-    /// @param server_name name of the server to fetch leases from.
+    /// @param remote_config config of the partner to fetch leases from.
     /// @param max_period maximum number of seconds to disable DHCP service
     /// @param last_lease Pointer to the last lease returned on the previous
     /// page of leases. This lease is used to set the value of the "from"
@@ -866,7 +866,7 @@ protected:
     /// @c post_sync_action to indicate whether the DHCP service has to
     /// be enabled after the leases synchronization.
     void asyncSyncLeases(http::HttpClient& http_client,
-                         const std::string& server_name,
+                         const HAConfig::PeerConfigPtr& remote_config,
                          const unsigned int max_period,
                          const dhcp::LeasePtr& last_lease,
                          PostSyncCallback post_sync_action,
@@ -884,7 +884,7 @@ protected:
     ///
     /// @param http_client reference to the client to be used to communicate
     /// with the other server.
-    /// @param server_name name of the server to fetch leases from.
+    /// @param remote_config config of the partner to fetch leases from.
     /// @param max_period maximum number of seconds to disable DHCP service
     /// @param last_lease Pointer to the last lease returned on the previous
     /// page of leases. This lease is used to set the value of the "from"
@@ -899,7 +899,7 @@ protected:
     /// @c post_sync_action to indicate whether the DHCP service has to
     /// be enabled after the leases synchronization.
     void asyncSyncLeasesInternal(http::HttpClient& http_client,
-                                 const std::string& server_name,
+                                 const HAConfig::PeerConfigPtr& remote_config,
                                  const unsigned int max_period,
                                  const dhcp::LeasePtr& last_lease,
                                  PostSyncCallback post_sync_action,
@@ -944,14 +944,15 @@ protected:
     /// invokes IOService::run().
     ///
     /// @param [out] status_message status message in textual form.
-    /// @param server_name name of the server to fetch leases from.
+    /// @param remote_config config of the server to fetch leases from.
     /// @param max_period maximum number of seconds to disable DHCP service
     /// of the peer. This value is used in dhcp-disable command issued to
     /// the peer before the lease4-get-page command.
     ///
     /// @return Synchronization result according to the status codes returned
     /// in responses to control commands.
-    int synchronize(std::string& status_message, const std::string& server_name,
+    int synchronize(std::string& status_message,
+                    const HAConfig::PeerConfigPtr& remote_config,
                     const unsigned int max_period);
 
     /// @brief Sends lease updates from backlog to partner asynchronously.
@@ -1100,12 +1101,12 @@ protected:
     ///
     /// @param http_client reference to the client to be used to communicate
     /// with the other server.
-    /// @param server_name name of the server to which the command should be
-    /// sent.
+    /// @param remote_config config of the partner to which the command should
+    /// be sent.
     /// @param post_request_action pointer to the function to be executed when
     /// the request is completed.
     void asyncSyncCompleteNotify(http::HttpClient& http_client,
-                                 const std::string& server_name,
+                                 const HAConfig::PeerConfigPtr& remote_config,
                                  PostRequestCallback post_request_action);
 
 public:
index 89564f370f2b627f6d4c6ea3a9fba96bc94b43eb..027900fd27ba0b868c4e53dad5587b2a6b2ff5c4 100644 (file)
@@ -71,16 +71,16 @@ public:
     ///
     /// This variant of the method uses default HTTP client for communication.
     ///
-    /// @param server_name name of the server to which the command should be
+    /// @param remote_config config of the server to which the command should be
     /// sent.
     /// @param max_period maximum number of seconds for which the DHCP service
     /// should be disabled.
     /// @param post_request_action pointer to the function to be executed when
     /// the request is completed.
-    void asyncDisableDHCPService(const std::string& server_name,
+    void asyncDisableDHCPService(const HAConfig::PeerConfigPtr& remote_config,
                                  const unsigned int max_period,
                                  const PostRequestCallback& post_request_action) {
-        HAService::asyncDisableDHCPService(*client_, server_name, max_period,
+        HAService::asyncDisableDHCPService(*client_, remote_config, max_period,
                                            post_request_action);
     }
 
@@ -89,13 +89,13 @@ public:
     ///
     /// This variant of the method uses default HTTP client for communication.
     ///
-    /// @param server_name name of the server to which the command should be
+    /// @param remote_config config of the server to which the command should be
     /// sent.
     /// @param post_request_action pointer to the function to be executed when
     /// the request is completed.
-    void asyncEnableDHCPService(const std::string& server_name,
+    void asyncEnableDHCPService(const HAConfig::PeerConfigPtr& remote_config,
                                 const PostRequestCallback& post_request_action) {
-        HAService::asyncEnableDHCPService(*client_, server_name, post_request_action);
+        HAService::asyncEnableDHCPService(*client_, remote_config, post_request_action);
     }
 
     using HAService::asyncSendHeartbeat;
index d968ea0508d4d7262a73827aa76c1560a3f26401..ac5f2a5715fb8a43e370b7ae2241955c05d0492c 100644 (file)
@@ -170,16 +170,16 @@ public:
     ///
     /// This variant of the method uses default HTTP client for communication.
     ///
-    /// @param server_name name of the server to which the command should be
+    /// @param remote_config config of the server to which the command should be
     /// sent.
     /// @param max_period maximum number of seconds for which the DHCP service
     /// should be disabled.
     /// @param post_request_action pointer to the function to be executed when
     /// the request is completed.
-    void asyncDisableDHCPService(const std::string& server_name,
+    void asyncDisableDHCPService(const HAConfig::PeerConfigPtr& remote_config,
                                  const unsigned int max_period,
                                  const PostRequestCallback& post_request_action) {
-        HAService::asyncDisableDHCPService(*client_, server_name, max_period,
+        HAService::asyncDisableDHCPService(*client_, remote_config, max_period,
                                            post_request_action);
     }
 
@@ -188,13 +188,13 @@ public:
     ///
     /// This variant of the method uses default HTTP client for communication.
     ///
-    /// @param server_name name of the server to which the command should be
+    /// @param remote_config config of the server to which the command should be
     /// sent.
     /// @param post_request_action pointer to the function to be executed when
     /// the request is completed.
-    void asyncEnableDHCPService(const std::string& server_name,
+    void asyncEnableDHCPService(const HAConfig::PeerConfigPtr& remote_config,
                                 const PostRequestCallback& post_request_action) {
-        HAService::asyncEnableDHCPService(*client_, server_name, post_request_action);
+        HAService::asyncEnableDHCPService(*client_, remote_config, post_request_action);
     }
 
     using HAService::asyncSendHeartbeat;
@@ -2057,8 +2057,9 @@ public:
     /// leases in the lease database.
     ///
     /// @param config_storage test HA configuration.
+    /// @param server_name name of the partner server.
     /// @param [out] rsp pointer to the object where response will be stored.
-    void runProcessSynchronize4(HAConfigPtr config_storage, ConstElementPtr& rsp) {
+    void runProcessSynchronize4(HAConfigPtr config_storage, std::string server_name, ConstElementPtr& rsp) {
         // Create lease manager.
         ASSERT_NO_THROW(LeaseMgrFactory::create("universe=4 type=memfile persist=false"));
 
@@ -2084,7 +2085,7 @@ public:
         auto thread = runIOServiceInThread();
 
         // Process ha-sync command.
-        ASSERT_NO_THROW(rsp = service.processSynchronize("server2", 20));
+        ASSERT_NO_THROW(rsp = service.processSynchronize(server_name, 20));
 
         // Stop the IO service. This should cause the thread to terminate.
         io_service_->stop();
@@ -2105,8 +2106,9 @@ public:
     /// leases in the lease database.
     ///
     /// @param config_storage test HA configuration.
+    /// @param server_name name of the partner server.
     /// @param [out] rsp pointer to the object where response will be stored.
-    void runProcessSynchronize6(HAConfigPtr config_storage, ConstElementPtr& rsp) {
+    void runProcessSynchronize6(HAConfigPtr config_storage, std::string server_name, ConstElementPtr& rsp) {
         // Create lease manager.
         ASSERT_NO_THROW(LeaseMgrFactory::create("universe=6 type=memfile persist=false"));
 
@@ -2133,7 +2135,7 @@ public:
         auto thread = runIOServiceInThread();
 
         // Process ha-sync command.
-        ASSERT_NO_THROW(rsp = service.processSynchronize("server2", 20));
+        ASSERT_NO_THROW(rsp = service.processSynchronize(server_name, 20));
 
         // Stop the IO service. This should cause the thread to terminate.
         io_service_->stop();
@@ -3961,7 +3963,7 @@ TEST_F(HAServiceTest, processSynchronize4) {
 
     // Run HAService::processSynchronize and gather a response.
     ConstElementPtr rsp;
-    runProcessSynchronize4(config_storage, rsp);
+    runProcessSynchronize4(config_storage, "server2", rsp);
 
     // The response should indicate success.
     ASSERT_TRUE(rsp);
@@ -3994,7 +3996,7 @@ TEST_F(HAServiceTest, processSynchronize4PassiveBackup) {
 
     // Run HAService::processSynchronize and gather a response.
     ConstElementPtr rsp;
-    runProcessSynchronize4(config_storage, rsp);
+    runProcessSynchronize4(config_storage, "server2", rsp);
 
     // The response should indicate success.
     ASSERT_TRUE(rsp);
@@ -4036,7 +4038,7 @@ TEST_F(HAServiceTest, processSynchronize4Authorized) {
 
     // Run HAService::processSynchronize and gather a response.
     ConstElementPtr rsp;
-    runProcessSynchronize4(config_storage, rsp);
+    runProcessSynchronize4(config_storage, "server2", rsp);
 
     // The response should indicate success.
     ASSERT_TRUE(rsp);
@@ -4072,7 +4074,7 @@ TEST_F(HAServiceTest, processSynchronizeDisableError) {
 
     // Run HAService::processSynchronize and gather a response.
     ConstElementPtr rsp;
-    runProcessSynchronize4(config_storage, rsp);
+    runProcessSynchronize4(config_storage, "server2", rsp);
 
     // The response should indicate an error
     ASSERT_TRUE(rsp);
@@ -4099,7 +4101,7 @@ TEST_F(HAServiceTest, processSynchronizeUnauthorized) {
 
     // Run HAService::processSynchronize and gather a response.
     ConstElementPtr rsp;
-    runProcessSynchronize4(config_storage, rsp);
+    runProcessSynchronize4(config_storage, "server2", rsp);
 
     // The response should indicate an error
     ASSERT_TRUE(rsp);
@@ -4123,7 +4125,7 @@ TEST_F(HAServiceTest, processSynchronizeLease4GetPageError) {
 
     // Run HAService::processSynchronize and gather a response.
     ConstElementPtr rsp;
-    runProcessSynchronize4(config_storage, rsp);
+    runProcessSynchronize4(config_storage, "server2", rsp);
 
     // The response should indicate an error
     ASSERT_TRUE(rsp);
@@ -4160,7 +4162,7 @@ TEST_F(HAServiceTest, processSynchronizeEnableError) {
 
     // Run HAService::processSynchronize and gather a response.
     ConstElementPtr rsp;
-    runProcessSynchronize4(config_storage, rsp);
+    runProcessSynchronize4(config_storage, "server2", rsp);
 
     // The response should indicate an error
     ASSERT_TRUE(rsp);
@@ -4208,7 +4210,7 @@ TEST_F(HAServiceTest, processSynchronizeNotifyError) {
 
     // Run HAService::processSynchronize and gather a response.
     ConstElementPtr rsp;
-    runProcessSynchronize4(config_storage, rsp);
+    runProcessSynchronize4(config_storage, "server2", rsp);
 
     // The response should indicate an error
     ASSERT_TRUE(rsp);
@@ -4238,6 +4240,27 @@ TEST_F(HAServiceTest, processSynchronizeNotifyError) {
     EXPECT_FALSE(factory2_->getResponseCreator()->findRequest("dhcp-enable",""));
 }
 
+// This test verifies that an error is reported when server-name parameter
+// points to a non-existing server.
+TEST_F(HAServiceTest, processSynchronize4InvalidServerName) {
+    // Create HA configuration for 3 servers. This server is
+    // server 1.
+    HAConfigPtr config_storage = createValidConfiguration();
+    setBasicAuth(config_storage);
+
+    // Run HAService::processSynchronize and gather a response.
+    ConstElementPtr rsp;
+    runProcessSynchronize4(config_storage, "server8", rsp);
+
+    // The response should indicate an error
+    ASSERT_TRUE(rsp);
+    checkAnswer(rsp, CONTROL_RESULT_ERROR);
+
+    // This server should issue no command because we expect that
+    // it returns after checking that the specified server doesn't exist.
+    EXPECT_FALSE(factory2_->getResponseCreator()->findRequest("dhcp-disable", ""));
+}
+
 // This test verifies that the ha-sync command is processed successfully for the
 // DHCPv6 server.
 TEST_F(HAServiceTest, processSynchronize6) {
@@ -4249,7 +4272,7 @@ TEST_F(HAServiceTest, processSynchronize6) {
 
     // Run HAService::processSynchronize and gather a response.
     ConstElementPtr rsp;
-    runProcessSynchronize6(config_storage, rsp);
+    runProcessSynchronize6(config_storage, "server2", rsp);
 
     // The response should indicate success.
     ASSERT_TRUE(rsp);
@@ -4282,7 +4305,7 @@ TEST_F(HAServiceTest, processSynchronize6PassiveBackup) {
 
     // Run HAService::processSynchronize and gather a response.
     ConstElementPtr rsp;
-    runProcessSynchronize6(config_storage, rsp);
+    runProcessSynchronize6(config_storage, "server2", rsp);
 
     // The response should indicate success.
     ASSERT_TRUE(rsp);
@@ -4324,7 +4347,7 @@ TEST_F(HAServiceTest, processSynchronize6Authorized) {
 
     // Run HAService::processSynchronize and gather a response.
     ConstElementPtr rsp;
-    runProcessSynchronize6(config_storage, rsp);
+    runProcessSynchronize6(config_storage, "server2", rsp);
 
     // The response should indicate success.
     ASSERT_TRUE(rsp);
@@ -4360,7 +4383,7 @@ TEST_F(HAServiceTest, processSynchronize6DisableError) {
 
     // Run HAService::processSynchronize and gather a response.
     ConstElementPtr rsp;
-    runProcessSynchronize6(config_storage, rsp);
+    runProcessSynchronize6(config_storage, "server2", rsp);
 
     // The response should indicate an error
     ASSERT_TRUE(rsp);
@@ -4386,7 +4409,7 @@ TEST_F(HAServiceTest, processSynchronize6Unauthorized) {
 
     // Run HAService::processSynchronize and gather a response.
     ConstElementPtr rsp;
-    runProcessSynchronize6(config_storage, rsp);
+    runProcessSynchronize6(config_storage, "server2", rsp);
 
     // The response should indicate an error
     ASSERT_TRUE(rsp);
@@ -4410,7 +4433,7 @@ TEST_F(HAServiceTest, processSynchronizeLease6GetPageError) {
 
     // Run HAService::processSynchronize and gather a response.
     ConstElementPtr rsp;
-    runProcessSynchronize6(config_storage, rsp);
+    runProcessSynchronize6(config_storage, "server2", rsp);
 
     // The response should indicate an error
     ASSERT_TRUE(rsp);
@@ -4443,7 +4466,7 @@ TEST_F(HAServiceTest, processSynchronize6EnableError) {
 
     // Run HAService::processSynchronize and gather a response.
     ConstElementPtr rsp;
-    runProcessSynchronize6(config_storage, rsp);
+    runProcessSynchronize6(config_storage, "server2", rsp);
 
     // The response should indicate an error
     ASSERT_TRUE(rsp);
@@ -4471,7 +4494,7 @@ TEST_F(HAServiceTest, processSynchronize6NotifyError) {
 
     // Run HAService::processSynchronize and gather a response.
     ConstElementPtr rsp;
-    runProcessSynchronize6(config_storage, rsp);
+    runProcessSynchronize6(config_storage, "server2", rsp);
 
     // The response should indicate an error
     ASSERT_TRUE(rsp);
@@ -4483,6 +4506,27 @@ TEST_F(HAServiceTest, processSynchronize6NotifyError) {
     EXPECT_FALSE(factory2_->getResponseCreator()->findRequest("dhcp-enable",""));
 }
 
+// This test verifies that an error is reported when server-name parameter
+// points to a local server.
+TEST_F(HAServiceTest, processSynchronize6LocalServer) {
+    // Create HA configuration for 3 servers. This server is
+    // server 1.
+    HAConfigPtr config_storage = createValidConfiguration();
+    setBasicAuth(config_storage);
+
+    // Run HAService::processSynchronize and gather a response.
+    ConstElementPtr rsp;
+    runProcessSynchronize6(config_storage, "server1", rsp);
+
+    // The response should indicate an error
+    ASSERT_TRUE(rsp);
+    checkAnswer(rsp, CONTROL_RESULT_ERROR);
+
+    // This server should issue no command because we expect that
+    // it returns after checking that the specified server doesn't exist.
+    EXPECT_FALSE(factory2_->getResponseCreator()->findRequest("dhcp-disable", ""));
+}
+
 // This test verifies that the DHCPv4 service can be disabled on the remote server.
 TEST_F(HAServiceTest, asyncDisableDHCPService4) {
     // Create HA configuration.
@@ -4500,7 +4544,7 @@ TEST_F(HAServiceTest, asyncDisableDHCPService4) {
 
     // Send dhcp-disable command with max-period of 10 seconds.
     // When the transaction is finished, the IO service gets stopped.
-    ASSERT_NO_THROW(service.asyncDisableDHCPService("server3", 10,
+    ASSERT_NO_THROW(service.asyncDisableDHCPService(config_storage->getPeerConfig("server3"), 10,
                                                     [this](const bool success,
                                                            const std::string& error_message,
                                                            const int) {
@@ -4546,7 +4590,7 @@ TEST_F(HAServiceTest, asyncDisableDHCPService4Authorized) {
 
     // Send dhcp-disable command with max-period of 10 seconds.
     // When the transaction is finished, the IO service gets stopped.
-    ASSERT_NO_THROW(service.asyncDisableDHCPService("server3", 10,
+    ASSERT_NO_THROW(service.asyncDisableDHCPService(config_storage->getPeerConfig("server3"), 10,
                                                     [this](const bool success,
                                                            const std::string& error_message,
                                                            const int) {
@@ -4575,7 +4619,7 @@ TEST_F(HAServiceTest, asyncDisableDHCPService4ServerOffline) {
 
     // Send dhcp-disable command with max-period of 10 seconds.
     // When the transaction is finished, the IO service gets stopped.
-    ASSERT_NO_THROW(service.asyncDisableDHCPService("server2", 10,
+    ASSERT_NO_THROW(service.asyncDisableDHCPService(config_storage->getPeerConfig("server2"), 10,
                                                     [this](const bool success,
                                                            const std::string& error_message,
                                                            const int) {
@@ -4610,7 +4654,7 @@ TEST_F(HAServiceTest, asyncDisableDHCPService4ControlResultError) {
 
     // Send dhcp-disable command with max-period of 10 seconds.
     // When the transaction is finished, the IO service gets stopped.
-    ASSERT_NO_THROW(service.asyncDisableDHCPService("server3", 10,
+    ASSERT_NO_THROW(service.asyncDisableDHCPService(config_storage->getPeerConfig("server3"), 10,
                                                     [this](const bool success,
                                                            const std::string& error_message,
                                                            const int) {
@@ -4644,7 +4688,7 @@ TEST_F(HAServiceTest, asyncDisableDHCPService4ControlResultUnauthorized) {
 
     // Send dhcp-disable command with max-period of 10 seconds.
     // When the transaction is finished, the IO service gets stopped.
-    ASSERT_NO_THROW(service.asyncDisableDHCPService("server3", 10,
+    ASSERT_NO_THROW(service.asyncDisableDHCPService(config_storage->getPeerConfig("server3"), 10,
                                                     [this](const bool success,
                                                            const std::string& error_message,
                                                            const int) {
@@ -4674,7 +4718,7 @@ TEST_F(HAServiceTest, asyncEnableDHCPService4) {
 
     // Send dhcp-enable command. When the transaction is finished,
     // the IO service gets stopped.
-    ASSERT_NO_THROW(service.asyncEnableDHCPService("server2",
+    ASSERT_NO_THROW(service.asyncEnableDHCPService(config_storage->getPeerConfig("server2"),
                                                    [this](const bool success,
                                                           const std::string& error_message,
                                                           const int) {
@@ -4719,7 +4763,7 @@ TEST_F(HAServiceTest, asyncEnableDHCPService4Authorized) {
 
     // Send dhcp-enable command. When the transaction is finished,
     // the IO service gets stopped.
-    ASSERT_NO_THROW(service.asyncEnableDHCPService("server2",
+    ASSERT_NO_THROW(service.asyncEnableDHCPService(config_storage->getPeerConfig("server2"),
                                                    [this](const bool success,
                                                           const std::string& error_message,
                                                           const int) {
@@ -4747,7 +4791,7 @@ TEST_F(HAServiceTest, asyncEnableDHCPService4ServerOffline) {
 
     // Send dhcp-enable command. When the transaction is finished,
     // the IO service gets stopped.
-    ASSERT_NO_THROW(service.asyncEnableDHCPService("server2",
+    ASSERT_NO_THROW(service.asyncEnableDHCPService(config_storage->getPeerConfig("server2"),
                                                    [this](const bool success,
                                                           const std::string& error_message,
                                                           const int) {
@@ -4782,7 +4826,7 @@ TEST_F(HAServiceTest, asyncEnableDHCPService4ControlResultError) {
 
     // Send dhcp-enable command. When the transaction is finished,
     // the IO service gets stopped.
-    ASSERT_NO_THROW(service.asyncEnableDHCPService("server2",
+    ASSERT_NO_THROW(service.asyncEnableDHCPService(config_storage->getPeerConfig("server2"),
                                                    [this](const bool success,
                                                           const std::string& error_message,
                                                           const int) {
@@ -4816,7 +4860,7 @@ TEST_F(HAServiceTest, asyncEnableDHCPService4ControlResultUnauthorized) {
 
     // Send dhcp-enable command. When the transaction is finished,
     // the IO service gets stopped.
-    ASSERT_NO_THROW(service.asyncEnableDHCPService("server2",
+    ASSERT_NO_THROW(service.asyncEnableDHCPService(config_storage->getPeerConfig("server2"),
                                                    [this](const bool success,
                                                           const std::string& error_message,
                                                           const int) {