26#include <boost/pointer_cast.hpp>
27#include <boost/make_shared.hpp>
28#include <boost/weak_ptr.hpp>
40namespace ph = std::placeholders;
47 CommandUnsupportedError(
const char* file,
size_t line,
const char* what) :
68 : io_service_(io_service), network_state_(network_state), config_(config),
69 server_type_(server_type), client_(), listener_(), communication_state_(),
70 query_filter_(config), mutex_(), pending_requests_(),
71 lease_update_backlog_(config->getDelayedUpdatesLimit()),
72 sync_complete_notified_(false) {
86 if (!
config_->getEnableMultiThreading()) {
92 config_->getHttpClientThreads(),
true));
95 if (
config_->getHttpDedicatedListener()) {
97 auto my_url =
config_->getThisServerConfig()->getUrl();
98 IOAddress server_address(IOAddress::IPV4_ZERO_ADDRESS());
102 server_address =
IOAddress(my_url.getStrippedHostname());
103 }
catch (
const std::exception& ex) {
105 <<
" is not a valid IP address");
109 uint32_t listener_threads =
config_->getHttpListenerThreads();
131 StateModel::defineEvents();
145 StateModel::verifyEvents();
159 StateModel::defineStates();
398 }
else if (
config_->amAllowingCommRecovery()) {
457 if (maintenance ||
config_->getThisServerConfig()->isAutoFailover()) {
728 unsigned int dhcp_disable_timeout =
729 static_cast<unsigned int>(
config_->getSyncTimeout() / 1000);
730 if (dhcp_disable_timeout == 0) {
731 ++dhcp_disable_timeout;
735 std::string status_message;
737 config_->getFailoverPeerConfig()->getName(),
738 dhcp_disable_timeout);
893 boost::to_upper(current_state_name);
894 boost::to_upper(new_state_name);
900 std::string partner_state_name =
getStateLabel(partner_state);
901 boost::to_upper(partner_state_name);
905 .arg(current_state_name)
907 .arg(partner_state_name);
912 .arg(current_state_name)
913 .arg(new_state_name);
934 .arg(new_state_name);
936 }
else if (!
config_->amSendingLeaseUpdates()) {
939 .arg(new_state_name);
946 .arg(new_state_name);
957 switch (
config_->getHAMode()) {
982 boost::to_upper(state_name);
995 return (inScopeInternal(query4));
1000 return (inScopeInternal(query6));
1003template<
typename QueryPtrType>
1005HAService::inScopeInternal(QueryPtrType& query) {
1007 std::string scope_class;
1026 boost::to_upper(current_state_name);
1039 boost::to_upper(current_state_name);
1041 .arg(
config_->getThisServerName())
1042 .arg(current_state_name);
1043 network_state_->disableService(NetworkState::Origin::HA_COMMAND);
1045 }
else if (should_enable && !
network_state_->isServiceEnabled()) {
1047 boost::to_upper(current_state_name);
1049 .arg(
config_->getThisServerName())
1050 .arg(current_state_name);
1088 if (!should_terminate) {
1092 return (should_terminate);
1139 size_t sent_num = 0;
1142 for (
auto p = peers_configs.begin(); p != peers_configs.end(); ++p) {
1150 for (
auto l = deleted_leases->begin(); l != deleted_leases->end(); ++l) {
1155 for (
auto l = leases->begin(); l != leases->end(); ++l) {
1177 for (
auto l = deleted_leases->begin(); l != deleted_leases->end(); ++l) {
1183 for (
auto l = leases->begin(); l != leases->end(); ++l) {
1208 size_t sent_num = 0;
1211 for (
auto p = peers_configs.begin(); p != peers_configs.end(); ++p) {
1218 for (
auto l = deleted_leases->begin(); l != deleted_leases->end(); ++l) {
1223 for (
auto l = leases->begin(); l != leases->end(); ++l) {
1259template<
typename QueryPtrType>
1263 if (MultiThreadingMgr::instance().getMode()) {
1264 std::lock_guard<std::mutex> lock(mutex_);
1265 return (leaseUpdateCompleteInternal(query, parking_lot));
1267 return (leaseUpdateCompleteInternal(query, parking_lot));
1271template<
typename QueryPtrType>
1273HAService::leaseUpdateCompleteInternal(QueryPtrType& query,
1275 auto it = pending_requests_.find(query);
1279 if (it == pending_requests_.end() || (--pending_requests_[query] <= 0)) {
1280 parking_lot->unpark(query);
1284 if (it != pending_requests_.end()) {
1285 pending_requests_.erase(it);
1292template<
typename QueryPtrType>
1295 if (MultiThreadingMgr::instance().getMode()) {
1296 std::lock_guard<std::mutex> lock(mutex_);
1297 updatePendingRequestInternal(query);
1299 updatePendingRequestInternal(query);
1303template<
typename QueryPtrType>
1305HAService::updatePendingRequestInternal(QueryPtrType& query) {
1306 if (pending_requests_.count(query) == 0) {
1307 pending_requests_[query] = 1;
1309 ++pending_requests_[query];
1313template<
typename QueryPtrType>
1321 (HttpRequest::Method::HTTP_POST,
"/", HttpVersion::HTTP_11(),
1323 config->addBasicAuthHttpHeader(request);
1324 request->setBodyAsJson(command);
1325 request->finalize();
1334 boost::weak_ptr<typename QueryPtrType::element_type> weak_query(query);
1337 client_->asyncSendRequest(config->getUrl(), config->getTlsContext(),
1339 [
this, weak_query, parking_lot, config]
1340 (
const boost::system::error_code& ec,
1342 const std::string& error_str) {
1346 QueryPtrType query = weak_query.lock();
1348 isc_throw(Unexpected,
"query is null while receiving response from"
1349 " HA peer. This is programmatic error");
1358 bool lease_update_success =
true;
1361 if (ec || !error_str.empty()) {
1362 LOG_WARN(ha_logger, HA_LEASE_UPDATE_COMMUNICATIONS_FAILED)
1363 .arg(query->getLabel())
1364 .arg(config->getLogLabel())
1365 .arg(ec ? ec.message() : error_str);
1369 lease_update_success = false;
1376 auto args = verifyAsyncResponse(response, rcode);
1379 logFailedLeaseUpdates(query, args);
1381 } catch (
const std::exception& ex) {
1383 .arg(query->getLabel())
1384 .arg(config->getLogLabel())
1388 lease_update_success =
false;
1397 communication_state_->setPartnerState(
"unavailable");
1407 if (!lease_update_success) {
1408 parking_lot->drop(query);
1416 if (leaseUpdateComplete(query, parking_lot)) {
1422 runModel(HA_LEASE_UPDATES_COMPLETE_EVT);
1426 std::bind(&HAService::clientConnectHandler,
this, ph::_1, ph::_2),
1427 std::bind(&HAService::clientHandshakeHandler,
this, ph::_1),
1428 std::bind(&HAService::clientCloseHandler,
this, ph::_1)
1435 if (config_->amWaitingBackupAck() || (config->getRole() != HAConfig::PeerConfig::BACKUP)) {
1437 updatePendingRequest(query);
1444 if (!config_->amSendingLeaseUpdates()) {
1449 if (peer_config->getRole() == HAConfig::PeerConfig::BACKUP) {
1454 if (config_->getThisServerConfig()->getRole() == HAConfig::PeerConfig::BACKUP) {
1460 switch (getCurrState()) {
1475 if (!config_->amSendingLeaseUpdates()) {
1479 if (peer_config->getRole() == HAConfig::PeerConfig::BACKUP) {
1487HAService::logFailedLeaseUpdates(
const PktPtr& query,
1490 if (!args || (args->getType() != Element::map)) {
1500 auto failed_leases = args->get(param_name);
1503 if (failed_leases && (failed_leases->getType() == Element::list)) {
1505 for (
int i = 0; i < failed_leases->size(); ++i) {
1506 auto lease = failed_leases->get(i);
1507 if (lease->getType() == Element::map) {
1510 auto ip_address = lease->get(
"ip-address");
1513 auto lease_type = lease->get(
"type");
1516 auto error_message = lease->get(
"error-message");
1519 .arg(query->getLabel())
1520 .arg(lease_type && (lease_type->getType() == Element::string) ?
1521 lease_type->stringValue() :
"(unknown)")
1522 .arg(ip_address && (ip_address->getType() == Element::string) ?
1523 ip_address->stringValue() :
"(unknown)")
1524 .arg(error_message && (error_message->getType() == Element::string) ?
1525 error_message->stringValue() :
"(unknown)");
1539HAService::processStatusGet()
const {
1540 ElementPtr ha_servers = Element::createMap();
1545 role = config_->getThisServerConfig()->getRole();
1546 std::string role_txt = HAConfig::PeerConfig::roleToString(role);
1547 local->set(
"role", Element::create(role_txt));
1548 int state = getCurrState();
1554 local->set(
"state", Element::create(std::string()));
1556 std::set<std::string> scopes = query_filter_.getServedScopes();
1558 for (std::string scope : scopes) {
1559 list->add(Element::create(scope));
1561 local->set(
"scopes", list);
1562 ha_servers->set(
"local", local);
1566 if ((config_->getHAMode() == HAConfig::PASSIVE_BACKUP) ||
1567 (config_->getThisServerConfig()->getRole() == HAConfig::PeerConfig::BACKUP)) {
1568 return (ha_servers);
1572 ElementPtr remote = communication_state_->getReport();
1575 role = config_->getFailoverPeerConfig()->getRole();
1576 std::string role_txt = HAConfig::PeerConfig::roleToString(role);
1577 remote->set(
"role", Element::create(role_txt));
1580 remote->set(
"role", Element::create(std::string()));
1582 ha_servers->set(
"remote", remote);
1584 return (ha_servers);
1588HAService::processHeartbeat() {
1590 std::string state_label = getState(getCurrState())->getLabel();
1591 arguments->set(
"state", Element::create(state_label));
1594 arguments->set(
"date-time", Element::create(date_time));
1596 auto scopes = query_filter_.getServedScopes();
1597 ElementPtr scopes_list = Element::createList();
1598 for (
auto scope : scopes) {
1599 scopes_list->add(Element::create(scope));
1601 arguments->set(
"scopes", scopes_list);
1603 arguments->set(
"unsent-update-count",
1604 Element::create(
static_cast<int64_t
>(communication_state_->getUnsentUpdateCount())));
1611HAService::processHAReset() {
1621HAService::asyncSendHeartbeat() {
1631 bool sync_complete_notified = sync_complete_notified_;
1632 sync_complete_notified_ =
false;
1636 (HttpRequest::Method::HTTP_POST,
"/", HttpVersion::HTTP_11(),
1638 partner_config->addBasicAuthHttpHeader(request);
1639 request->setBodyAsJson(CommandCreator::createHeartbeat(server_type_));
1640 request->finalize();
1647 client_->asyncSendRequest(partner_config->getUrl(),
1648 partner_config->getTlsContext(),
1650 [
this, partner_config, sync_complete_notified]
1651 (
const boost::system::error_code& ec,
1653 const std::string& error_str) {
1661 bool heartbeat_success = true;
1664 if (ec || !error_str.empty()) {
1665 LOG_WARN(ha_logger, HA_HEARTBEAT_COMMUNICATIONS_FAILED)
1666 .arg(partner_config->getLogLabel())
1667 .arg(ec ? ec.message() : error_str);
1668 heartbeat_success = false;
1677 ConstElementPtr args = verifyAsyncResponse(response, rcode);
1678 if (!args || args->getType() != Element::map) {
1679 isc_throw(CtrlChannelError,
"returned arguments in the response"
1683 ConstElementPtr state = args->get(
"state");
1684 if (!state || state->getType() != Element::string) {
1685 isc_throw(CtrlChannelError,
"server state not returned in response"
1686 " to a ha-heartbeat command or it is not a string");
1690 communication_state_->setPartnerState(state->stringValue());
1692 ConstElementPtr date_time = args->get(
"date-time");
1693 if (!date_time || date_time->getType() != Element::string) {
1694 isc_throw(CtrlChannelError,
"date-time not returned in response"
1695 " to a ha-heartbeat command or it is not a string");
1698 communication_state_->setPartnerTime(date_time->stringValue());
1702 auto scopes = args->get(
"scopes");
1703 communication_state_->setPartnerScopes(scopes);
1718 auto unsent_update_count = args->get(
"unsent-update-count");
1719 if (unsent_update_count) {
1720 if (unsent_update_count->getType() != Element::integer) {
1721 isc_throw(CtrlChannelError,
"unsent-update-count returned in"
1722 " the ha-heartbeat response is not an integer");
1724 communication_state_->setPartnerUnsentUpdateCount(static_cast<uint64_t>
1725 (unsent_update_count->intValue()));
1728 } catch (
const std::exception& ex) {
1730 .arg(partner_config->getLogLabel())
1732 heartbeat_success =
false;
1738 if (heartbeat_success) {
1739 communication_state_->poke();
1744 communication_state_->setPartnerState(
"unavailable");
1746 if (communication_state_->isCommunicationInterrupted()) {
1748 .arg(partner_config->getName());
1756 if (sync_complete_notified && !heartbeat_success) {
1757 postNextEvent(HA_SYNCED_PARTNER_UNAVAILABLE_EVT);
1764 runModel(HA_HEARTBEAT_COMPLETE_EVT);
1767 std::bind(&HAService::clientConnectHandler,
this, ph::_1, ph::_2),
1768 std::bind(&HAService::clientHandshakeHandler,
this, ph::_1),
1769 std::bind(&HAService::clientCloseHandler,
this, ph::_1)
1774HAService::scheduleHeartbeat() {
1775 if (!communication_state_->isHeartbeatRunning()) {
1781HAService::startHeartbeat() {
1782 if (config_->getHeartbeatDelay() > 0) {
1783 communication_state_->startHeartbeat(config_->getHeartbeatDelay(),
1784 std::bind(&HAService::asyncSendHeartbeat,
1791 const std::string& server_name,
1792 const unsigned int max_period,
1798 (HttpRequest::Method::HTTP_POST,
"/", HttpVersion::HTTP_11(),
1801 remote_config->addBasicAuthHttpHeader(request);
1802 request->setBodyAsJson(CommandCreator::createDHCPDisable(max_period,
1804 request->finalize();
1812 remote_config->getTlsContext(),
1814 [
this, remote_config, post_request_action]
1815 (
const boost::system::error_code& ec,
1817 const std::string& error_str) {
1826 std::string error_message;
1829 if (ec || !error_str.empty()) {
1830 error_message = (ec ? ec.message() : error_str);
1831 LOG_ERROR(ha_logger, HA_DHCP_DISABLE_COMMUNICATIONS_FAILED)
1832 .arg(remote_config->getLogLabel())
1833 .arg(error_message);
1839 static_cast<void>(verifyAsyncResponse(response, rcode));
1841 } catch (
const std::exception& ex) {
1842 error_message = ex.what();
1844 .arg(remote_config->getLogLabel())
1845 .arg(error_message);
1851 if (!error_message.empty()) {
1852 communication_state_->setPartnerState(
"unavailable");
1856 if (post_request_action) {
1857 post_request_action(error_message.empty(),
1863 std::bind(&HAService::clientConnectHandler,
this, ph::_1, ph::_2),
1864 std::bind(&HAService::clientHandshakeHandler,
this, ph::_1),
1865 std::bind(&HAService::clientCloseHandler,
this, ph::_1)
1871 const std::string& server_name,
1877 (HttpRequest::Method::HTTP_POST,
"/", HttpVersion::HTTP_11(),
1879 remote_config->addBasicAuthHttpHeader(request);
1880 request->setBodyAsJson(CommandCreator::createDHCPEnable(server_type_));
1881 request->finalize();
1889 remote_config->getTlsContext(),
1891 [
this, remote_config, post_request_action]
1892 (
const boost::system::error_code& ec,
1894 const std::string& error_str) {
1903 std::string error_message;
1906 if (ec || !error_str.empty()) {
1907 error_message = (ec ? ec.message() : error_str);
1908 LOG_ERROR(ha_logger, HA_DHCP_ENABLE_COMMUNICATIONS_FAILED)
1909 .arg(remote_config->getLogLabel())
1910 .arg(error_message);
1916 static_cast<void>(verifyAsyncResponse(response, rcode));
1918 } catch (
const std::exception& ex) {
1919 error_message = ex.what();
1921 .arg(remote_config->getLogLabel())
1922 .arg(error_message);
1928 if (!error_message.empty()) {
1929 communication_state_->setPartnerState(
"unavailable");
1933 if (post_request_action) {
1934 post_request_action(error_message.empty(),
1940 std::bind(&HAService::clientConnectHandler,
this, ph::_1, ph::_2),
1941 std::bind(&HAService::clientHandshakeHandler,
this, ph::_1),
1942 std::bind(&HAService::clientCloseHandler,
this, ph::_1)
1947HAService::localDisableDHCPService() {
1948 network_state_->disableService(NetworkState::Origin::HA_COMMAND);
1952HAService::localEnableDHCPService() {
1953 network_state_->enableService(NetworkState::Origin::HA_COMMAND);
1957HAService::asyncSyncLeases() {
1961 unsigned int dhcp_disable_timeout =
1962 static_cast<unsigned int>(config_->getSyncTimeout() / 1000);
1963 if (dhcp_disable_timeout == 0) {
1965 dhcp_disable_timeout = 1;
1968 asyncSyncLeases(*client_, config_->getFailoverPeerConfig()->getName(),
1969 dhcp_disable_timeout,
LeasePtr(), null_action);
1974 const std::string& server_name,
1975 const unsigned int max_period,
1978 const bool dhcp_disabled) {
1984 asyncDisableDHCPService(http_client, server_name, max_period,
1985 [
this, &http_client, server_name, max_period, last_lease,
1986 post_sync_action, dhcp_disabled]
1987 (
const bool success,
const std::string& error_message,
const int) {
1994 asyncSyncLeasesInternal(http_client, server_name, max_period,
1995 last_lease, post_sync_action,
true);
1998 post_sync_action(success, error_message, dhcp_disabled);
2005 const std::string& server_name,
2006 const unsigned int max_period,
2009 const bool dhcp_disabled) {
2015 (HttpRequest::Method::HTTP_POST,
"/", HttpVersion::HTTP_11(),
2017 partner_config->addBasicAuthHttpHeader(request);
2018 if (server_type_ == HAServerType::DHCPv4) {
2019 request->setBodyAsJson(CommandCreator::createLease4GetPage(
2020 boost::dynamic_pointer_cast<Lease4>(last_lease), config_->getSyncPageLimit()));
2023 request->setBodyAsJson(CommandCreator::createLease6GetPage(
2024 boost::dynamic_pointer_cast<Lease6>(last_lease), config_->getSyncPageLimit()));
2026 request->finalize();
2034 partner_config->getTlsContext(),
2036 [
this, partner_config, post_sync_action, &http_client, server_name,
2037 max_period, dhcp_disabled]
2038 (
const boost::system::error_code& ec,
2040 const std::string& error_str) {
2044 LeasePtr last_lease;
2052 std::string error_message;
2055 if (ec || !error_str.empty()) {
2056 error_message = (ec ? ec.message() : error_str);
2057 LOG_ERROR(ha_logger, HA_LEASES_SYNC_COMMUNICATIONS_FAILED)
2058 .arg(partner_config->getLogLabel())
2059 .arg(error_message);
2065 ConstElementPtr args = verifyAsyncResponse(response, rcode);
2068 if (args && (args->getType() != Element::map)) {
2069 isc_throw(CtrlChannelError,
2070 "arguments in the received response must be a map");
2073 ConstElementPtr leases = args->get(
"leases");
2074 if (!leases || (leases->getType() != Element::list)) {
2075 isc_throw(CtrlChannelError,
2076 "server response does not contain leases argument or this"
2077 " argument is not a list");
2081 const auto& leases_element = leases->listValue();
2083 LOG_INFO(ha_logger, HA_LEASES_SYNC_LEASE_PAGE_RECEIVED)
2084 .arg(leases_element.size())
2087 for (auto l = leases_element.begin(); l != leases_element.end(); ++l) {
2090 if (server_type_ == HAServerType::DHCPv4) {
2091 Lease4Ptr lease = Lease4::fromElement(*l);
2094 Lease4Ptr existing_lease = LeaseMgrFactory::instance().getLease4(lease->addr_);
2095 if (!existing_lease) {
2097 LeaseMgrFactory::instance().addLease(lease);
2099 } else if (existing_lease->cltt_ < lease->cltt_) {
2105 Lease::syncCurrentExpirationTime(*existing_lease, *lease);
2106 LeaseMgrFactory::instance().updateLease4(lease);
2109 LOG_DEBUG(ha_logger, DBGLVL_TRACE_BASIC, HA_LEASE_SYNC_STALE_LEASE4_SKIP)
2110 .arg(lease->addr_.toText())
2111 .arg(lease->subnet_id_);
2117 if ((leases_element.size() >= config_->getSyncPageLimit()) &&
2118 (l + 1 == leases_element.end())) {
2119 last_lease = boost::dynamic_pointer_cast<Lease>(lease);
2123 Lease6Ptr lease = Lease6::fromElement(*l);
2126 Lease6Ptr existing_lease = LeaseMgrFactory::instance().getLease6(lease->type_,
2128 if (!existing_lease) {
2130 LeaseMgrFactory::instance().addLease(lease);
2132 } else if (existing_lease->cltt_ < lease->cltt_) {
2138 Lease::syncCurrentExpirationTime(*existing_lease, *lease);
2139 LeaseMgrFactory::instance().updateLease6(lease);
2142 LOG_DEBUG(ha_logger, DBGLVL_TRACE_BASIC, HA_LEASE_SYNC_STALE_LEASE6_SKIP)
2143 .arg(lease->addr_.toText())
2144 .arg(lease->subnet_id_);
2150 if ((leases_element.size() >= config_->getSyncPageLimit()) &&
2151 (l + 1 == leases_element.end())) {
2152 last_lease = boost::dynamic_pointer_cast<Lease>(lease);
2156 } catch (const std::exception& ex) {
2157 LOG_WARN(ha_logger, HA_LEASE_SYNC_FAILED)
2163 } catch (
const std::exception& ex) {
2164 error_message = ex.what();
2166 .arg(partner_config->getLogLabel())
2167 .arg(error_message);
2173 if (!error_message.empty()) {
2174 communication_state_->setPartnerState(
"unavailable");
2176 }
else if (last_lease) {
2179 asyncSyncLeases(http_client, server_name, max_period, last_lease,
2180 post_sync_action, dhcp_disabled);
2185 if (post_sync_action) {
2186 post_sync_action(error_message.empty(),
2192 std::bind(&HAService::clientConnectHandler,
this, ph::_1, ph::_2),
2193 std::bind(&HAService::clientHandshakeHandler,
this, ph::_1),
2194 std::bind(&HAService::clientCloseHandler,
this, ph::_1)
2200HAService::processSynchronize(
const std::string& server_name,
2201 const unsigned int max_period) {
2202 std::string answer_message;
2203 int sync_status = synchronize(answer_message, server_name, max_period);
2208HAService::synchronize(std::string& status_message,
const std::string& server_name,
2209 const unsigned int max_period) {
2213 asyncSyncLeases(client, server_name, max_period,
Lease4Ptr(),
2214 [&](
const bool success,
const std::string& error_message,
2215 const bool dhcp_disabled) {
2220 status_message = error_message;
2226 if (dhcp_disabled) {
2231 asyncSyncCompleteNotify(client, server_name,
2232 [&](
const bool success,
2233 const std::string& error_message,
2239 asyncEnableDHCPService(client, server_name,
2240 [&](
const bool success,
2241 const std::string& error_message,
2246 if (!success && status_message.empty()) {
2247 status_message = error_message;
2259 if (!success && status_message.empty()) {
2260 status_message = error_message;
2272 asyncEnableDHCPService(client, server_name,
2273 [&](
const bool success,
2274 const std::string& error_message,
2276 if (!success && status_message.empty()) {
2277 status_message = error_message;
2309 if (!status_message.empty()) {
2310 postNextEvent(HA_SYNCING_FAILED_EVT);
2314 .arg(status_message);
2321 status_message =
"Lease database synchronization complete.";
2322 postNextEvent(HA_SYNCING_SUCCEEDED_EVT);
2332HAService::asyncSendLeaseUpdatesFromBacklog(
HttpClient& http_client,
2335 if (lease_update_backlog_.size() == 0) {
2341 if (server_type_ == HAServerType::DHCPv4) {
2343 Lease4Ptr lease = boost::dynamic_pointer_cast<Lease4>(lease_update_backlog_.pop(op_type));
2344 if (op_type == LeaseUpdateBacklog::ADD) {
2345 command = CommandCreator::createLease4Update(*lease);
2347 command = CommandCreator::createLease4Delete(*lease);
2351 command = CommandCreator::createLease6BulkApply(lease_update_backlog_);
2356 (HttpRequest::Method::HTTP_POST,
"/", HttpVersion::HTTP_11(),
2358 config->addBasicAuthHttpHeader(request);
2359 request->setBodyAsJson(command);
2360 request->finalize();
2368 [
this, &http_client, config, post_request_action]
2369 (
const boost::system::error_code& ec,
2371 const std::string& error_str) {
2374 std::string error_message;
2376 if (ec || !error_str.empty()) {
2377 error_message = (ec ? ec.message() : error_str);
2378 LOG_WARN(ha_logger, HA_LEASES_BACKLOG_COMMUNICATIONS_FAILED)
2379 .arg(config->getLogLabel())
2380 .arg(ec ? ec.message() : error_str);
2385 auto args = verifyAsyncResponse(response, rcode);
2386 } catch (
const std::exception& ex) {
2387 error_message = ex.what();
2389 .arg(config->getLogLabel())
2399 if (error_message.empty()) {
2400 asyncSendLeaseUpdatesFromBacklog(http_client, config, post_request_action);
2402 post_request_action(error_message.empty(), error_message, rcode);
2408HAService::sendLeaseUpdatesFromBacklog() {
2409 auto num_updates = lease_update_backlog_.size();
2410 if (num_updates == 0) {
2417 auto remote_config = config_->getFailoverPeerConfig();
2418 bool updates_successful =
true;
2422 .arg(remote_config->getName());
2424 asyncSendLeaseUpdatesFromBacklog(client, remote_config,
2425 [&](
const bool success,
const std::string&,
const int) {
2427 updates_successful = success;
2439 if (updates_successful) {
2441 .arg(remote_config->getName())
2442 .arg(stopwatch.logFormatLastDuration());
2445 return (updates_successful);
2452 ConstElementPtr command = CommandCreator::createHAReset(server_type_);
2456 (HttpRequest::Method::HTTP_POST,
"/", HttpVersion::HTTP_11(),
2458 config->addBasicAuthHttpHeader(request);
2459 request->setBodyAsJson(command);
2460 request->finalize();
2468 [
this, config, post_request_action]
2469 (
const boost::system::error_code& ec,
2471 const std::string& error_str) {
2474 std::string error_message;
2476 if (ec || !error_str.empty()) {
2477 error_message = (ec ? ec.message() : error_str);
2478 LOG_WARN(ha_logger, HA_RESET_COMMUNICATIONS_FAILED)
2479 .arg(config->getLogLabel())
2480 .arg(ec ? ec.message() : error_str);
2485 auto args = verifyAsyncResponse(response, rcode);
2486 } catch (
const std::exception& ex) {
2487 error_message = ex.what();
2489 .arg(config->getLogLabel())
2494 post_request_action(error_message.empty(), error_message, rcode);
2499HAService::sendHAReset() {
2502 auto remote_config = config_->getFailoverPeerConfig();
2503 bool reset_successful =
true;
2505 asyncSendHAReset(client, remote_config,
2506 [&](
const bool success,
const std::string&,
const int) {
2508 reset_successful = success;
2514 return (reset_successful);
2518HAService::processScopes(
const std::vector<std::string>& scopes) {
2520 query_filter_.serveScopes(scopes);
2521 adjustNetworkState();
2523 }
catch (
const std::exception& ex) {
2531HAService::processContinue() {
2539HAService::processMaintenanceNotify(
const bool cancel) {
2543 " maintenance for the server not in the"
2544 " in-maintenance state."));
2547 postNextEvent(HA_MAINTENANCE_CANCEL_EVT);
2548 verboseTransition(getPrevState());
2553 switch (getCurrState()) {
2563 return (
createAnswer(HA_CONTROL_RESULT_MAINTENANCE_NOT_ALLOWED,
2564 "Unable to transition the server from the "
2566 " in-maintenance state."));
2569 runModel(HA_MAINTENANCE_NOTIFY_EVT);
2575HAService::processMaintenanceStart() {
2576 switch (getCurrState()) {
2583 " partner-in-maintenance state."));
2593 (HttpRequest::Method::HTTP_POST,
"/", HttpVersion::HTTP_11(),
2595 remote_config->addBasicAuthHttpHeader(request);
2596 request->setBodyAsJson(CommandCreator::createMaintenanceNotify(
false, server_type_));
2597 request->finalize();
2606 boost::system::error_code captured_ec;
2607 std::string captured_error_message;
2608 int captured_rcode = 0;
2612 remote_config->getTlsContext(),
2614 [
this, remote_config, &io_service, &captured_ec, &captured_error_message,
2616 (
const boost::system::error_code& ec,
2618 const std::string& error_str) {
2628 std::string error_message;
2631 if (ec || !error_str.empty()) {
2632 error_message = (ec ? ec.message() : error_str);
2633 LOG_ERROR(ha_logger, HA_MAINTENANCE_NOTIFY_COMMUNICATIONS_FAILED)
2634 .arg(remote_config->getLogLabel())
2635 .arg(error_message);
2641 static_cast<void>(verifyAsyncResponse(response, captured_rcode));
2643 } catch (
const std::exception& ex) {
2644 error_message = ex.what();
2646 .arg(remote_config->getLogLabel())
2647 .arg(error_message);
2653 if (!error_message.empty()) {
2654 communication_state_->setPartnerState(
"unavailable");
2658 captured_error_message = error_message;
2661 std::bind(&HAService::clientConnectHandler,
this, ph::_1, ph::_2),
2662 std::bind(&HAService::clientHandshakeHandler,
this, ph::_1),
2663 std::bind(&HAService::clientCloseHandler,
this, ph::_1)
2673 postNextEvent(HA_MAINTENANCE_START_EVT);
2677 "Server is now in the partner-down state as its"
2678 " partner appears to be offline for maintenance."));
2684 postNextEvent(HA_MAINTENANCE_START_EVT);
2692 " partner-in-maintenance state. The partner server responded"
2693 " with the following message to the ha-maintenance-notify"
2694 " command: " + captured_error_message +
"."));
2699 "Server is now in the partner-in-maintenance state"
2700 " and its partner is in-maintenance state. The partner"
2701 " can be now safely shut down."));
2705HAService::processMaintenanceCancel() {
2708 " request because the server is not in the"
2709 " partner-in-maintenance state."));
2717 (HttpRequest::Method::HTTP_POST,
"/", HttpVersion::HTTP_11(),
2719 remote_config->addBasicAuthHttpHeader(request);
2720 request->setBodyAsJson(CommandCreator::createMaintenanceNotify(
true, server_type_));
2721 request->finalize();
2730 std::string error_message;
2734 remote_config->getTlsContext(),
2736 [
this, remote_config, &io_service, &error_message]
2737 (
const boost::system::error_code& ec,
2739 const std::string& error_str) {
2744 if (ec || !error_str.empty()) {
2745 error_message = (ec ? ec.message() : error_str);
2746 LOG_ERROR(ha_logger, HA_MAINTENANCE_NOTIFY_CANCEL_COMMUNICATIONS_FAILED)
2747 .arg(remote_config->getLogLabel())
2748 .arg(error_message);
2755 static_cast<void>(verifyAsyncResponse(response, rcode));
2757 } catch (
const std::exception& ex) {
2758 error_message = ex.what();
2760 .arg(remote_config->getLogLabel())
2761 .arg(error_message);
2767 if (!error_message.empty()) {
2768 communication_state_->setPartnerState(
"unavailable");
2772 std::bind(&HAService::clientConnectHandler,
this, ph::_1, ph::_2),
2773 std::bind(&HAService::clientHandshakeHandler,
this, ph::_1),
2774 std::bind(&HAService::clientCloseHandler,
this, ph::_1)
2783 if (!error_message.empty()) {
2785 "Unable to cancel maintenance. The partner server responded"
2786 " with the following message to the ha-maintenance-notify"
2787 " command: " + error_message +
"."));
2792 postNextEvent(HA_MAINTENANCE_CANCEL_EVT);
2793 verboseTransition(getPrevState());
2797 "Server maintenance successfully canceled."));
2802 const std::string& server_name,
2808 (HttpRequest::Method::HTTP_POST,
"/", HttpVersion::HTTP_11(),
2811 remote_config->addBasicAuthHttpHeader(request);
2812 request->setBodyAsJson(CommandCreator::createSyncCompleteNotify(server_type_));
2813 request->finalize();
2821 remote_config->getTlsContext(),
2823 [
this, remote_config, post_request_action]
2824 (
const boost::system::error_code& ec,
2826 const std::string& error_str) {
2835 std::string error_message;
2838 if (ec || !error_str.empty()) {
2839 error_message = (ec ? ec.message() : error_str);
2840 LOG_ERROR(ha_logger, HA_SYNC_COMPLETE_NOTIFY_COMMUNICATIONS_FAILED)
2841 .arg(remote_config->getLogLabel())
2842 .arg(error_message);
2848 static_cast<void>(verifyAsyncResponse(response, rcode));
2850 } catch (
const CommandUnsupportedError& ex) {
2853 }
catch (
const std::exception& ex) {
2854 error_message = ex.what();
2856 .arg(remote_config->getLogLabel())
2857 .arg(error_message);
2863 if (!error_message.empty()) {
2864 communication_state_->setPartnerState(
"unavailable");
2868 if (post_request_action) {
2869 post_request_action(error_message.empty(),
2875 std::bind(&HAService::clientConnectHandler,
this, ph::_1, ph::_2),
2876 std::bind(&HAService::clientHandshakeHandler,
this, ph::_1),
2877 std::bind(&HAService::clientCloseHandler,
this, ph::_1)
2882HAService::processSyncCompleteNotify() {
2884 sync_complete_notified_ =
true;
2886 localEnableDHCPService();
2889 "Server successfully notified about the synchronization completion."));
2898 boost::dynamic_pointer_cast<HttpResponseJson>(response);
2899 if (!json_response) {
2910 if (body->getType() != Element::list) {
2912 if (body->getType() == Element::map) {
2928 if (body->empty()) {
2937 std::ostringstream s;
2939 if (args && args->getType() == Element::string) {
2940 s << args->stringValue() <<
", ";
2943 s <<
"error code " << rcode;
2946 isc_throw(CommandUnsupportedError, s.str());
2956HAService::clientConnectHandler(
const boost::system::error_code& ec,
int tcp_native_fd) {
2960 if (client_->getThreadIOService()) {
2968 if ((!ec || (ec.value() == boost::asio::error::in_progress))
2969 && (tcp_native_fd >= 0)) {
2974 IfaceMgr::instance().addExternalSocket(tcp_native_fd,
2975 std::bind(&HAService::socketReadyHandler,
this, ph::_1)
2987HAService::socketReadyHandler(
int tcp_native_fd) {
2992 client_->closeIfOutOfBand(tcp_native_fd);
2996HAService::clientCloseHandler(
int tcp_native_fd) {
2997 if (tcp_native_fd >= 0) {
2998 IfaceMgr::instance().deleteExternalSocket(tcp_native_fd);
3003HAService::pendingRequestSize() {
3004 if (MultiThreadingMgr::instance().getMode()) {
3005 std::lock_guard<std::mutex> lock(mutex_);
3006 return (pending_requests_.size());
3008 return (pending_requests_.size());
3012template<
typename QueryPtrType>
3014HAService::getPendingRequest(
const QueryPtrType& query) {
3015 if (MultiThreadingMgr::instance().getMode()) {
3016 std::lock_guard<std::mutex> lock(mutex_);
3017 return (getPendingRequestInternal(query));
3019 return (getPendingRequestInternal(query));
3023template<
typename QueryPtrType>
3025HAService::getPendingRequestInternal(
const QueryPtrType& query) {
3026 if (pending_requests_.count(query) == 0) {
3029 return (pending_requests_[query]);
3034HAService::checkPermissionsClientAndListener() {
3042 client_->checkPermissions();
3046 listener_->checkPermissions();
3054 }
catch (
const std::exception& ex) {
3061HAService::startClientAndListener() {
3063 MultiThreadingMgr::instance().addCriticalSectionCallbacks(
"HA_MT",
3064 std::bind(&HAService::checkPermissionsClientAndListener,
this),
3065 std::bind(&HAService::pauseClientAndListener,
this),
3066 std::bind(&HAService::resumeClientAndListener,
this));
3078HAService::pauseClientAndListener() {
3089 }
catch (
const std::exception& ex) {
3096HAService::resumeClientAndListener() {
3105 listener_->resume();
3107 }
catch (std::exception& ex) {
3114HAService::stopClientAndListener() {
3116 MultiThreadingMgr::instance().removeCriticalSectionCallbacks(
"HA_MT");
3128template int HAService::getPendingRequest(
const Pkt4Ptr&);
3129template int HAService::getPendingRequest(
const Pkt6Ptr&);
virtual const char * what() const
Returns a C-style character string of the cause of the exception.
Exception thrown when a worker thread is trying to stop or pause the respective thread pool (which wo...
A generic exception that is thrown when an unexpected error condition occurs.
The IOAddress class represents an IP addresses (version agnostic)
The IOService class is a wrapper for the ASIO io_service class.
void run()
Start the underlying event loop.
void stop()
Stop the underlying event loop.
A multi-threaded HTTP listener that can process API commands requests.
A standard control channel exception that is thrown if a function is there is a problem with one of t...
static data::ConstElementPtr createLease4Delete(const dhcp::Lease4 &lease4)
Creates lease4-del command.
static data::ConstElementPtr createLease4Update(const dhcp::Lease4 &lease4)
Creates lease4-update command.
static data::ConstElementPtr createLease6BulkApply(const dhcp::Lease6CollectionPtr &leases, const dhcp::Lease6CollectionPtr &deleted_leases)
Creates lease6-bulk-apply command.
Holds communication state between DHCPv4 servers.
Holds communication state between DHCPv6 servers.
Role
Server's role in the High Availability setup.
static std::string roleToString(const HAConfig::PeerConfig::Role &role)
Returns role name.
std::map< std::string, PeerConfigPtr > PeerConfigMap
Map of the servers' configurations.
static std::string HAModeToString(const HAMode &ha_mode)
Returns HA mode name.
boost::shared_ptr< PeerConfig > PeerConfigPtr
Pointer to the server's configuration.
static const int HA_MAINTENANCE_START_EVT
ha-maintenance-start command received.
bool inScope(dhcp::Pkt4Ptr &query4)
Checks if the DHCPv4 query should be processed by this server.
void adjustNetworkState()
Enables or disables network state depending on the served scopes.
void stopClientAndListener()
Stop the client and(or) listener instances.
int getNormalState() const
Returns normal operation state for the current configuration.
bool shouldQueueLeaseUpdates(const HAConfig::PeerConfigPtr &peer_config) const
Checks if the lease updates should be queued.
static const int HA_HEARTBEAT_COMPLETE_EVT
Finished heartbeat command.
bool isMaintenanceCanceled() const
Convenience method checking if the current state is a result of canceling the maintenance.
void asyncSendLeaseUpdate(const QueryPtrType &query, const HAConfig::PeerConfigPtr &config, const data::ConstElementPtr &command, const hooks::ParkingLotHandlePtr &parking_lot)
Asynchronously sends lease update to the peer.
void verboseTransition(const unsigned state)
Transitions to a desired state and logs it.
bool sendLeaseUpdatesFromBacklog()
Attempts to send all lease updates from the backlog synchronously.
config::CmdHttpListenerPtr listener_
HTTP listener instance used to receive and respond to HA commands and lease updates.
bool leaseUpdateComplete(QueryPtrType &query, const hooks::ParkingLotHandlePtr &parking_lot)
Handle last pending request for this query.
HAConfigPtr config_
Pointer to the HA hooks library configuration.
bool shouldTerminate() const
Indicates if the server should transition to the terminated state as a result of high clock skew.
void terminatedStateHandler()
Handler for "terminated" state.
dhcp::NetworkStatePtr network_state_
Pointer to the state of the DHCP service (enabled/disabled).
HAService(const asiolink::IOServicePtr &io_service, const dhcp::NetworkStatePtr &network_state, const HAConfigPtr &config, const HAServerType &server_type=HAServerType::DHCPv4)
Constructor.
void scheduleHeartbeat()
Schedules asynchronous heartbeat to a peer if it is not scheduled.
void passiveBackupStateHandler()
Handler for "passive-backup" state.
QueryFilter query_filter_
Selects queries to be processed/dropped.
static const int HA_MAINTENANCE_NOTIFY_EVT
ha-maintenance-notify command received.
static const int HA_SYNCED_PARTNER_UNAVAILABLE_EVT
The heartbeat command failed after receiving ha-sync-complete-notify command from the partner.
void inMaintenanceStateHandler()
Handler for the "in-maintenance" state.
virtual void verifyEvents()
Verifies events used by the HA service.
void conditionalLogPausedState() const
Logs if the server is paused in the current state.
bool unpause()
Unpauses the HA state machine with logging.
static const int HA_CONTROL_RESULT_MAINTENANCE_NOT_ALLOWED
Control result returned in response to ha-maintenance-notify.
void serveDefaultScopes()
Instructs the HA service to serve default scopes.
size_t asyncSendLeaseUpdates(const dhcp::Pkt4Ptr &query, const dhcp::Lease4CollectionPtr &leases, const dhcp::Lease4CollectionPtr &deleted_leases, const hooks::ParkingLotHandlePtr &parking_lot)
Schedules asynchronous IPv4 leases updates.
static const int HA_SYNCING_SUCCEEDED_EVT
Lease database synchronization succeeded.
bool sendHAReset()
Sends ha-reset command to partner synchronously.
std::function< void(const bool, const std::string &, const int)> PostRequestCallback
Callback invoked when request was sent and a response received or an error occurred.
virtual void defineEvents()
Defines events used by the HA service.
asiolink::IOServicePtr io_service_
Pointer to the IO service object shared between this hooks library and the DHCP server.
CommunicationStatePtr communication_state_
Holds communication state with a peer.
LeaseUpdateBacklog lease_update_backlog_
Backlog of DHCP lease updates.
virtual ~HAService()
Destructor.
static const int HA_SYNCING_FAILED_EVT
Lease database synchronization failed.
static const int HA_MAINTENANCE_CANCEL_EVT
ha-maintenance-cancel command received.
void readyStateHandler()
Handler for "ready" state.
virtual void defineStates()
Defines states of the HA service.
void backupStateHandler()
Handler for the "backup" state.
void communicationRecoveryHandler()
Handler for the "communication-recovery" state.
bool isPartnerStateInvalid() const
Indicates if the partner's state is invalid.
int synchronize(std::string &status_message, const std::string &server_name, const unsigned int max_period)
Synchronizes lease database with a partner.
void normalStateHandler()
Handler for the "hot-standby" and "load-balancing" states.
void waitingStateHandler()
Handler for "waiting" state.
bool shouldSendLeaseUpdates(const HAConfig::PeerConfigPtr &peer_config) const
Checks if the lease updates should be sent as result of leases allocation or release.
static const int HA_LEASE_UPDATES_COMPLETE_EVT
Finished lease updates commands.
void partnerDownStateHandler()
Handler for "partner-down" state.
http::HttpClientPtr client_
HTTP client instance used to send HA commands and lease updates.
void updatePendingRequest(QueryPtrType &query)
Update pending request counter for this query.
bool shouldPartnerDown() const
Indicates if the server should transition to the partner down state.
std::function< void(const bool, const std::string &, const bool)> PostSyncCallback
Callback invoked when lease database synchronization is complete.
void syncingStateHandler()
Handler for "syncing" state.
void partnerInMaintenanceStateHandler()
Handler for "partner-in-maintenance" state.
bool push(const OpType op_type, const dhcp::LeasePtr &lease)
Appends lease update to the queue.
OpType
Type of the lease update (operation type).
void clear()
Removes all lease updates from the queue.
bool wasOverflown()
Checks if the queue was overflown.
bool inScope(const dhcp::Pkt4Ptr &query4, std::string &scope_class) const
Checks if this server should process the DHCPv4 query.
void serveFailoverScopes()
Enable scopes required in failover case.
void serveDefaultScopes()
Serve default scopes for the given HA mode.
void serveNoScopes()
Disables all scopes.
void asyncSendRequest(const Url &url, const asiolink::TlsContextPtr &tls_context, const HttpRequestPtr &request, const HttpResponsePtr &response, const RequestHandler &request_callback, const RequestTimeout &request_timeout=RequestTimeout(10000), const ConnectHandler &connect_callback=ConnectHandler(), const HandshakeHandler &handshake_callback=HandshakeHandler(), const CloseHandler &close_callback=CloseHandler())
Queues new asynchronous HTTP request for a given URL.
This class parses and generates time values used in HTTP.
std::string rfc1123Format() const
Returns time value formatted as specified in RFC 1123.
const EventPtr & getEvent(unsigned int value)
Fetches the event referred to by value.
std::string getStateLabel(const int state) const
Fetches the label associated with an state value.
void unpauseModel()
Unpauses state model.
bool isModelPaused() const
Returns whether or not the model is paused.
void postNextEvent(unsigned int event)
Sets the next event to the given event value.
void defineState(unsigned int value, const std::string &label, StateHandler handler, const StatePausing &state_pausing=STATE_PAUSE_NEVER)
Adds an state value and associated label to the set of states.
bool doOnExit()
Checks if on exit flag is true.
unsigned int getNextEvent() const
Fetches the model's next event.
void defineEvent(unsigned int value, const std::string &label)
Adds an event value and associated label to the set of events.
void transition(unsigned int state, unsigned int event)
Sets up the model to transition into given state with a given event.
bool doOnEntry()
Checks if on entry flag is true.
static const int NOP_EVT
Signifies that no event has occurred.
void startModel(const int start_state)
Begins execution of the model.
unsigned int getLastEvent() const
Fetches the model's last event.
unsigned int getCurrState() const
Fetches the model's current state.
Utility class to measure code execution times.
void stop()
Stops the stopwatch.
std::string logFormatLastDuration() const
Returns the last measured duration in the format directly usable in log messages.
This file contains several functions and constants that are used for handling commands and responses ...
#define isc_throw(type, stream)
A shortcut macro to insert known values into exception arguments.
An abstract API for lease database.
#define LOG_ERROR(LOGGER, MESSAGE)
Macro to conveniently test error output and log it.
#define LOG_INFO(LOGGER, MESSAGE)
Macro to conveniently test info output and log it.
#define LOG_WARN(LOGGER, MESSAGE)
Macro to conveniently test warn output and log it.
boost::shared_ptr< IOService > IOServicePtr
Defines a smart pointer to an IOService instance.
const int CONTROL_RESULT_EMPTY
Status code indicating that the specified command was completed correctly, but failed to produce any ...
const char * CONTROL_TEXT
String used for storing textual description ("text")
constexpr long TIMEOUT_DEFAULT_HTTP_CLIENT_REQUEST
Timeout for the HTTP clients awaiting a response to a request.
const int CONTROL_RESULT_ERROR
Status code indicating a general failure.
const int CONTROL_RESULT_COMMAND_UNSUPPORTED
Status code indicating that the specified command is not supported.
ConstElementPtr createAnswer(const int status_code, const std::string &text, const ConstElementPtr &arg)
ConstElementPtr parseAnswer(int &rcode, const ConstElementPtr &msg)
const char * CONTROL_RESULT
String used for result, i.e. integer status ("result")
const int CONTROL_RESULT_SUCCESS
Status code indicating a successful operation.
boost::shared_ptr< const Element > ConstElementPtr
boost::shared_ptr< Element > ElementPtr
boost::shared_ptr< isc::dhcp::Pkt > PktPtr
A pointer to either Pkt4 or Pkt6 packet.
std::string ClientClass
Defines a single class name.
boost::shared_ptr< Lease4Collection > Lease4CollectionPtr
A shared pointer to the collection of IPv4 leases.
boost::shared_ptr< Pkt4 > Pkt4Ptr
A pointer to Pkt4 object.
boost::shared_ptr< Lease > LeasePtr
Pointer to the lease object.
boost::shared_ptr< NetworkState > NetworkStatePtr
Pointer to the NetworkState object.
boost::shared_ptr< Lease6Collection > Lease6CollectionPtr
A shared pointer to the collection of IPv6 leases.
boost::shared_ptr< Pkt6 > Pkt6Ptr
A pointer to Pkt6 packet.
boost::shared_ptr< Lease4 > Lease4Ptr
Pointer to a Lease4 structure.
const isc::log::MessageID HA_INVALID_PARTNER_STATE_LOAD_BALANCING
const isc::log::MessageID HA_RESUME_CLIENT_LISTENER_FAILED
const isc::log::MessageID HA_LOCAL_DHCP_ENABLE
const isc::log::MessageID HA_LEASES_BACKLOG_NOTHING_TO_SEND
const isc::log::MessageID HA_LEASES_BACKLOG_FAILED
const isc::log::MessageID HA_SYNC_FAILED
const isc::log::MessageID HA_TERMINATED_RESTART_PARTNER
const int HA_PASSIVE_BACKUP_ST
In passive-backup state with a single active server and backup servers.
const int HA_HOT_STANDBY_ST
Hot standby state.
const isc::log::MessageID HA_INVALID_PARTNER_STATE_COMMUNICATION_RECOVERY
const isc::log::MessageID HA_LEASES_BACKLOG_SUCCESS
const int HA_COMMUNICATION_RECOVERY_ST
Communication recovery state.
const isc::log::MessageID HA_STATE_MACHINE_CONTINUED
isc::log::Logger ha_logger("ha-hooks")
const isc::log::MessageID HA_LEASES_SYNC_FAILED
const isc::log::MessageID HA_SYNC_SUCCESSFUL
const int HA_UNAVAILABLE_ST
Special state indicating that this server is unable to communicate with the partner.
const isc::log::MessageID HA_CONFIG_LEASE_UPDATES_DISABLED_REMINDER
const isc::log::MessageID HA_SERVICE_STARTED
const int HA_TERMINATED_ST
HA service terminated state.
const int HA_IN_MAINTENANCE_ST
In maintenance state.
const int HA_LOAD_BALANCING_ST
Load balancing state.
const isc::log::MessageID HA_DHCP_ENABLE_FAILED
const isc::log::MessageID HA_LEASE_UPDATE_DELETE_FAILED_ON_PEER
const isc::log::MessageID HA_LEASES_BACKLOG_START
const isc::log::MessageID HA_SYNC_START
const isc::log::MessageID HA_HEARTBEAT_FAILED
const int HA_PARTNER_DOWN_ST
Partner down state.
const isc::log::MessageID HA_LEASE_UPDATES_ENABLED
const isc::log::MessageID HA_INVALID_PARTNER_STATE_HOT_STANDBY
const isc::log::MessageID HA_STATE_MACHINE_PAUSED
const isc::log::MessageID HA_TERMINATED
const isc::log::MessageID HA_DHCP_DISABLE_FAILED
boost::shared_ptr< HAConfig > HAConfigPtr
Pointer to the High Availability configuration structure.
const isc::log::MessageID HA_MAINTENANCE_STARTED_IN_PARTNER_DOWN
const int HA_PARTNER_IN_MAINTENANCE_ST
Partner in-maintenance state.
const isc::log::MessageID HA_MAINTENANCE_NOTIFY_FAILED
const int HA_WAITING_ST
Server waiting state, i.e. waiting for another server to be ready.
HAServerType
Lists possible server types for which HA service is created.
const int HA_BACKUP_ST
Backup state.
const isc::log::MessageID HA_PAUSE_CLIENT_LISTENER_ILLEGAL
const isc::log::MessageID HA_PAUSE_CLIENT_LISTENER_FAILED
const isc::log::MessageID HA_MAINTENANCE_SHUTDOWN_SAFE
const isc::log::MessageID HA_MAINTENANCE_NOTIFY_CANCEL_FAILED
const isc::log::MessageID HA_LEASE_UPDATES_DISABLED
const isc::log::MessageID HA_LOCAL_DHCP_DISABLE
const int HA_SYNCING_ST
Synchronizing database state.
const isc::log::MessageID HA_RESET_FAILED
const isc::log::MessageID HA_STATE_TRANSITION
const isc::log::MessageID HA_CONFIG_LEASE_SYNCING_DISABLED_REMINDER
std::string stateToString(int state)
Returns state name.
const int HA_READY_ST
Server ready state, i.e. synchronized database, can enable DHCP service.
const isc::log::MessageID HA_SYNC_COMPLETE_NOTIFY_FAILED
const isc::log::MessageID HA_COMMUNICATION_INTERRUPTED
const isc::log::MessageID HA_MAINTENANCE_STARTED
const isc::log::MessageID HA_LEASE_UPDATE_CREATE_UPDATE_FAILED_ON_PEER
const isc::log::MessageID HA_LEASE_UPDATE_FAILED
const isc::log::MessageID HA_STATE_TRANSITION_PASSIVE_BACKUP
boost::shared_ptr< ParkingLotHandle > ParkingLotHandlePtr
Pointer to the parking lot handle.
boost::shared_ptr< PostHttpRequestJson > PostHttpRequestJsonPtr
Pointer to PostHttpRequestJson.
boost::shared_ptr< HttpResponseJson > HttpResponseJsonPtr
Pointer to the HttpResponseJson object.
boost::shared_ptr< HttpResponse > HttpResponsePtr
Pointer to the HttpResponse object.
Defines the logger used by the top-level component of kea-lfc.
HTTP request/response timeout value.