Kea: query_filter.cc Source File

| Kea 3.2.0-git

query_filter.cc
Go to the documentation of this file.
1// Copyright (C) 2018-2025 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#include <config.h>
8
9#include <ha_log.h>
10#include <query_filter.h>
11#include <dhcp/dhcp4.h>
12#include <dhcp/dhcp6.h>
13#include <dhcp/option.h>
14#include <exceptions/exceptions.h>
15#include <util/multi_threading_mgr.h>
16
17#include <array>
18#include <iostream>
19#include <sstream>
20
21using namespace isc::dhcp;
22using namespace isc::log;
23using namespace isc::util;
24
25namespace {
26
30std::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 }
48};
49
51std::array<bool, DHCP_TYPES_EOF> v4_ha_types = {
52 false, // DHCP_NOTYPE = 0
53 true, // DHCPDISCOVER = 1
54 false, // DHCPOFFER = 2
55 true, // DHCPREQUEST = 3
56 true, // DHCPDECLINE = 4
57 false, // DHCPACK = 5
58 false, // DHCPNAK = 6
59 true, // DHCPRELEASE = 7
60 true, // DHCPINFORM = 8
61 false, // DHCPFORCERENEW = 9
62 false, // DHCPLEASEQUERY = 10
63 false, // DHCPLEASEUNASSIGNED = 11
64 false, // DHCPLEASEUNKNOWN = 12
65 false, // DHCPLEASEACTIVE = 13
66 false, // DHCPBULKLEASEQUERY = 14
67 false, // DHCPLEASEQUERYDONE = 15
68 false, // DHCPACTIVELEASEQUERY = 16
69 false, // DHCPLEASEQUERYSTATUS = 17
70 false // DHCPTLS = 18
71};
72
74std::array<bool, DHCPV6_TYPES_EOF> v6_ha_types = {
75 false, // DHCPV6_NOTYPE = 0
76 true, // DHCPV6_SOLICIT = 1
77 false, // DHCPV6_ADVERTISE = 2
78 true, // DHCPV6_REQUEST = 3
79 true, // DHCPV6_CONFIRM = 4
80 true, // DHCPV6_RENEW = 5
81 true, // DHCPV6_REBIND = 6
82 false, // DHCPV6_REPLY = 7
83 true, // DHCPV6_RELEASE = 8
84 true, // DHCPV6_DECLINE = 9
85 false, // DHCPV6_RECONFIGURE = 10
86 false, // DHCPV6_INFORMATION_REQUEST = 11
87 false, // DHCPV6_RELAY_FORW = 12
88 false, // DHCPV6_RELAY_REPL = 13
89 false, // DHCPV6_LEASEQUERY = 14
90 false, // DHCPV6_LEASEQUERY_REPLY = 15
91 false, // DHCPV6_LEASEQUERY_DONE = 16
92 false, // DHCPV6_LEASEQUERY_DATA = 17
93 false, // DHCPV6_RECONFIGURE_REQUEST = 18
94 false, // DHCPV6_RECONFIGURE_REPLY = 19
98 false, // DHCPV6_DHCPV4_QUERY = 20
99 false, // DHCPV6_DHCPV4_RESPONSE = 21
100 false, // DHCPV6_ACTIVELEASEQUERY = 22
101 false, // DHCPV6_STARTTLS = 23
102 false, // DHCPV6_BNDUPD = 24
103 false, // DHCPV6_BNDREPLY = 25
104 false, // DHCPV6_POOLREQ = 26
105 false, // DHCPV6_POOLRESP = 27
106 false, // DHCPV6_UPDREQ = 28
107 false, // DHCPV6_UPDREQALL = 29
108 false, // DHCPV6_UPDDONE = 30
109 false, // DHCPV6_CONNECT = 31
110 false, // DHCPV6_CONNECTREPLY = 32
111 false, // DHCPV6_DISCONNECT = 33
112 false, // DHCPV6_STATE = 34
113 false // DHCPV6_CONTACT = 35
114};
115
116} // end of anonymous namespace
117
118namespace isc {
119namespace ha {
120
121QueryFilter::QueryFilter(const HAConfigPtr& config)
122 : config_(config), peers_(), scopes_(), active_servers_(0),
123 mutex_(new std::mutex) {
124
125 // Make sure that the configuration is valid. We make certain
126 // assumptions about the availability of the servers' configurations
127 // in the config_ structure.
128 config_->validate();
129
130 HAConfig::PeerConfigMap peers_map = config->getAllServersConfig();
131 std::vector<HAConfig::PeerConfigPtr> backup_peers;
132
133 // The returned configurations are not ordered. Let's iterate over them
134 // and put them in the desired order.
135 for (auto const& peer_pair : peers_map) {
136 auto peer = peer_pair.second;
137 // The primary server is always first on the list.
138 if (peer->getRole() == HAConfig::PeerConfig::PRIMARY) {
139 peers_.insert(peers_.begin(), peer);
140 ++active_servers_;
141
142 // The secondary server is always behind the primary server.
143 } else if ((peer->getRole() == HAConfig::PeerConfig::SECONDARY) ||
144 (peer->getRole() == HAConfig::PeerConfig::STANDBY)) {
145 peers_.push_back(peer);
146
147 // If this is a secondary server, we're in the load balancing
148 // mode, in which case we have two active servers.
149 if (peer->getRole() == HAConfig::PeerConfig::SECONDARY) {
150 ++active_servers_;
151 }
152
153 // If this is neither primary nor secondary/standby, it is a backup.
154 } else {
155 backup_peers.push_back(peer);
156 }
157 }
158
159 // Append backup servers to the list.
160 if (!backup_peers.empty()) {
161 peers_.insert(peers_.end(), backup_peers.begin(), backup_peers.end());
162 }
163
164 // The query filter is initially setup to serve default scopes, i.e. for the
165 // load balancing case the primary and secondary are responsible for their
166 // own scopes. The backup servers are not responding to any queries. In the
167 // hot standby mode, the primary server is responsible for the entire traffic.
168 // The standby server is not responding.
169 serveDefaultScopes();
170}
171
172void
173QueryFilter::serveScope(const std::string& scope_name) {
174 if (MultiThreadingMgr::instance().getMode()) {
175 std::lock_guard<std::mutex> lock(*mutex_);
176 serveScopeInternal(scope_name);
177 } else {
178 serveScopeInternal(scope_name);
179 }
180}
181
182void
183QueryFilter::serveScopeInternal(const std::string& scope_name) {
184 validateScopeName(scope_name);
185 scopes_[scope_name] = true;
186}
187
188void
189QueryFilter::serveScopeOnly(const std::string& scope_name) {
190 if (MultiThreadingMgr::instance().getMode()) {
191 std::lock_guard<std::mutex> lock(*mutex_);
192 serveScopeOnlyInternal(scope_name);
193 } else {
194 serveScopeOnlyInternal(scope_name);
195 }
196}
197
198void
199QueryFilter::serveScopeOnlyInternal(const std::string& scope_name) {
200 validateScopeName(scope_name);
201 serveNoScopesInternal();
202 serveScopeInternal(scope_name);
203}
204
205void
206QueryFilter::serveScopes(const std::vector<std::string>& scopes) {
207 if (MultiThreadingMgr::instance().getMode()) {
208 std::lock_guard<std::mutex> lock(*mutex_);
209 serveScopesInternal(scopes);
210 } else {
211 serveScopesInternal(scopes);
212 }
213}
214
215void
216QueryFilter::serveScopesInternal(const std::vector<std::string>& scopes) {
217 // Remember currently enabled scopes in case we fail to process
218 // the provided list of scopes.
219 auto current_scopes = scopes_;
220 try {
221 serveNoScopesInternal();
222 for (size_t i = 0; i < scopes.size(); ++i) {
223 serveScopeInternal(scopes[i]);
224 }
225
226 } catch (...) {
227 // There was an error processing scopes list. Need to revert
228 // to the previous configuration.
229 scopes_ = current_scopes;
230 throw;
231 }
232}
233
234void
235QueryFilter::serveDefaultScopes() {
236 if (MultiThreadingMgr::instance().getMode()) {
237 std::lock_guard<std::mutex> lock(*mutex_);
238 serveDefaultScopesInternal();
239 } else {
240 serveDefaultScopesInternal();
241 }
242}
243
244void
245QueryFilter::serveDefaultScopesInternal() {
246 // Get this server instance configuration.
247 HAConfig::PeerConfigPtr my_config = config_->getThisServerConfig();
248 HAConfig::PeerConfig::Role my_role = my_config->getRole();
249
250 // Clear scopes.
251 serveNoScopesInternal();
252
253 // If I am primary or secondary, then I am only responsible for my own
254 // scope. If I am standby, I am not responsible for any scope.
255 if ((my_role == HAConfig::PeerConfig::PRIMARY) ||
256 (my_role == HAConfig::PeerConfig::SECONDARY)) {
257 serveScopeInternal(my_config->getName());
258 }
259}
260
261void
262QueryFilter::serveFailoverScopes() {
263 if (MultiThreadingMgr::instance().getMode()) {
264 std::lock_guard<std::mutex> lock(*mutex_);
265 serveFailoverScopesInternal();
266 } else {
267 serveFailoverScopesInternal();
268 }
269}
270
271void
272QueryFilter::serveFailoverScopesInternal() {
273 // Clear scopes.
274 serveNoScopesInternal();
275
276 // Iterate over the roles of all servers to see which scope should
277 // be enabled.
278 for (auto const& peer : peers_) {
279 // The scope of the primary server must always be served. If we're
280 // doing load balancing, the scope of the secondary server also
281 // has to be served. Regardless if I am primary or secondary,
282 // I will start serving queries from both scopes. If I am a
283 // standby server, I will start serving the scope of the primary
284 // server.
285 if ((peer->getRole() == HAConfig::PeerConfig::PRIMARY) ||
286 (peer->getRole() == HAConfig::PeerConfig::SECONDARY)) {
287 serveScopeInternal(peer->getName());
288 }
289 }
290}
291
292void
293QueryFilter::serveNoScopes() {
294 if (MultiThreadingMgr::instance().getMode()) {
295 std::lock_guard<std::mutex> lock(*mutex_);
296 serveNoScopesInternal();
297 } else {
298 serveNoScopesInternal();
299 }
300}
301
302void
303QueryFilter::serveNoScopesInternal() {
304 scopes_.clear();
305
306 // Disable scope for each peer in the configuration.
307 for (auto const& peer : peers_) {
308 scopes_[peer->getName()] = false;
309 }
310}
311
312bool
313QueryFilter::amServingScope(const std::string& scope_name) const {
314 if (MultiThreadingMgr::instance().getMode()) {
315 std::lock_guard<std::mutex> lock(*mutex_);
316 return (amServingScopeInternal(scope_name));
317 } else {
318 return (amServingScopeInternal(scope_name));
319 }
320}
321
322bool
323QueryFilter::amServingScopeInternal(const std::string& scope_name) const {
324 auto scope = scopes_.find(scope_name);
325 return ((scope == scopes_.end()) || (scope->second));
326}
327
328std::set<std::string>
329QueryFilter::getServedScopes() const {
330 if (MultiThreadingMgr::instance().getMode()) {
331 std::lock_guard<std::mutex> lock(*mutex_);
332 return (getServedScopesInternal());
333 } else {
334 return (getServedScopesInternal());
335 }
336}
337
338std::set<std::string>
339QueryFilter::getServedScopesInternal() const {
340 std::set<std::string> scope_set;
341 for (auto const& scope : scopes_) {
342 if (scope.second) {
343 scope_set.insert(scope.first);
344 }
345 }
346 return (scope_set);
347}
348
349bool
350QueryFilter::isHaType(const dhcp::Pkt4Ptr& query4) {
351 auto msg_type = query4->getType();
352 return (msg_type < v4_ha_types.size() && v4_ha_types[msg_type]);
353}
354
355bool
356 QueryFilter::isHaType(const dhcp::Pkt6Ptr& query) {
357 auto msg_type = query->getType();
358 return (msg_type < v6_ha_types.size() && v6_ha_types[msg_type]);
359}
360
361
362bool
363QueryFilter::inScope(const dhcp::Pkt4Ptr& query4, std::string& scope_class) const {
364 if (MultiThreadingMgr::instance().getMode()) {
365 std::lock_guard<std::mutex> lock(*mutex_);
366 return (queryInScopeInternal(query4, scope_class));
367 } else {
368 return (queryInScopeInternal(query4, scope_class));
369 }
370}
371
372bool
373 QueryFilter::inScope(const dhcp::Pkt6Ptr& query6, std::string& scope_class) const {
374 if (MultiThreadingMgr::instance().getMode()) {
375 std::lock_guard<std::mutex> lock(*mutex_);
376 return (queryInScopeInternal(query6, scope_class));
377 } else {
378 return (queryInScopeInternal(query6, scope_class));
379 }
380}
381
382template<typename QueryPtrType>
383bool
384QueryFilter::queryInScopeInternal(const QueryPtrType& query,
385 std::string& scope_class) const {
386 if (!query) {
387 isc_throw(BadValue, "query must not be null");
388 }
389
390 // If it's not a type HA cares about, it's in scope for this peer.
391 if (!isHaType(query)) {
392 auto scope = peers_[0]->getName();
393 scope_class = makeScopeClass(scope);
394 return (true);
395 }
396
397 int candidate_server = 0;
398
399 // If we're doing load balancing we have to check if this query
400 // belongs to us or the partner. If it belongs to a partner but
401 // we're configured to serve this scope, we should accept it.
402 if (config_->getHAMode() == HAConfig::LOAD_BALANCING) {
403 candidate_server = loadBalance(query);
404 // Malformed query received.
405 if (candidate_server < 0) {
406 return (false);
407 }
408 }
409
410 auto scope = peers_[candidate_server]->getName();
411 scope_class = makeScopeClass(scope);
412 return ((candidate_server >= 0) && amServingScopeInternal(scope));
413}
414
415bool
416 QueryFilter::inScope(const Lease4Ptr& lease4) const {
417 if (MultiThreadingMgr::instance().getMode()) {
418 std::lock_guard<std::mutex> lock(*mutex_);
419 return (leaseInScopeInternal(lease4));
420 } else {
421 return (leaseInScopeInternal(lease4));
422 }
423}
424
425bool
426 QueryFilter::inScope(const Lease6Ptr& lease6) const {
427 if (MultiThreadingMgr::instance().getMode()) {
428 std::lock_guard<std::mutex> lock(*mutex_);
429 return (leaseInScopeInternal(lease6));
430 } else {
431 return (leaseInScopeInternal(lease6));
432 }
433}
434
435template<typename LeasePtrType>
436bool
437QueryFilter::leaseInScopeInternal(const LeasePtrType& lease) const {
438 if (!lease) {
439 isc_throw(BadValue, "lease must not be null");
440 }
441
442 int candidate_server = 0;
443
444 // If we're doing load balancing we have to check if this query
445 // belongs to us or the partner. If it belongs to a partner but
446 // we're configured to serve this scope, we should accept it.
447 if (config_->getHAMode() == HAConfig::LOAD_BALANCING) {
448 candidate_server = loadBalance(lease);
449 // Malformed query received.
450 if (candidate_server < 0) {
451 return (false);
452 }
453 }
454
455 auto scope = peers_[candidate_server]->getName();
456 return ((candidate_server >= 0) && amServingScopeInternal(scope));
457}
458
459int
460QueryFilter::loadBalance(const dhcp::Pkt4Ptr& query4) const {
461 uint8_t lb_hash = 0;
462 // Try to compute the hash by client identifier if the client
463 // identifier has been specified.
464 OptionPtr opt_client_id = query4->getOption(DHO_DHCP_CLIENT_IDENTIFIER);
465 if (opt_client_id && !opt_client_id->getData().empty()) {
466 auto const& client_id_key = opt_client_id->getData();
467 lb_hash = loadBalanceHash(&client_id_key[0], client_id_key.size());
468
469 } else {
470 // No client identifier available. Use the HW address instead.
471 HWAddrPtr hwaddr = query4->getHWAddr();
472 if (hwaddr && !hwaddr->hwaddr_.empty()) {
473 lb_hash = loadBalanceHash(&hwaddr->hwaddr_[0], hwaddr->hwaddr_.size());
474
475 } else {
476 // No client identifier and no HW address. Indicate an
477 // error.
478 std::stringstream xid;
479 xid << "0x" << std::hex << query4->getTransid() << std::dec;
480 LOG_DEBUG(ha_logger, DBGLVL_TRACE_BASIC, HA_LOAD_BALANCING_IDENTIFIER_MISSING)
481 .arg(config_->getThisServerName())
482 .arg(xid.str());
483 return (-1);
484 }
485 }
486
487 // The hash value modulo number of active servers gives an index
488 // of the server to process the packet.
489 return (active_servers_ > 0 ? static_cast<int>(lb_hash % active_servers_) : -1);
490}
491
492int
493 QueryFilter::loadBalance(const dhcp::Pkt6Ptr& query6) const {
494 uint8_t lb_hash = 0;
495 // Compute the hash by DUID if the DUID.
496 OptionPtr opt_duid = query6->getOption(D6O_CLIENTID);
497 if (opt_duid && !opt_duid->getData().empty()) {
498 auto const& duid_key = opt_duid->getData();
499 lb_hash = loadBalanceHash(&duid_key[0], duid_key.size());
500
501 } else {
502 // No DUID. Indicate an error.
503 std::stringstream xid;
504 xid << "0x" << std::hex << query6->getTransid() << std::dec;
505 LOG_DEBUG(ha_logger, DBGLVL_TRACE_BASIC, HA_LOAD_BALANCING_DUID_MISSING)
506 .arg(config_->getThisServerName())
507 .arg(xid.str());
508 return (-1);
509 }
510
511 // The hash value modulo number of active servers gives an index
512 // of the server to process the packet.
513 return (active_servers_ > 0 ? static_cast<int>(lb_hash % active_servers_) : -1);
514}
515
516int
517 QueryFilter::loadBalance(const dhcp::Lease4Ptr& lease4) const {
518 uint8_t lb_hash = 0;
519 // Try to compute the hash by client identifier if the client
520 // identifier has been specified.
521 if (lease4->client_id_ && !lease4->client_id_->getClientId().empty()) {
522 auto const& client_id_key = lease4->client_id_->getClientId();
523 lb_hash = loadBalanceHash(&client_id_key[0], client_id_key.size());
524
525 } else {
526 // No client identifier available. Use the HW address instead.
527 HWAddrPtr hwaddr = lease4->hwaddr_;
528 if (hwaddr && !hwaddr->hwaddr_.empty()) {
529 lb_hash = loadBalanceHash(&hwaddr->hwaddr_[0], hwaddr->hwaddr_.size());
530
531 } else {
532 // No client identifier and no HW address. Indicate an
533 // error.
534 LOG_DEBUG(ha_logger, DBGLVL_TRACE_BASIC, HA_LOAD_BALANCING_LEASE_IDENTIFIER_MISSING)
535 .arg(config_->getThisServerName())
536 .arg(lease4->addr_);
537 return (-1);
538 }
539 }
540
541 // The hash value modulo number of active servers gives an index
542 // of the server to process the packet.
543 return (active_servers_ > 0 ? static_cast<int>(lb_hash % active_servers_) : -1);
544}
545
546int
547 QueryFilter::loadBalance(const dhcp::Lease6Ptr& lease6) const {
548 uint8_t lb_hash = 0;
549 // Compute the hash by DUID if the DUID.
550 auto duid = lease6->duid_;
551 if (duid && !duid->getDuid().empty()) {
552 auto const& duid_key = duid->getDuid();
553 lb_hash = loadBalanceHash(&duid_key[0], duid_key.size());
554
555 } else {
556 // No DUID. Indicate an error.
557 LOG_DEBUG(ha_logger, DBGLVL_TRACE_BASIC, HA_LOAD_BALANCING_LEASE_DUID_MISSING)
558 .arg(config_->getThisServerName())
559 .arg(lease6->addr_);
560 return (-1);
561 }
562
563 // The hash value modulo number of active servers gives an index
564 // of the server to process the packet.
565 return (active_servers_ > 0 ? static_cast<int>(lb_hash % active_servers_) : -1);
566}
567
568uint8_t
569QueryFilter::loadBalanceHash(const uint8_t* key, const size_t key_len) const {
570 uint8_t hash = static_cast<uint8_t>(key_len);
571
572 for (size_t i = key_len; i > 0;) {
573 hash = loadb_mx_tbl[hash ^ key[--i]];
574 }
575
576 return (hash);
577}
578
579void
580QueryFilter::validateScopeName(const std::string& scope_name) const {
581 try {
582 // If there is no such server, the scope name is invalid.
583 static_cast<void>(config_->getPeerConfig(scope_name));
584
585 } catch (...) {
586 isc_throw(BadValue, "invalid server name specified '" << scope_name
587 << "' while enabling/disabling HA scopes");
588 }
589}
590
591std::string
592QueryFilter::makeScopeClass(const std::string& scope_name) const {
593 return (std::string("HA_") + scope_name);
594}
595
596} // end of namespace isc::ha
597} // end of namespace isc
isc::BadValue
A generic exception that is thrown if a parameter given to a method is considered invalid in that con...
Definition exceptions/exceptions.h:132
isc::ha::HAConfig::PeerConfig::Role
Role
Server's role in the High Availability setup.
Definition ha_config.h:83
isc::ha::HAConfig::PeerConfig::STANDBY
@ STANDBY
Definition ha_config.h:86
isc::ha::HAConfig::PeerConfig::PRIMARY
@ PRIMARY
Definition ha_config.h:84
isc::ha::HAConfig::PeerConfig::SECONDARY
@ SECONDARY
Definition ha_config.h:85
isc::ha::HAConfig::LOAD_BALANCING
@ LOAD_BALANCING
Definition ha_config.h:56
isc::ha::HAConfig::PeerConfigMap
std::map< std::string, PeerConfigPtr > PeerConfigMap
Map of the servers' configurations.
Definition ha_config.h:245
isc::ha::HAConfig::PeerConfigPtr
boost::shared_ptr< PeerConfig > PeerConfigPtr
Pointer to the server's configuration.
Definition ha_config.h:242
isc::ha::QueryFilter::serveScopes
void serveScopes(const std::vector< std::string > &scopes)
Enables selected scopes.
Definition query_filter.cc:206
isc::ha::QueryFilter::inScope
bool inScope(const dhcp::Pkt4Ptr &query4, std::string &scope_class) const
Checks if this server should process the DHCPv4 query.
Definition query_filter.cc:363
isc::ha::QueryFilter::amServingScope
bool amServingScope(const std::string &scope_name) const
Checks if this server instance is configured to process traffic belonging to a particular scope.
Definition query_filter.cc:313
isc::ha::QueryFilter::makeScopeClass
std::string makeScopeClass(const std::string &scope_name) const
Returns scope class name for the specified scope name.
Definition query_filter.cc:592
isc::ha::QueryFilter::mutex_
boost::scoped_ptr< std::mutex > mutex_
Mutex to protect the internal state.
Definition query_filter.h:440
isc::ha::QueryFilter::serveFailoverScopes
void serveFailoverScopes()
Enable scopes required in failover case.
Definition query_filter.cc:262
isc::ha::QueryFilter::loadBalanceHash
uint8_t loadBalanceHash(const uint8_t *key, const size_t key_len) const
Compute load balancing hash.
Definition query_filter.cc:569
isc::ha::QueryFilter::validateScopeName
void validateScopeName(const std::string &scope_name) const
Checks if the scope name matches a name of any of the configured servers.
Definition query_filter.cc:580
isc::ha::QueryFilter::active_servers_
int active_servers_
Number of the active servers in the given HA mode.
Definition query_filter.h:437
isc::ha::QueryFilter::config_
HAConfigPtr config_
Pointer to the HA configuration.
Definition query_filter.h:427
isc::ha::QueryFilter::serveScopeOnly
void serveScopeOnly(const std::string &scope_name)
Enable scope and disable all other scopes.
Definition query_filter.cc:189
isc::ha::QueryFilter::loadBalance
int loadBalance(const dhcp::Pkt4Ptr &query4) const
Performs load balancing of the DHCPv4 queries.
Definition query_filter.cc:460
isc::ha::QueryFilter::isHaType
static bool isHaType(const dhcp::Pkt4Ptr &query4)
Determines if a DHCPv4 query is a message type HA should process.
Definition query_filter.cc:350
isc::ha::QueryFilter::serveDefaultScopes
void serveDefaultScopes()
Serve default scopes for the given HA mode.
Definition query_filter.cc:235
isc::ha::QueryFilter::serveNoScopes
void serveNoScopes()
Disables all scopes.
Definition query_filter.cc:293
isc::ha::QueryFilter::getServedScopes
std::set< std::string > getServedScopes() const
Returns served scopes.
Definition query_filter.cc:329
isc::ha::QueryFilter::serveScope
void serveScope(const std::string &scope_name)
Enable scope.
Definition query_filter.cc:173
isc::ha::QueryFilter::peers_
std::vector< HAConfig::PeerConfigPtr > peers_
Vector of HA peers configurations.
Definition query_filter.h:430
isc::ha::QueryFilter::scopes_
std::map< std::string, bool > scopes_
Holds mapping of the scope names to the flag which indicates if the scopes are enabled or disabled.
Definition query_filter.h:434
isc::ha::QueryFilter::QueryFilter
QueryFilter(const HAConfigPtr &config)
Constructor.
Definition query_filter.cc:121
isc::util::MultiThreadingMgr::instance
static MultiThreadingMgr & instance()
Returns a single instance of Multi Threading Manager.
Definition multi_threading_mgr.cc:25
dhcp4.h
dhcp6.h
D6O_CLIENTID
@ D6O_CLIENTID
Definition dhcp6.h:21
exceptions.h
isc_throw
#define isc_throw(type, stream)
A shortcut macro to insert known values into exception arguments.
Definition exceptions/exceptions.h:210
ha_log.h
LOG_DEBUG
#define LOG_DEBUG(LOGGER, LEVEL, MESSAGE)
Macro to conveniently test debug output and log it.
Definition macros.h:14
multi_threading_mgr.h
isc::config
Definition command_interpreter.cc:23
isc::dhcp
Definition dhcp4/client_handler.cc:20
isc::dhcp::DHO_DHCP_CLIENT_IDENTIFIER
@ DHO_DHCP_CLIENT_IDENTIFIER
Definition dhcp4.h:130
isc::dhcp::Pkt4Ptr
boost::shared_ptr< Pkt4 > Pkt4Ptr
A pointer to Pkt4 object.
Definition pkt4.h:556
isc::dhcp::Lease6Ptr
boost::shared_ptr< Lease6 > Lease6Ptr
Pointer to a Lease6 structure.
Definition lease.h:528
isc::dhcp::HWAddrPtr
boost::shared_ptr< HWAddr > HWAddrPtr
Shared pointer to a hardware address structure.
Definition hwaddr.h:154
isc::dhcp::Pkt6Ptr
boost::shared_ptr< Pkt6 > Pkt6Ptr
A pointer to Pkt6 packet.
Definition pkt6.h:31
isc::dhcp::Lease4Ptr
boost::shared_ptr< Lease4 > Lease4Ptr
Pointer to a Lease4 structure.
Definition lease.h:315
isc::dhcp::OptionPtr
boost::shared_ptr< Option > OptionPtr
Definition option.h:37
isc::ha
Definition command_creator.cc:20
isc::ha::HA_LOAD_BALANCING_LEASE_IDENTIFIER_MISSING
const isc::log::MessageID HA_LOAD_BALANCING_LEASE_IDENTIFIER_MISSING
Definition ha_messages.h:89
isc::ha::ha_logger
isc::log::Logger ha_logger("ha-hooks")
Definition ha_log.h:17
isc::ha::HA_LOAD_BALANCING_LEASE_DUID_MISSING
const isc::log::MessageID HA_LOAD_BALANCING_LEASE_DUID_MISSING
Definition ha_messages.h:88
isc::ha::HAConfigPtr
boost::shared_ptr< HAConfig > HAConfigPtr
Pointer to the High Availability configuration structure.
Definition ha_config.h:37
isc::ha::HA_LOAD_BALANCING_DUID_MISSING
const isc::log::MessageID HA_LOAD_BALANCING_DUID_MISSING
Definition ha_messages.h:86
isc::ha::HA_LOAD_BALANCING_IDENTIFIER_MISSING
const isc::log::MessageID HA_LOAD_BALANCING_IDENTIFIER_MISSING
Definition ha_messages.h:87
isc::log
Definition buffer_appender_impl.cc:17
isc::log::DBGLVL_TRACE_BASIC
const int DBGLVL_TRACE_BASIC
Trace basic operations.
Definition log_dbglevels.h:69
isc::util
Definition time_utils.cc:43
isc
Defines the logger used by the top-level component of kea-lfc.
Definition check_exists_add.cc:18
option.h
query_filter.h