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 }
 
   51std::array<bool, DHCP_TYPES_EOF> v4_ha_types = {
 
   74std::array<bool, DHCPV6_TYPES_EOF> v6_ha_types = {
 
  131    std::vector<HAConfig::PeerConfigPtr> backup_peers;
 
  135    for (
auto const& peer_pair : peers_map) {
 
  136        auto peer = peer_pair.second;
 
  155            backup_peers.push_back(peer);
 
  160    if (!backup_peers.empty()) {
 
  161        peers_.insert(peers_.end(), backup_peers.begin(), backup_peers.end());
 
 
  175        std::lock_guard<std::mutex> lock(*
mutex_);
 
  176        serveScopeInternal(scope_name);
 
  178        serveScopeInternal(scope_name);
 
 
  183QueryFilter::serveScopeInternal(
const std::string& scope_name) {
 
  191        std::lock_guard<std::mutex> lock(*
mutex_);
 
  192        serveScopeOnlyInternal(scope_name);
 
  194        serveScopeOnlyInternal(scope_name);
 
 
  199QueryFilter::serveScopeOnlyInternal(
const std::string& scope_name) {
 
  201    serveNoScopesInternal();
 
  202    serveScopeInternal(scope_name);
 
  208        std::lock_guard<std::mutex> lock(*
mutex_);
 
  209        serveScopesInternal(scopes);
 
  211        serveScopesInternal(scopes);
 
 
  216QueryFilter::serveScopesInternal(
const std::vector<std::string>& scopes) {
 
  221        serveNoScopesInternal();
 
  222        for (
size_t i = 0; i < scopes.size(); ++i) {
 
  223            serveScopeInternal(scopes[i]);
 
  237        std::lock_guard<std::mutex> lock(*
mutex_);
 
  238        serveDefaultScopesInternal();
 
  240        serveDefaultScopesInternal();
 
 
  245QueryFilter::serveDefaultScopesInternal() {
 
  251    serveNoScopesInternal();
 
  257        serveScopeInternal(my_config->getName());
 
  264        std::lock_guard<std::mutex> lock(*
mutex_);
 
  265        serveFailoverScopesInternal();
 
  267        serveFailoverScopesInternal();
 
 
  272QueryFilter::serveFailoverScopesInternal() {
 
  274    serveNoScopesInternal();
 
  278    for (
auto const& peer : 
peers_) {
 
  287            serveScopeInternal(peer->getName());
 
  295        std::lock_guard<std::mutex> lock(*
mutex_);
 
  296        serveNoScopesInternal();
 
  298        serveNoScopesInternal();
 
 
  303QueryFilter::serveNoScopesInternal() {
 
  307    for (
auto const& peer : 
peers_) {
 
  308        scopes_[peer->getName()] = 
false;
 
  315        std::lock_guard<std::mutex> lock(*
mutex_);
 
  316        return (amServingScopeInternal(scope_name));
 
  318        return (amServingScopeInternal(scope_name));
 
 
  323QueryFilter::amServingScopeInternal(
const std::string& scope_name)
 const {
 
  324    auto scope = 
scopes_.find(scope_name);
 
  325    return ((scope == 
scopes_.end()) || (scope->second));
 
  331        std::lock_guard<std::mutex> lock(*
mutex_);
 
  332        return (getServedScopesInternal());
 
  334        return (getServedScopesInternal());
 
 
  339QueryFilter::getServedScopesInternal()
 const {
 
  340    std::set<std::string> scope_set;
 
  341    for (
auto const& scope : 
scopes_) {
 
  343            scope_set.insert(scope.first);
 
  351    auto msg_type = query4->getType();
 
  352    return (msg_type < v4_ha_types.size() && v4_ha_types[msg_type]);
 
 
  357    auto msg_type = query->getType();
 
  358    return (msg_type < v6_ha_types.size() && v6_ha_types[msg_type]);
 
 
  365        std::lock_guard<std::mutex> lock(*
mutex_);
 
  366        return (queryInScopeInternal(query4, scope_class));
 
  368        return (queryInScopeInternal(query4, scope_class));
 
 
  375        std::lock_guard<std::mutex> lock(*
mutex_);
 
  376        return (queryInScopeInternal(query6, scope_class));
 
  378        return (queryInScopeInternal(query6, scope_class));
 
 
  382template<
typename QueryPtrType>
 
  384QueryFilter::queryInScopeInternal(
const QueryPtrType& query,
 
  385                             std::string& scope_class)
 const {
 
  392        auto scope = 
peers_[0]->getName();
 
  397    int candidate_server = 0;
 
  405        if (candidate_server < 0) {
 
  410    auto scope = 
peers_[candidate_server]->getName();
 
  412    return ((candidate_server >= 0) && amServingScopeInternal(scope));
 
  418        std::lock_guard<std::mutex> lock(*
mutex_);
 
  419        return (leaseInScopeInternal(lease4));
 
  421        return (leaseInScopeInternal(lease4));
 
 
  428        std::lock_guard<std::mutex> lock(*
mutex_);
 
  429        return (leaseInScopeInternal(lease6));
 
  431        return (leaseInScopeInternal(lease6));
 
 
  435template<
typename LeasePtrType>
 
  437QueryFilter::leaseInScopeInternal(
const LeasePtrType& lease)
 const {
 
  442    int candidate_server = 0;
 
  450        if (candidate_server < 0) {
 
  455    auto scope = 
peers_[candidate_server]->getName();
 
  456    return ((candidate_server >= 0) && amServingScopeInternal(scope));
 
  465    if (opt_client_id && !opt_client_id->getData().empty()) {
 
  466        auto const& client_id_key = opt_client_id->getData();
 
  472        if (hwaddr && !hwaddr->hwaddr_.empty()) {
 
  473            lb_hash = 
loadBalanceHash(&hwaddr->hwaddr_[0], hwaddr->hwaddr_.size());
 
  478            std::stringstream xid;
 
  479            xid << 
"0x" << std::hex << query4->getTransid() << std::dec;
 
  481                .arg(
config_->getThisServerName())
 
 
  497    if (opt_duid && !opt_duid->getData().empty()) {
 
  498        auto const& duid_key = opt_duid->getData();
 
  503        std::stringstream xid;
 
  504        xid << 
"0x" << std::hex << query6->getTransid() << std::dec;
 
  506            .arg(
config_->getThisServerName())
 
 
  521    if (lease4->client_id_ && !lease4->client_id_->getClientId().empty()) {
 
  522        auto const& client_id_key = lease4->client_id_->getClientId();
 
  528        if (hwaddr && !hwaddr->hwaddr_.empty()) {
 
  529            lb_hash = 
loadBalanceHash(&hwaddr->hwaddr_[0], hwaddr->hwaddr_.size());
 
  535                .arg(
config_->getThisServerName())
 
 
  550    auto duid = lease6->duid_;
 
  551    if (duid && !duid->getDuid().empty()) {
 
  552        auto const& duid_key = duid->getDuid();
 
  558            .arg(
config_->getThisServerName())
 
 
  570    uint8_t hash  = 
static_cast<uint8_t
>(key_len);
 
  572    for (
size_t i = key_len; i > 0;) {
 
  573        hash = loadb_mx_tbl[hash ^ key[--i]];
 
 
  583        static_cast<void>(
config_->getPeerConfig(scope_name));
 
  587                  << 
"' while enabling/disabling HA scopes");
 
 
  593    return (std::string(
"HA_") + scope_name);
 
 
A generic exception that is thrown if a parameter given to a method is considered invalid in that con...
Role
Server's role in the High Availability setup.
std::map< std::string, PeerConfigPtr > PeerConfigMap
Map of the servers' configurations.
boost::shared_ptr< PeerConfig > PeerConfigPtr
Pointer to the server's configuration.
void serveScopes(const std::vector< std::string > &scopes)
Enables selected scopes.
bool inScope(const dhcp::Pkt4Ptr &query4, std::string &scope_class) const
Checks if this server should process the DHCPv4 query.
bool amServingScope(const std::string &scope_name) const
Checks if this server instance is configured to process traffic belonging to a particular scope.
std::string makeScopeClass(const std::string &scope_name) const
Returns scope class name for the specified scope name.
boost::scoped_ptr< std::mutex > mutex_
Mutex to protect the internal state.
void serveFailoverScopes()
Enable scopes required in failover case.
uint8_t loadBalanceHash(const uint8_t *key, const size_t key_len) const
Compute load balancing hash.
void validateScopeName(const std::string &scope_name) const
Checks if the scope name matches a name of any of the configured servers.
int active_servers_
Number of the active servers in the given HA mode.
HAConfigPtr config_
Pointer to the HA configuration.
void serveScopeOnly(const std::string &scope_name)
Enable scope and disable all other scopes.
int loadBalance(const dhcp::Pkt4Ptr &query4) const
Performs load balancing of the DHCPv4 queries.
static bool isHaType(const dhcp::Pkt4Ptr &query4)
Determines if a DHCPv4 query is a message type HA should process.
void serveDefaultScopes()
Serve default scopes for the given HA mode.
void serveNoScopes()
Disables all scopes.
std::set< std::string > getServedScopes() const
Returns served scopes.
void serveScope(const std::string &scope_name)
Enable scope.
std::vector< HAConfig::PeerConfigPtr > peers_
Vector of HA peers configurations.
std::map< std::string, bool > scopes_
Holds mapping of the scope names to the flag which indicates if the scopes are enabled or disabled.
QueryFilter(const HAConfigPtr &config)
Constructor.
static MultiThreadingMgr & instance()
Returns a single instance of Multi Threading Manager.
#define isc_throw(type, stream)
A shortcut macro to insert known values into exception arguments.
#define LOG_DEBUG(LOGGER, LEVEL, MESSAGE)
Macro to conveniently test debug output and log it.
@ DHO_DHCP_CLIENT_IDENTIFIER
boost::shared_ptr< Pkt4 > Pkt4Ptr
A pointer to Pkt4 object.
boost::shared_ptr< Lease6 > Lease6Ptr
Pointer to a Lease6 structure.
boost::shared_ptr< HWAddr > HWAddrPtr
Shared pointer to a hardware address structure.
boost::shared_ptr< Pkt6 > Pkt6Ptr
A pointer to Pkt6 packet.
boost::shared_ptr< Lease4 > Lease4Ptr
Pointer to a Lease4 structure.
boost::shared_ptr< Option > OptionPtr
const isc::log::MessageID HA_LOAD_BALANCING_LEASE_IDENTIFIER_MISSING
isc::log::Logger ha_logger("ha-hooks")
const isc::log::MessageID HA_LOAD_BALANCING_LEASE_DUID_MISSING
boost::shared_ptr< HAConfig > HAConfigPtr
Pointer to the High Availability configuration structure.
const isc::log::MessageID HA_LOAD_BALANCING_DUID_MISSING
const isc::log::MessageID HA_LOAD_BALANCING_IDENTIFIER_MISSING
const int DBGLVL_TRACE_BASIC
Trace basic operations.
Defines the logger used by the top-level component of kea-lfc.