30 std::array<uint8_t, 256> loadb_mx_tbl = { {
31 251, 175, 119, 215, 81, 14, 79, 191, 103, 49, 181, 143, 186, 157, 0,
32 232, 31, 32, 55, 60, 152, 58, 17, 237, 174, 70, 160, 144, 220, 90, 57,
33 223, 59, 3, 18, 140, 111, 166, 203, 196, 134, 243, 124, 95, 222, 179,
34 197, 65, 180, 48, 36, 15, 107, 46, 233, 130, 165, 30, 123, 161, 209, 23,
35 97, 16, 40, 91, 219, 61, 100, 10, 210, 109, 250, 127, 22, 138, 29, 108,
36 244, 67, 207, 9, 178, 204, 74, 98, 126, 249, 167, 116, 34, 77, 193,
37 200, 121, 5, 20, 113, 71, 35, 128, 13, 182, 94, 25, 226, 227, 199, 75,
38 27, 41, 245, 230, 224, 43, 225, 177, 26, 155, 150, 212, 142, 218, 115,
39 241, 73, 88, 105, 39, 114, 62, 255, 192, 201, 145, 214, 168, 158, 221,
40 148, 154, 122, 12, 84, 82, 163, 44, 139, 228, 236, 205, 242, 217, 11,
41 187, 146, 159, 64, 86, 239, 195, 42, 106, 198, 118, 112, 184, 172, 87,
42 2, 173, 117, 176, 229, 247, 253, 137, 185, 99, 164, 102, 147, 45, 66,
43 231, 52, 141, 211, 194, 206, 246, 238, 56, 110, 78, 248, 63, 240, 189,
44 93, 92, 51, 53, 183, 19, 171, 72, 50, 33, 104, 101, 69, 8, 252, 83, 120,
45 76, 135, 85, 54, 202, 125, 188, 213, 96, 235, 136, 208, 162, 129, 190,
46 132, 156, 38, 47, 1, 7, 254, 24, 4, 216, 131, 89, 21, 28, 133, 37, 153,
47 149, 80, 170, 68, 6, 169, 234, 151 }
56 : config_(config), peers_(), scopes_(), active_servers_(0),
57 mutex_(new
std::mutex) {
65 std::vector<HAConfig::PeerConfigPtr> backup_peers;
69 for (
auto peer_pair = peers_map.begin(); peer_pair != peers_map.end(); ++peer_pair) {
70 auto peer = peer_pair->second;
89 backup_peers.push_back(peer);
94 if (!backup_peers.empty()) {
95 peers_.insert(
peers_.end(), backup_peers.begin(), backup_peers.end());
108 if (MultiThreadingMgr::instance().getMode()) {
109 std::lock_guard<std::mutex> lock(*
mutex_);
110 serveScopeInternal(scope_name);
112 serveScopeInternal(scope_name);
117 QueryFilter::serveScopeInternal(
const std::string& scope_name) {
124 if (MultiThreadingMgr::instance().getMode()) {
125 std::lock_guard<std::mutex> lock(*
mutex_);
126 serveScopeOnlyInternal(scope_name);
128 serveScopeOnlyInternal(scope_name);
133 QueryFilter::serveScopeOnlyInternal(
const std::string& scope_name) {
135 serveNoScopesInternal();
136 serveScopeInternal(scope_name);
141 if (MultiThreadingMgr::instance().getMode()) {
142 std::lock_guard<std::mutex> lock(*
mutex_);
143 serveScopesInternal(scopes);
145 serveScopesInternal(scopes);
150 QueryFilter::serveScopesInternal(
const std::vector<std::string>& scopes) {
155 serveNoScopesInternal();
156 for (
size_t i = 0; i < scopes.size(); ++i) {
157 serveScopeInternal(scopes[i]);
170 if (MultiThreadingMgr::instance().getMode()) {
171 std::lock_guard<std::mutex> lock(*
mutex_);
172 serveDefaultScopesInternal();
174 serveDefaultScopesInternal();
179 QueryFilter::serveDefaultScopesInternal() {
185 serveNoScopesInternal();
191 serveScopeInternal(my_config->getName());
197 if (MultiThreadingMgr::instance().getMode()) {
198 std::lock_guard<std::mutex> lock(*
mutex_);
199 serveFailoverScopesInternal();
201 serveFailoverScopesInternal();
206 QueryFilter::serveFailoverScopesInternal() {
208 serveNoScopesInternal();
212 for (
auto peer =
peers_.begin(); peer !=
peers_.end(); ++peer) {
221 serveScopeInternal((*peer)->getName());
228 if (MultiThreadingMgr::instance().getMode()) {
229 std::lock_guard<std::mutex> lock(*
mutex_);
230 serveNoScopesInternal();
232 serveNoScopesInternal();
237 QueryFilter::serveNoScopesInternal() {
241 for (
auto peer =
peers_.begin(); peer !=
peers_.end(); ++peer) {
242 scopes_[(*peer)->getName()] =
false;
248 if (MultiThreadingMgr::instance().getMode()) {
249 std::lock_guard<std::mutex> lock(*
mutex_);
250 return (amServingScopeInternal(scope_name));
252 return (amServingScopeInternal(scope_name));
257 QueryFilter::amServingScopeInternal(
const std::string& scope_name)
const {
258 auto scope =
scopes_.find(scope_name);
259 return ((scope ==
scopes_.end()) || (scope->second));
262 std::set<std::string>
264 if (MultiThreadingMgr::instance().getMode()) {
265 std::lock_guard<std::mutex> lock(*
mutex_);
266 return (getServedScopesInternal());
268 return (getServedScopesInternal());
272 std::set<std::string>
273 QueryFilter::getServedScopesInternal()
const {
274 std::set<std::string> scope_set;
277 scope_set.insert(scope.first);
285 if (MultiThreadingMgr::instance().getMode()) {
286 std::lock_guard<std::mutex> lock(*
mutex_);
287 return (inScopeInternal(query4, scope_class));
289 return (inScopeInternal(query4, scope_class));
295 if (MultiThreadingMgr::instance().getMode()) {
296 std::lock_guard<std::mutex> lock(*
mutex_);
297 return (inScopeInternal(query6, scope_class));
299 return (inScopeInternal(query6, scope_class));
303 template<
typename QueryPtrType>
305 QueryFilter::inScopeInternal(
const QueryPtrType& query,
306 std::string& scope_class)
const {
311 int candidate_server = 0;
319 if (candidate_server < 0) {
324 auto scope =
peers_[candidate_server]->getName();
326 return ((candidate_server >= 0) && amServingScopeInternal(scope));
335 if (opt_client_id && !opt_client_id->getData().empty()) {
336 const auto& client_id_key = opt_client_id->getData();
342 if (hwaddr && !hwaddr->hwaddr_.empty()) {
343 lb_hash =
loadBalanceHash(&hwaddr->hwaddr_[0], hwaddr->hwaddr_.size());
348 std::stringstream xid;
349 xid <<
"0x" << std::hex << query4->getTransid() << std::dec;
366 if (opt_duid && !opt_duid->getData().empty()) {
367 const auto& duid_key = opt_duid->getData();
372 std::stringstream xid;
373 xid <<
"0x" << std::hex << query6->getTransid() << std::dec;
386 uint8_t hash =
static_cast<uint8_t
>(key_len);
388 for (
auto i = key_len; i > 0;) {
389 hash = loadb_mx_tbl[hash ^ key[--i]];
399 static_cast<void>(
config_->getPeerConfig(scope_name));
403 <<
"' while enabling/disabling HA scopes");
409 return (std::string(
"HA_") + scope_name);
void serveScope(const std::string &scope_name)
Enable scope.
const int DBGLVL_TRACE_BASIC
Trace basic operations.
void serveNoScopes()
Disables all scopes.
std::map< std::string, PeerConfigPtr > PeerConfigMap
Map of the servers' configurations.
bool inScope(const dhcp::Pkt4Ptr &query4, std::string &scope_class) const
Checks if this server should process the DHCPv4 query.
std::string makeScopeClass(const std::string &scope_name) const
Returns scope class name for the specified scope name.
boost::shared_ptr< HWAddr > HWAddrPtr
Shared pointer to a hardware address structure.
boost::shared_ptr< Option > OptionPtr
std::set< std::string > getServedScopes() const
Returns served scopes.
int loadBalance(const dhcp::Pkt4Ptr &query4) const
Performs load balancing of the DHCPv4 queries.
std::vector< HAConfig::PeerConfigPtr > peers_
Vector of HA peers configurations.
void serveDefaultScopes()
Serve default scopes for the given HA mode.
#define isc_throw(type, stream)
A shortcut macro to insert known values into exception arguments.
A generic exception that is thrown if a parameter given to a method is considered invalid in that con...
boost::shared_ptr< Pkt6 > Pkt6Ptr
A pointer to Pkt6 packet.
std::map< std::string, bool > scopes_
Holds mapping of the scope names to the flag which indicates if the scopes are enabled or disabled...
void serveScopes(const std::vector< std::string > &scopes)
Enables selected scopes.
boost::scoped_ptr< std::mutex > mutex_
Mutex to protect the internal state.
boost::shared_ptr< Pkt4 > Pkt4Ptr
A pointer to Pkt4 object.
bool amServingScope(const std::string &scope_name) const
Checks if this server instance is configured to process traffic belonging to a particular scope...
void validateScopeName(const std::string &scope_name) const
Checks if the scope name matches a name of any of the configured servers.
void serveFailoverScopes()
Enable scopes required in failover case.
const isc::log::MessageID HA_LOAD_BALANCING_DUID_MISSING
Defines the logger used by the top-level component of kea-dhcp-ddns.
uint8_t loadBalanceHash(const uint8_t *key, const size_t key_len) const
Compute load balancing hash.
HAConfigPtr config_
Pointer to the HA configuration.
#define LOG_DEBUG(LOGGER, LEVEL, MESSAGE)
Macro to conveniently test debug output and log it.
void serveScopeOnly(const std::string &scope_name)
Enable scope and disable all other scopes.
isc::log::Logger ha_logger("ha-hooks")
Role
Server's role in the High Availability setup.
const isc::log::MessageID HA_LOAD_BALANCING_IDENTIFIER_MISSING
int active_servers_
Number of the active servers in the given HA mode.
boost::shared_ptr< HAConfig > HAConfigPtr
Pointer to the High Availability configuration structure.
boost::shared_ptr< PeerConfig > PeerConfigPtr
Pointer to the server's configuration.