Kea 2.7.5
ha_service.h
Go to the documentation of this file.
1// Copyright (C) 2018-2024 Internet Systems Consortium, Inc. ("ISC")
2//
3// This Source Code Form is subject to the terms of the Mozilla Public
4// License, v. 2.0. If a copy of the MPL was not distributed with this
5// file, You can obtain one at http://mozilla.org/MPL/2.0/.
6
7#ifndef HA_SERVICE_H
8#define HA_SERVICE_H
9
10#include <communication_state.h>
11#include <ha_config.h>
12#include <ha_server_type.h>
13#include <lease_sync_filter.h>
15#include <query_filter.h>
17#include <asiolink/io_service.h>
18#include <asiolink/tls_socket.h>
19#include <cc/data.h>
21#include <dhcp/pkt4.h>
22#include <http/response.h>
23#include <dhcpsrv/lease.h>
25#include <hooks/parking_lots.h>
26#include <http/client.h>
27#include <util/state_model.h>
28
29#include <boost/noncopyable.hpp>
30#include <boost/shared_ptr.hpp>
31#include <functional>
32#include <map>
33#include <mutex>
34#include <vector>
35
36namespace isc {
37namespace ha {
38
39class HAService;
40
42typedef HARelationshipMapper<HAService> HAServiceMapper;
43
45typedef boost::shared_ptr<HAServiceMapper> HAServiceMapperPtr;
46
52class HAService : public boost::noncopyable, public util::StateModel {
53public:
54
57
60
63
66
69
72
75
79
82
86
87protected:
88
95 typedef std::function<void(const bool, const std::string&, const int)> PostRequestCallback;
96
104 typedef std::function<void(const bool, const std::string&, const bool)> PostSyncCallback;
105
106public:
107
120 HAService(const unsigned int id,
121 const asiolink::IOServicePtr& io_service,
122 const dhcp::NetworkStatePtr& network_state,
123 const HAConfigPtr& config,
124 const HAServerType& server_type = HAServerType::DHCPv4);
125
130 virtual ~HAService();
131
134 return (server_type_);
135 }
136
137private:
138
143 unsigned int getLocalOrigin() const {
145 }
146
151 unsigned int getRemoteOrigin() const {
153 }
154
162 std::string getCSCallbacksSetName() const;
163
165 virtual void defineEvents();
166
168 virtual void verifyEvents();
169
171 virtual void defineStates();
172
185 void backupStateHandler();
186
214 void communicationRecoveryHandler();
215
244 void normalStateHandler();
245
255 void inMaintenanceStateHandler();
256
281 void partnerDownStateHandler();
282
303 void partnerInMaintenanceStateHandler();
304
312 void passiveBackupStateHandler();
313
329 void readyStateHandler();
330
347 void syncingStateHandler();
348
366 void terminatedStateHandler();
367
391 void waitingStateHandler();
392
395 int getPartnerState() const {
396 return (communication_state_->getPartnerState());
397 }
398
399protected:
400
404 void verboseTransition(const unsigned state);
405
412 int getNormalState() const;
413
414public:
415
423 bool unpause();
424
425protected:
426
431 void conditionalLogPausedState() const;
432
433public:
434
439 void serveDefaultScopes();
440
445 void serveFailoverScopes();
446
460 bool inScope(dhcp::Pkt4Ptr& query4);
461
475 bool inScope(dhcp::Pkt6Ptr& query6);
476
477private:
478
492 template<typename QueryPtrType>
493 bool inScopeInternal(QueryPtrType& query);
494
495public:
496
501 void adjustNetworkState();
502
503protected:
504
518 bool shouldPartnerDown() const;
519
538 bool shouldTerminate() const;
539
544 bool isMaintenanceCanceled() const;
545
561 bool isPartnerStateInvalid() const;
562
563public:
564
598 size_t asyncSendLeaseUpdates(const dhcp::Pkt4Ptr& query,
599 const dhcp::Lease4CollectionPtr& leases,
600 const dhcp::Lease4CollectionPtr& deleted_leases,
601 const hooks::ParkingLotHandlePtr& parking_lot);
602
619 size_t asyncSendSingleLeaseUpdate(const dhcp::Pkt4Ptr& query,
620 const dhcp::Lease4Ptr& lease,
621 const hooks::ParkingLotHandlePtr& parking_lot);
622
641 size_t asyncSendLeaseUpdates(const dhcp::Pkt6Ptr& query,
642 const dhcp::Lease6CollectionPtr& leases,
643 const dhcp::Lease6CollectionPtr& deleted_leases,
644 const hooks::ParkingLotHandlePtr& parking_lot);
645
646protected:
647
660 template<typename QueryPtrType>
661 void asyncSendLeaseUpdate(const QueryPtrType& query,
662 const HAConfig::PeerConfigPtr& config,
663 const data::ConstElementPtr& command,
664 const hooks::ParkingLotHandlePtr& parking_lot);
665
675 void logFailedLeaseUpdates(const dhcp::PktPtr& query,
676 const data::ConstElementPtr& args) const;
677
688 bool shouldSendLeaseUpdates(const HAConfig::PeerConfigPtr& peer_config) const;
689
701 bool shouldQueueLeaseUpdates(const HAConfig::PeerConfigPtr& peer_config) const;
702
703public:
704
730
736
750
751protected:
752
754 void asyncSendHeartbeat();
755
761 void scheduleHeartbeat();
762
764 void startHeartbeat();
765
777 void asyncDisableDHCPService(http::HttpClient& http_client,
778 const HAConfig::PeerConfigPtr& remote_config,
779 const unsigned int max_period,
780 PostRequestCallback post_request_action);
781
791 void asyncEnableDHCPService(http::HttpClient& http_client,
792 const HAConfig::PeerConfigPtr& remote_config,
793 PostRequestCallback post_request_action);
794
797
800
816 void asyncSyncLeases();
817
868 void asyncSyncLeases(http::HttpClient& http_client,
869 const HAConfig::PeerConfigPtr& remote_config,
870 const unsigned int max_period,
871 const dhcp::LeasePtr& last_lease,
872 PostSyncCallback post_sync_action,
873 const bool dhcp_disabled = false);
874
901 void asyncSyncLeasesInternal(http::HttpClient& http_client,
902 const HAConfig::PeerConfigPtr& remote_config,
903 const unsigned int max_period,
904 const dhcp::LeasePtr& last_lease,
905 PostSyncCallback post_sync_action,
906 const bool dhcp_disabled);
907
908public:
909
929 data::ConstElementPtr processSynchronize(const std::string& server_name,
930 const unsigned int max_period);
931
932protected:
933
954 int synchronize(std::string& status_message,
955 const HAConfig::PeerConfigPtr& remote_config,
956 const unsigned int max_period);
957
976 void asyncSendLeaseUpdatesFromBacklog(http::HttpClient& http_client,
977 const HAConfig::PeerConfigPtr& remote_config,
978 PostRequestCallback post_request_action);
979
994
1001 void asyncSendHAReset(http::HttpClient& http_client,
1002 const HAConfig::PeerConfigPtr& remote_config,
1003 PostRequestCallback post_request_action);
1004
1017 bool sendHAReset();
1018
1019public:
1020
1026 data::ConstElementPtr processScopes(const std::vector<std::string>& scopes);
1027
1032
1054
1072
1089
1096
1097protected:
1098
1108 void asyncSyncCompleteNotify(http::HttpClient& http_client,
1109 const HAConfig::PeerConfigPtr& remote_config,
1110 PostRequestCallback post_request_action);
1111
1112public:
1113
1127 data::ConstElementPtr processSyncCompleteNotify(const unsigned int origin_id);
1128
1137
1145
1153
1159 void stopClientAndListener();
1160
1161protected:
1162
1178 int& rcode);
1179
1189 bool clientConnectHandler(const boost::system::error_code& ec, int tcp_native_fd);
1190
1196 bool clientHandshakeHandler(const boost::system::error_code&) {
1197 return (true);
1198 }
1199
1216 void socketReadyHandler(int tcp_native_fd);
1217
1225 void clientCloseHandler(int tcp_native_fd);
1226
1228 unsigned int id_;
1229
1233
1236
1239
1242
1245
1249
1252
1255
1258
1275 template<typename QueryPtrType>
1276 bool leaseUpdateComplete(QueryPtrType& query,
1277 const hooks::ParkingLotHandlePtr& parking_lot);
1278
1284 template<typename QueryPtrType>
1285 void updatePendingRequest(QueryPtrType& query);
1286
1291 size_t pendingRequestSize();
1292
1302 template<typename QueryPtrType>
1303 int getPendingRequest(const QueryPtrType& query);
1304
1305private:
1324 template<typename QueryPtrType>
1325 bool leaseUpdateCompleteInternal(QueryPtrType& query,
1326 const hooks::ParkingLotHandlePtr& parking_lot);
1327
1335 template<typename QueryPtrType>
1336 void updatePendingRequestInternal(QueryPtrType& query);
1337
1348 template<typename QueryPtrType>
1349 int getPendingRequestInternal(const QueryPtrType& query);
1350
1352 std::mutex mutex_;
1353
1362 std::map<boost::shared_ptr<dhcp::Pkt>, int> pending_requests_;
1363
1364protected:
1365
1372
1381};
1382
1384typedef boost::shared_ptr<HAService> HAServicePtr;
1385
1386} // end of namespace isc::ha
1387} // end of namespace isc
1388
1389#endif
static const unsigned int HA_LOCAL_COMMAND
The network state is being altered by an HA internal command.
static const unsigned int HA_REMOTE_COMMAND
The network state is being altered by a "dhcp-disable" or "dhcp-enable" command sent by a HA partner.
boost::shared_ptr< PeerConfig > PeerConfigPtr
Pointer to the server's configuration.
Definition ha_config.h:242
High availability service.
Definition ha_service.h:52
static const int HA_MAINTENANCE_START_EVT
ha-maintenance-start command received.
Definition ha_service.h:71
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.
Definition ha_service.h:56
std::function< void(const bool, const std::string &, const bool) PostSyncCallback)
Callback invoked when lease database synchronization is complete.
Definition ha_service.h:104
void asyncSendHAReset(http::HttpClient &http_client, const HAConfig::PeerConfigPtr &remote_config, PostRequestCallback post_request_action)
Sends ha-reset command to partner asynchronously.
bool clientConnectHandler(const boost::system::error_code &ec, int tcp_native_fd)
HttpClient connect callback handler.
void asyncSyncLeases()
Asynchronously reads leases from a peer and updates local lease database.
bool isMaintenanceCanceled() const
Convenience method checking if the current state is a result of canceling the maintenance.
data::ConstElementPtr processMaintenanceCancel()
Processes ha-maintenance-cancel command and returns a response.
void checkPermissionsClientAndListener()
Check client and(or) listener current thread permissions to perform thread pool state transition.
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.
void clientCloseHandler(int tcp_native_fd)
HttpClient close callback handler.
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.
data::ConstElementPtr processMaintenanceStart()
Processes ha-maintenance-start command and returns a response.
unsigned int id_
Unique service id.
HAServerType server_type_
DHCP server type.
bool sync_complete_notified_
An indicator that a partner sent ha-sync-complete-notify command.
bool shouldTerminate() const
Indicates if the server should transition to the terminated state.
data::ConstElementPtr processScopes(const std::vector< std::string > &scopes)
Processes ha-scopes command and returns a response.
dhcp::NetworkStatePtr network_state_
Pointer to the state of the DHCP service (enabled/disabled).
data::ConstElementPtr processSynchronize(const std::string &server_name, const unsigned int max_period)
Processes ha-sync command and returns a response.
void scheduleHeartbeat()
Schedules asynchronous heartbeat to a peer if it is not scheduled.
void asyncSyncCompleteNotify(http::HttpClient &http_client, const HAConfig::PeerConfigPtr &remote_config, PostRequestCallback post_request_action)
Schedules asynchronous "ha-sync-complete-notify" command to the specified server.
QueryFilter query_filter_
Selects queries to be processed/dropped.
static const int HA_MAINTENANCE_NOTIFY_EVT
ha-maintenance-notify command received.
Definition ha_service.h:68
static const int HA_SYNCED_PARTNER_UNAVAILABLE_EVT
The heartbeat command failed after receiving ha-sync-complete-notify command from the partner.
Definition ha_service.h:78
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.
Definition ha_service.h:81
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.
size_t pendingRequestSize()
Get the number of entries in the pending request map.
static const int HA_SYNCING_SUCCEEDED_EVT
Lease database synchronization succeeded.
Definition ha_service.h:65
bool sendHAReset()
Sends ha-reset command to partner synchronously.
asiolink::IOServicePtr io_service_
Pointer to the IO service object shared between this hooks library and the DHCP server.
void localDisableDHCPService()
Disables local DHCP service.
CommunicationStatePtr communication_state_
Holds communication state with a peer.
void logFailedLeaseUpdates(const dhcp::PktPtr &query, const data::ConstElementPtr &args) const
Log failed lease updates.
bool clientHandshakeHandler(const boost::system::error_code &)
HttpClient handshake callback handler.
LeaseUpdateBacklog lease_update_backlog_
Backlog of DHCP lease updates.
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.
Definition ha_service.h:95
virtual ~HAService()
Destructor.
static const int HA_SYNCING_FAILED_EVT
Lease database synchronization failed.
Definition ha_service.h:62
static const int HA_MAINTENANCE_CANCEL_EVT
ha-maintenance-cancel command received.
Definition ha_service.h:74
void asyncSendLeaseUpdatesFromBacklog(http::HttpClient &http_client, const HAConfig::PeerConfigPtr &remote_config, PostRequestCallback post_request_action)
Sends lease updates from backlog to partner asynchronously.
data::ConstElementPtr processHeartbeat()
Processes ha-heartbeat command and returns a response.
void asyncSyncLeasesInternal(http::HttpClient &http_client, const HAConfig::PeerConfigPtr &remote_config, const unsigned int max_period, const dhcp::LeasePtr &last_lease, PostSyncCallback post_sync_action, const bool dhcp_disabled)
Implements fetching one page of leases during synchronization.
data::ConstElementPtr processHAReset()
Processes ha-reset command and returns a response.
size_t asyncSendSingleLeaseUpdate(const dhcp::Pkt4Ptr &query, const dhcp::Lease4Ptr &lease, const hooks::ParkingLotHandlePtr &parking_lot)
Schedules an asynchronous IPv4 lease update.
void asyncSendHeartbeat()
Starts asynchronous heartbeat to a peer.
bool isPartnerStateInvalid() const
Indicates if the partner's state is invalid.
void startClientAndListener()
Start the client and(or) listener instances.
data::ConstElementPtr verifyAsyncResponse(const http::HttpResponsePtr &response, int &rcode)
Checks if the response is valid or contains an error.
void resumeClientAndListener()
Resumes client and(or) listener thread pool operations.
data::ConstElementPtr processStatusGet() const
Processes status-get command and returns a response.
int getPendingRequest(const QueryPtrType &query)
Get the number of scheduled requests for a given query.
LeaseSyncFilter lease_sync_filter_
Lease synchronization filter used in hub-and-spoke model.
int synchronize(std::string &status_message, const HAConfig::PeerConfigPtr &remote_config, const unsigned int max_period)
Synchronizes lease database with a partner.
bool shouldSendLeaseUpdates(const HAConfig::PeerConfigPtr &peer_config) const
Checks if the lease updates should be sent as result of leases allocation or release.
void serveFailoverScopes()
Instructs the HA service to serve failover scopes.
void localEnableDHCPService()
Enables local DHCP service.
static const int HA_LEASE_UPDATES_COMPLETE_EVT
Finished lease updates commands.
Definition ha_service.h:59
HAService(const unsigned int id, const asiolink::IOServicePtr &io_service, const dhcp::NetworkStatePtr &network_state, const HAConfigPtr &config, const HAServerType &server_type=HAServerType::DHCPv4)
Constructor.
Definition ha_service.cc:76
HAServerType getServerType() const
Returns HA server type used in object construction.
Definition ha_service.h:133
void socketReadyHandler(int tcp_native_fd)
IfaceMgr external socket ready callback handler.
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.
void startHeartbeat()
Unconditionally starts one heartbeat to a peer.
data::ConstElementPtr processSyncCompleteNotify(const unsigned int origin_id)
Process ha-sync-complete-notify command and returns a response.
data::ConstElementPtr processContinue()
Processes ha-continue command and returns a response.
void asyncDisableDHCPService(http::HttpClient &http_client, const HAConfig::PeerConfigPtr &remote_config, const unsigned int max_period, PostRequestCallback post_request_action)
Schedules asynchronous "dhcp-disable" command to the specified server.
void pauseClientAndListener()
Pauses client and(or) listener thread pool operations.
data::ConstElementPtr processMaintenanceNotify(const bool cancel)
Processes ha-maintenance-notify command and returns a response.
static const int HA_WAITING_TO_TERMINATED_ST_DELAY_MINUTES
A delay in minutes to transition from the waiting to terminated state when the partner remains in ter...
Definition ha_service.h:85
void asyncEnableDHCPService(http::HttpClient &http_client, const HAConfig::PeerConfigPtr &remote_config, PostRequestCallback post_request_action)
Schedules asynchronous "dhcp-enable" command to the specified server.
Checks if a lease fetched from the other server should be synchronized into the local lease database.
Queue holding a backlog of unsent lease updates.
DHCP query filtering class.
Implements a finite state machine.
static const int SM_DERIVED_EVENT_MIN
Value at which custom events in a derived class should begin.
boost::shared_ptr< CmdHttpListener > CmdHttpListenerPtr
Defines a shared pointer to CmdHttpListener.
boost::shared_ptr< const Element > ConstElementPtr
Definition data.h:29
boost::shared_ptr< isc::dhcp::Pkt > PktPtr
A pointer to either Pkt4 or Pkt6 packet.
Definition pkt.h:998
boost::shared_ptr< Lease4Collection > Lease4CollectionPtr
A shared pointer to the collection of IPv4 leases.
Definition lease.h:503
boost::shared_ptr< Pkt4 > Pkt4Ptr
A pointer to Pkt4 object.
Definition pkt4.h:555
boost::shared_ptr< Lease > LeasePtr
Pointer to the lease object.
Definition lease.h:25
boost::shared_ptr< NetworkState > NetworkStatePtr
Pointer to the NetworkState object.
boost::shared_ptr< Lease6Collection > Lease6CollectionPtr
A shared pointer to the collection of IPv6 leases.
Definition lease.h:676
boost::shared_ptr< Pkt6 > Pkt6Ptr
A pointer to Pkt6 packet.
Definition pkt6.h:31
boost::shared_ptr< Lease4 > Lease4Ptr
Pointer to a Lease4 structure.
Definition lease.h:295
boost::shared_ptr< CommunicationState > CommunicationStatePtr
Type of the pointer to the CommunicationState object.
HARelationshipMapper< HAService > HAServiceMapper
Type of an object mapping HAService to relationships.
Definition ha_service.h:42
boost::shared_ptr< HAServiceMapper > HAServiceMapperPtr
Pointer to an object mapping HAService to relationships.
Definition ha_service.h:45
boost::shared_ptr< HAConfig > HAConfigPtr
Pointer to the High Availability configuration structure.
Definition ha_config.h:37
HAServerType
Lists possible server types for which HA service is created.
boost::shared_ptr< HAService > HAServicePtr
Pointer to the HAService class.
boost::shared_ptr< ParkingLotHandle > ParkingLotHandlePtr
Pointer to the parking lot handle.
boost::shared_ptr< HttpClient > HttpClientPtr
Defines a pointer to an HttpClient instance.
Definition client.h:339
boost::shared_ptr< HttpResponse > HttpResponsePtr
Pointer to the HttpResponse object.
Definition response.h:81
Defines the logger used by the top-level component of kea-lfc.
This file defines the class StateModel.