Kea  1.9.9-git
communication_state.h
Go to the documentation of this file.
1 // Copyright (C) 2018-2021 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_COMMUNICATION_STATE_H
8 #define HA_COMMUNICATION_STATE_H
9 
10 #include <ha_config.h>
11 #include <ha_service_states.h>
13 #include <asiolink/io_service.h>
14 #include <cc/data.h>
15 #include <dhcp/pkt.h>
16 
17 #include <boost/date_time/posix_time/posix_time.hpp>
18 #include <boost/multi_index_container.hpp>
19 #include <boost/multi_index/composite_key.hpp>
20 #include <boost/multi_index/hashed_index.hpp>
21 #include <boost/multi_index/indexed_by.hpp>
22 #include <boost/multi_index/member.hpp>
23 #include <boost/multi_index/ordered_index.hpp>
24 #include <boost/scoped_ptr.hpp>
25 #include <boost/shared_ptr.hpp>
26 
27 #include <functional>
28 #include <map>
29 #include <mutex>
30 #include <set>
31 #include <string>
32 
33 namespace isc {
34 namespace ha {
35 
86 public:
87 
93  const HAConfigPtr& config);
94 
98  virtual ~CommunicationState();
99 
103  int getPartnerState() const;
104 
110  void setPartnerState(const std::string& state);
111 
112 private:
118  void setPartnerStateInternal(const std::string& state);
119 
120 public:
124  std::set<std::string> getPartnerScopes() const;
125 
129  void setPartnerScopes(data::ConstElementPtr new_scopes);
130 
131 private:
135  void setPartnerScopesInternal(data::ConstElementPtr new_scopes);
136 
137 public:
143  void startHeartbeat(const long interval,
144  const std::function<void()>& heartbeat_impl);
145 
147  void stopHeartbeat();
148 
149 private:
155  void startHeartbeatInternal(const long interval = 0,
156  const std::function<void()>& heartbeat_impl = 0);
157 
159  void stopHeartbeatInternal();
160 
161 public:
165  bool isHeartbeatRunning() const;
166 
172  void poke();
173 
174 private:
180  void pokeInternal();
181 
182 public:
186  int64_t getDurationInMillisecs() const;
187 
196  bool isCommunicationInterrupted() const;
197 
229  virtual void analyzeMessage(const boost::shared_ptr<dhcp::Pkt>& message) = 0;
230 
236  size_t getAnalyzedMessagesCount() const;
237 
252  virtual bool failureDetected() const = 0;
253 
262  virtual size_t getConnectingClientsCount() const = 0;
263 
272  virtual size_t getUnackedClientsCount() const = 0;
273 
274 protected:
275 
288  virtual void clearConnectingClients() = 0;
289 
290 public:
291 
314  bool clockSkewShouldWarn();
315 
316 private:
339  bool clockSkewShouldWarnInternal();
340 
341 public:
358  bool clockSkewShouldTerminate() const;
359 
360 private:
377  bool clockSkewShouldTerminateInternal() const;
378 
385  bool isClockSkewGreater(const long seconds) const;
386 
387 public:
388 
400  void setPartnerTime(const std::string& time_text);
401 
402 private:
414  void setPartnerTimeInternal(const std::string& time_text);
415 
416 public:
418  std::string logFormatClockSkew() const;
419 
420 private:
422  std::string logFormatClockSkewInternal() const;
423 
424 public:
432  data::ElementPtr getReport() const;
433 
441  void modifyPokeTime(const long secs);
442 
443 private:
444 
450  int64_t getDurationInMillisecsInternal() const;
451 
452 protected:
456  boost::posix_time::time_duration updatePokeTime();
457 
458 private:
464  boost::posix_time::time_duration updatePokeTimeInternal();
465 
466 protected:
469 
472 
475 
477  long interval_;
478 
480  boost::posix_time::ptime poke_time_;
481 
483  std::function<void()> heartbeat_impl_;
484 
489 
491  std::set<std::string> partner_scopes_;
492 
494  boost::posix_time::time_duration clock_skew_;
495 
498  boost::posix_time::ptime last_clock_skew_warn_;
499 
501  boost::posix_time::ptime my_time_at_skew_;
502 
504  boost::posix_time::ptime partner_time_at_skew_;
505 
508 
510  const boost::scoped_ptr<std::mutex> mutex_;
511 };
512 
514 typedef boost::shared_ptr<CommunicationState> CommunicationStatePtr;
515 
516 
523 public:
524 
530  const HAConfigPtr& config);
531 
546  virtual void analyzeMessage(const boost::shared_ptr<dhcp::Pkt>& message);
547 
553  virtual bool failureDetected() const;
554 
563  virtual size_t getConnectingClientsCount() const;
564 
573  virtual size_t getUnackedClientsCount() const;
574 
575 protected:
576 
593  virtual void analyzeMessageInternal(const boost::shared_ptr<dhcp::Pkt>& message);
594 
602  virtual bool failureDetectedInternal() const;
603 
609  virtual void clearConnectingClients();
610 
614  std::vector<uint8_t> hwaddr_;
615  std::vector<uint8_t> clientid_;
616  bool unacked_;
617  };
618 
621  typedef boost::multi_index_container<
623  boost::multi_index::indexed_by<
624  // First index is a composite index which allows to find a client
625  // by the HW address/client identifier tuple.
626  boost::multi_index::hashed_unique<
627  boost::multi_index::composite_key<
628  ConnectingClient4,
629  boost::multi_index::member<ConnectingClient4, std::vector<uint8_t>,
631  boost::multi_index::member<ConnectingClient4, std::vector<uint8_t>,
633  >
634  >,
635  // Second index allows for counting all clients which are
636  // considered unacked.
637  boost::multi_index::ordered_non_unique<
638  boost::multi_index::member<ConnectingClient4, bool, &ConnectingClient4::unacked_>
639  >
640  >
642 
647 };
648 
650 typedef boost::shared_ptr<CommunicationState4> CommunicationState4Ptr;
651 
658 public:
659 
665  const HAConfigPtr& config);
666 
675  virtual void analyzeMessage(const boost::shared_ptr<dhcp::Pkt>& message);
676 
682  virtual bool failureDetected() const;
683 
692  virtual size_t getConnectingClientsCount() const;
693 
702  virtual size_t getUnackedClientsCount() const;
703 
704 protected:
705 
716  virtual void analyzeMessageInternal(const boost::shared_ptr<dhcp::Pkt>& message);
717 
725  virtual bool failureDetectedInternal() const;
726 
732  virtual void clearConnectingClients();
733 
737  std::vector<uint8_t> duid_;
738  bool unacked_;
739  };
740 
743  typedef boost::multi_index_container<
745  boost::multi_index::indexed_by<
746  // First index is for accessing connecting clients by DUID.
747  boost::multi_index::hashed_unique<
748  boost::multi_index::member<ConnectingClient6, std::vector<uint8_t>,
750  >,
751  // Second index allows for counting all clients which are
752  // considered unacked.
753  boost::multi_index::ordered_non_unique<
754  boost::multi_index::member<ConnectingClient6, bool, &ConnectingClient6::unacked_>
755  >
756  >
758 
763 };
764 
766 typedef boost::shared_ptr<CommunicationState6> CommunicationState6Ptr;
767 
768 } // end of namespace isc::ha
769 } // end of namespace isc
770 
771 #endif
CommunicationState6(const asiolink::IOServicePtr &io_service, const HAConfigPtr &config)
Constructor.
boost::shared_ptr< CommunicationState6 > CommunicationState6Ptr
Pointer to the CommunicationState6 object.
virtual size_t getConnectingClientsCount() const =0
Returns the current number of clients which attempted to get a lease from the partner server...
virtual bool failureDetected() const
Checks if the partner failure has been detected based on the DHCP traffic analysis.
virtual void clearConnectingClients()=0
Removes information about the clients the partner server should respond to while communication with t...
bool isCommunicationInterrupted() const
Checks if communication with the partner is interrupted.
void setPartnerTime(const std::string &time_text)
Provide partner's notion of time so the new clock skew can be calculated.
Holds communication state between the two HA peers.
boost::shared_ptr< CommunicationState4 > CommunicationState4Ptr
Pointer to the CommunicationState4 object.
ConnectingClients4 connecting_clients_
Holds information about the clients attempting to contact the partner server while the servers are in...
virtual bool failureDetectedInternal() const
Checks if the partner failure has been detected based on the DHCP traffic analysis.
virtual size_t getUnackedClientsCount() const
Returns the current number of clients which haven't gotten a lease from the partner server...
boost::shared_ptr< Element > ElementPtr
Definition: data.h:20
std::function< void()> heartbeat_impl_
Pointer to the function providing heartbeat implementation.
asiolink::IOServicePtr io_service_
Pointer to the common IO service instance.
Structure holding information about a client which sent a packet being analyzed.
virtual void clearConnectingClients()
Removes information about the clients the partner server should respond to while communication with t...
virtual void analyzeMessageInternal(const boost::shared_ptr< dhcp::Pkt > &message)
Checks if the DHCPv6 message appears to be unanswered.
boost::multi_index_container< ConnectingClient6, boost::multi_index::indexed_by< boost::multi_index::hashed_unique< boost::multi_index::member< ConnectingClient6, std::vector< uint8_t >,&ConnectingClient6::duid_ > >, boost::multi_index::ordered_non_unique< boost::multi_index::member< ConnectingClient6, bool,&ConnectingClient6::unacked_ > > > > ConnectingClients6
Multi index container holding information about the clients attempting to get leases from the partner...
boost::posix_time::time_duration updatePokeTime()
Update the poke time and compute the duration.
boost::posix_time::ptime partner_time_at_skew_
Partner reported time when skew was calculated.
long interval_
Interval specified for the heartbeat.
boost::posix_time::ptime poke_time_
Last poke time.
Holds communication state between DHCPv4 servers.
virtual bool failureDetected() const
Checks if the partner failure has been detected based on the DHCP traffic analysis.
int getPartnerState() const
Returns last known state of the partner.
virtual void analyzeMessage(const boost::shared_ptr< dhcp::Pkt > &message)=0
Checks if the DHCP message appears to be unanswered.
void modifyPokeTime(const long secs)
Modifies poke time by adding seconds to it.
int partner_state_
Last known state of the partner server.
const boost::scoped_ptr< std::mutex > mutex_
The mutex used to protect internal state.
size_t getAnalyzedMessagesCount() const
Returns the number of analyzed messages while being in the communications interrupted state...
boost::shared_ptr< const Element > ConstElementPtr
Definition: data.h:23
virtual void analyzeMessage(const boost::shared_ptr< dhcp::Pkt > &message)
Checks if the DHCPv6 message appears to be unanswered.
std::set< std::string > getPartnerScopes() const
Returns scopes served by the partner server.
void stopHeartbeat()
Stops recurring heartbeat.
virtual size_t getUnackedClientsCount() const
Returns the current number of clients which haven't gotten a lease from the partner server...
virtual bool failureDetected() const =0
Checks if the partner failure has been detected based on the DHCP traffic analysis.
Defines the logger used by the top-level component of kea-dhcp-ddns.
bool clockSkewShouldTerminate() const
Indicates whether the HA service should enter "terminated" state as a result of the clock skew exceed...
void poke()
Pokes the communication state.
boost::posix_time::time_duration clock_skew_
Clock skew between the active servers.
CommunicationState4(const asiolink::IOServicePtr &io_service, const HAConfigPtr &config)
Constructor.
virtual void analyzeMessage(const boost::shared_ptr< dhcp::Pkt > &message)
Checks if the DHCPv4 message appears to be unanswered.
bool isHeartbeatRunning() const
Checks if recurring heartbeat is running.
virtual bool failureDetectedInternal() const
Checks if the partner failure has been detected based on the DHCP traffic analysis.
ConnectingClients6 connecting_clients_
Holds information about the clients attempting to contact the partner server while the servers are in...
data::ElementPtr getReport() const
Returns the report about current communication state.
boost::posix_time::ptime my_time_at_skew_
My time when skew was calculated.
void setPartnerState(const std::string &state)
Sets partner state.
void startHeartbeat(const long interval, const std::function< void()> &heartbeat_impl)
Starts recurring heartbeat (public interface).
std::set< std::string > partner_scopes_
Last known set of scopes served by the partner server.
virtual ~CommunicationState()
Destructor.
Structure holding information about the client which has send the packet being analyzed.
bool clockSkewShouldWarn()
Issues a warning about high clock skew between the active servers if one is warranted.
boost::posix_time::ptime last_clock_skew_warn_
Holds a time when last warning about too high clock skew was issued.
std::string logFormatClockSkew() const
Returns current clock skew value in the logger friendly format.
asiolink::IntervalTimerPtr timer_
Interval timer triggering heartbeat commands.
void setPartnerScopes(data::ConstElementPtr new_scopes)
Sets partner scopes.
int64_t getDurationInMillisecs() const
Returns duration between the poke time and current time.
virtual size_t getUnackedClientsCount() const =0
Returns the current number of clients which haven't got the lease from the partner server...
HAConfigPtr config_
High availability configuration.
virtual void clearConnectingClients()
Removes information about the clients the partner server should respond to while communication with t...
virtual size_t getConnectingClientsCount() const
Returns the current number of clients which attempted to get a lease from the partner server...
boost::shared_ptr< CommunicationState > CommunicationStatePtr
Type of the pointer to the CommunicationState object.
virtual void analyzeMessageInternal(const boost::shared_ptr< dhcp::Pkt > &message)
Checks if the DHCPv4 message appears to be unanswered.
boost::shared_ptr< HAConfig > HAConfigPtr
Pointer to the High Availability configuration structure.
Definition: ha_config.h:760
virtual size_t getConnectingClientsCount() const
Returns the current number of clients which attempted to get a lease from the partner server...
size_t analyzed_messages_count_
Total number of analyzed messages to be responded by partner.
boost::multi_index_container< ConnectingClient4, boost::multi_index::indexed_by< boost::multi_index::hashed_unique< boost::multi_index::composite_key< ConnectingClient4, boost::multi_index::member< ConnectingClient4, std::vector< uint8_t >,&ConnectingClient4::hwaddr_ >, boost::multi_index::member< ConnectingClient4, std::vector< uint8_t >,&ConnectingClient4::clientid_ > > >, boost::multi_index::ordered_non_unique< boost::multi_index::member< ConnectingClient4, bool,&ConnectingClient4::unacked_ > > > > ConnectingClients4
Multi index container holding information about the clients attempting to get leases from the partner...
Holds communication state between DHCPv6 servers.
CommunicationState(const asiolink::IOServicePtr &io_service, const HAConfigPtr &config)
Constructor.