/* * This file is part of PowerDNS or dnsdist. * Copyright -- PowerDNS.COM B.V. and its contributors * * This program is free software; you can redistribute it and/or modify * it under the terms of version 2 of the GNU General Public License as * published by the Free Software Foundation. * * In addition, for the avoidance of any doubt, permission is granted to * link this program with OpenSSL and to (re)distribute the binaries * produced as the result of such linking. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ #pragma once struct dnsdist_ffi_servers_list_t; struct dnsdist_ffi_server_t; struct dnsdist_ffi_dnsquestion_t; struct DownstreamState; struct PerThreadPoliciesState; class ServerPolicy { public: template using NumberedVector = std::vector >; using NumberedServerVector = NumberedVector>; typedef std::function(const NumberedServerVector& servers, const DNSQuestion*)> policyfunc_t; typedef std::function ffipolicyfunc_t; ServerPolicy(const std::string& name_, policyfunc_t policy_, bool isLua_): d_name(name_), d_policy(std::move(policy_)), d_isLua(isLua_) { } ServerPolicy(const std::string& name_, ffipolicyfunc_t policy_): d_name(name_), d_ffipolicy(std::move(policy_)), d_isLua(true), d_isFFI(true) { } /* create a per-thread FFI policy */ ServerPolicy(const std::string& name_, const std::string& code); ServerPolicy() { } std::shared_ptr getSelectedBackend(const ServerPolicy::NumberedServerVector& servers, DNSQuestion& dq) const; const std::string& getName() const { return d_name; } std::string toString() const { return string("ServerPolicy") + (d_isLua ? " (Lua)" : "") + " \"" + d_name + "\""; } private: struct PerThreadState { LuaContext d_luaContext; std::unordered_map d_policies; bool d_initialized{false}; }; const ffipolicyfunc_t& getPerThreadPolicy() const; static thread_local PerThreadState t_perThreadState; public: std::string d_name; std::string d_perThreadPolicyCode; policyfunc_t d_policy; ffipolicyfunc_t d_ffipolicy; bool d_isLua{false}; bool d_isFFI{false}; bool d_isPerThread{false}; }; struct ServerPool; using pools_t = map>; std::shared_ptr getPool(const pools_t& pools, const std::string& poolName); std::shared_ptr createPoolIfNotExists(pools_t& pools, const string& poolName); void setPoolPolicy(pools_t& pools, const string& poolName, std::shared_ptr policy); void addServerToPool(pools_t& pools, const string& poolName, std::shared_ptr server); void removeServerFromPool(pools_t& pools, const string& poolName, std::shared_ptr server); const std::shared_ptr getDownstreamCandidates(const map>& pools, const std::string& poolName); std::shared_ptr firstAvailable(const ServerPolicy::NumberedServerVector& servers, const DNSQuestion* dq); std::shared_ptr leastOutstanding(const ServerPolicy::NumberedServerVector& servers, const DNSQuestion* dq); std::shared_ptr wrandom(const ServerPolicy::NumberedServerVector& servers, const DNSQuestion* dq); std::shared_ptr whashed(const ServerPolicy::NumberedServerVector& servers, const DNSQuestion* dq); std::shared_ptr whashedFromHash(const ServerPolicy::NumberedServerVector& servers, size_t hash); std::shared_ptr chashed(const ServerPolicy::NumberedServerVector& servers, const DNSQuestion* dq); std::shared_ptr chashedFromHash(const ServerPolicy::NumberedServerVector& servers, size_t hash); std::shared_ptr roundrobin(const ServerPolicy::NumberedServerVector& servers, const DNSQuestion* dq); extern double g_consistentHashBalancingFactor; extern double g_weightedBalancingFactor; extern uint32_t g_hashperturb; extern bool g_roundrobinFailOnNoServer;