}
}
- auto localPools = g_pools.getLocal();
- for (const auto& entry : *localPools) {
+ for (const auto& entry : dnsdist::configuration::getCurrentRuntimeConfiguration().d_pools) {
string poolName = entry.first;
boost::replace_all(poolName, ".", "_");
if (poolName.empty()) {
}
};
+class ServerPolicy;
+struct ServerPool;
+
namespace dnsdist::configuration
{
/* when we add EDNS to a query, we don't want to advertise
a RCU-like mechanism */
struct RuntimeConfiguration
{
+ std::map<std::string, std::shared_ptr<ServerPool>> d_pools;
+ std::shared_ptr<ServerPolicy> d_lbPolicy;
NetmaskGroup d_ACL;
NetmaskGroup d_proxyProtocolACL;
NetmaskGroup d_consoleACL;
infolog("Added automatically upgraded server %s", newServer->getNameWithAddr());
- auto localPools = g_pools.getCopy();
if (!newServer->d_config.pools.empty()) {
for (const auto& poolName : newServer->d_config.pools) {
- addServerToPool(localPools, poolName, newServer);
+ addServerToPool(poolName, newServer);
}
}
else {
- addServerToPool(localPools, "", newServer);
+ addServerToPool("", newServer);
}
newServer->start();
}
for (const string& poolName : backend.d_ds->d_config.pools) {
- removeServerFromPool(localPools, poolName, backend.d_ds);
+ removeServerFromPool(poolName, backend.d_ds);
}
/* the server might also be in the default pool */
- removeServerFromPool(localPools, "", backend.d_ds);
+ removeServerFromPool("", backend.d_ds);
}
std::stable_sort(states.begin(), states.end(), [](const decltype(newServer)& a, const decltype(newServer)& b) {
return a->d_config.order < b->d_config.order;
});
- g_pools.setState(localPools);
g_dstates.setState(states);
if (!backend.keepAfterUpgrade) {
backend.d_ds->stop();
#include "dolog.hh"
#include "dns_random.hh"
-GlobalStateHolder<ServerPolicy> g_policy;
-
static constexpr size_t s_staticArrayCutOff = 16;
template <typename T> using DynamicIndexArray = std::vector<std::pair<T, size_t>>;
template <typename T> using StaticIndexArray = std::array<std::pair<T, size_t>, s_staticArrayCutOff>;
return servers.at(candidates.at((counter++) % candidates.size()) - 1).second;
}
-const std::shared_ptr<const ServerPolicy::NumberedServerVector> getDownstreamCandidates(const pools_t& pools, const std::string& poolName)
+const std::shared_ptr<const ServerPolicy::NumberedServerVector> getDownstreamCandidates(const std::string& poolName)
{
- std::shared_ptr<ServerPool> pool = getPool(pools, poolName);
+ std::shared_ptr<ServerPool> pool = getPool(poolName);
return pool->getServers();
}
-std::shared_ptr<ServerPool> createPoolIfNotExists(pools_t& pools, const string& poolName)
+std::shared_ptr<ServerPool> createPoolIfNotExists(const string& poolName)
{
- std::shared_ptr<ServerPool> pool;
- pools_t::iterator it = pools.find(poolName);
- if (it != pools.end()) {
- pool = it->second;
+ {
+ const auto& pools = dnsdist::configuration::getCurrentRuntimeConfiguration().d_pools;
+ const auto it = pools.find(poolName);
+ if (it != pools.end()) {
+ return it->second;
+ }
}
- else {
- if (!poolName.empty())
- vinfolog("Creating pool %s", poolName);
- pool = std::make_shared<ServerPool>();
- pools.insert(std::pair<std::string, std::shared_ptr<ServerPool> >(poolName, pool));
+
+ if (!poolName.empty()) {
+ vinfolog("Creating pool %s", poolName);
}
+
+ auto pool = std::make_shared<ServerPool>();
+ dnsdist::configuration::updateRuntimeConfiguration([&poolName,&pool](dnsdist::configuration::RuntimeConfiguration& config) {
+ config.d_pools.emplace(poolName, pool);
+ });
+
return pool;
}
-void setPoolPolicy(pools_t& pools, const string& poolName, std::shared_ptr<ServerPolicy> policy)
+void setPoolPolicy(const string& poolName, std::shared_ptr<ServerPolicy> policy)
{
- std::shared_ptr<ServerPool> pool = createPoolIfNotExists(pools, poolName);
+ std::shared_ptr<ServerPool> pool = createPoolIfNotExists(poolName);
if (!poolName.empty()) {
vinfolog("Setting pool %s server selection policy to %s", poolName, policy->getName());
} else {
pool->policy = std::move(policy);
}
-void addServerToPool(pools_t& pools, const string& poolName, std::shared_ptr<DownstreamState> server)
+void addServerToPool(const string& poolName, std::shared_ptr<DownstreamState> server)
{
- std::shared_ptr<ServerPool> pool = createPoolIfNotExists(pools, poolName);
+ std::shared_ptr<ServerPool> pool = createPoolIfNotExists(poolName);
if (!poolName.empty()) {
vinfolog("Adding server to pool %s", poolName);
} else {
pool->addServer(server);
}
-void removeServerFromPool(pools_t& pools, const string& poolName, std::shared_ptr<DownstreamState> server)
+void removeServerFromPool(const string& poolName, std::shared_ptr<DownstreamState> server)
{
- std::shared_ptr<ServerPool> pool = getPool(pools, poolName);
+ std::shared_ptr<ServerPool> pool = getPool(poolName);
if (!poolName.empty()) {
vinfolog("Removing server from pool %s", poolName);
pool->removeServer(server);
}
-std::shared_ptr<ServerPool> getPool(const pools_t& pools, const std::string& poolName)
+std::shared_ptr<ServerPool> getPool(const std::string& poolName)
{
- pools_t::const_iterator it = pools.find(poolName);
-
+ const auto& pools = dnsdist::configuration::getCurrentRuntimeConfiguration().d_pools;
+ auto it = pools.find(poolName);
if (it == pools.end()) {
throw std::out_of_range("No pool named " + poolName);
}
template <class T>
using NumberedVector = std::vector<std::pair<unsigned int, T>>;
using NumberedServerVector = NumberedVector<shared_ptr<DownstreamState>>;
- typedef std::function<shared_ptr<DownstreamState>(const NumberedServerVector& servers, const DNSQuestion*)> policyfunc_t;
- typedef std::function<unsigned int(dnsdist_ffi_servers_list_t* servers, dnsdist_ffi_dnsquestion_t* dq)> ffipolicyfunc_t;
+ using policyfunc_t = std::function<std::shared_ptr<DownstreamState>(const NumberedServerVector& servers, const DNSQuestion*)>;
+ using ffipolicyfunc_t = std::function<unsigned int(dnsdist_ffi_servers_list_t* servers, dnsdist_ffi_dnsquestion_t* dq)>;
ServerPolicy(const std::string& name_, policyfunc_t policy_, bool isLua_) :
d_name(name_), d_policy(std::move(policy_)), d_isLua(isLua_)
struct ServerPool;
-using pools_t = map<std::string, std::shared_ptr<ServerPool>>;
-std::shared_ptr<ServerPool> getPool(const pools_t& pools, const std::string& poolName);
-std::shared_ptr<ServerPool> createPoolIfNotExists(pools_t& pools, const string& poolName);
-void setPoolPolicy(pools_t& pools, const string& poolName, std::shared_ptr<ServerPolicy> policy);
-void addServerToPool(pools_t& pools, const string& poolName, std::shared_ptr<DownstreamState> server);
-void removeServerFromPool(pools_t& pools, const string& poolName, std::shared_ptr<DownstreamState> server);
+using pools_t = std::map<std::string, std::shared_ptr<ServerPool>>;
+std::shared_ptr<ServerPool> getPool(const std::string& poolName);
+std::shared_ptr<ServerPool> createPoolIfNotExists(const string& poolName);
+void setPoolPolicy(const string& poolName, std::shared_ptr<ServerPolicy> policy);
+void addServerToPool(const string& poolName, std::shared_ptr<DownstreamState> server);
+void removeServerFromPool(const string& poolName, std::shared_ptr<DownstreamState> server);
-const std::shared_ptr<const ServerPolicy::NumberedServerVector> getDownstreamCandidates(const map<std::string, std::shared_ptr<ServerPool>>& pools, const std::string& poolName);
+const std::shared_ptr<const ServerPolicy::NumberedServerVector> getDownstreamCandidates(const std::string& poolName);
std::shared_ptr<DownstreamState> firstAvailable(const ServerPolicy::NumberedServerVector& servers, const DNSQuestion* dq);
/* DownstreamState */
luaCtx.registerFunction<void (DownstreamState::*)(int)>("setQPS", [](DownstreamState& state, int lim) { state.qps = lim > 0 ? QPSLimiter(lim, lim) : QPSLimiter(); });
luaCtx.registerFunction<void (std::shared_ptr<DownstreamState>::*)(string)>("addPool", [](const std::shared_ptr<DownstreamState>& state, const string& pool) {
- auto localPools = g_pools.getCopy();
- addServerToPool(localPools, pool, state);
- g_pools.setState(localPools);
+ addServerToPool( pool, state);
state->d_config.pools.insert(pool);
});
luaCtx.registerFunction<void (std::shared_ptr<DownstreamState>::*)(string)>("rmPool", [](const std::shared_ptr<DownstreamState>& state, const string& pool) {
- auto localPools = g_pools.getCopy();
- removeServerFromPool(localPools, pool, state);
- g_pools.setState(localPools);
+ removeServerFromPool(pool, state);
state->d_config.pools.erase(pool);
});
luaCtx.registerFunction<uint64_t (DownstreamState::*)() const>("getOutstanding", [](const DownstreamState& state) { return state.outstanding.load(); });
return 0;
}
- const auto localPools = g_pools.getCopy();
- auto it = localPools.find(poolName);
- if (it == localPools.end()) {
+ const auto& pools = dnsdist::configuration::getCurrentRuntimeConfiguration().d_pools;
+ auto it = pools.find(poolName);
+ if (it == pools.end()) {
return 0;
}
return 0;
}
- const auto localPools = g_pools.getCopy();
- auto it = localPools.find(poolName);
- if (it == localPools.end()) {
+ const auto& pools = dnsdist::configuration::getCurrentRuntimeConfiguration().d_pools;
+ auto it = pools.find(poolName);
+ if (it == pools.end()) {
return 0;
}
/* this needs to be done _AFTER_ the order has been set,
since the server are kept ordered inside the pool */
- auto localPools = g_pools.getCopy();
if (!ret->d_config.pools.empty()) {
for (const auto& poolName : ret->d_config.pools) {
- addServerToPool(localPools, poolName, ret);
+ addServerToPool(poolName, ret);
}
}
else {
- addServerToPool(localPools, "", ret);
+ addServerToPool("", ret);
}
- g_pools.setState(localPools);
if (ret->connected) {
if (g_launchWork) {
if (!server) {
throw std::runtime_error("unable to locate the requested server");
}
- auto localPools = g_pools.getCopy();
for (const string& poolName : server->d_config.pools) {
- removeServerFromPool(localPools, poolName, server);
+ removeServerFromPool(poolName, server);
}
/* the server might also be in the default pool */
- removeServerFromPool(localPools, "", server);
- g_pools.setState(localPools);
+ removeServerFromPool("", server);
states.erase(remove(states.begin(), states.end(), server), states.end());
g_dstates.setState(states);
server->stop();
});
luaCtx.writeFunction("getPoolServers", [](const string& pool) {
- const auto poolServers = getDownstreamCandidates(g_pools.getCopy(), pool);
+ const auto poolServers = getDownstreamCandidates(pool);
return *poolServers;
});
// 1 2 3 4
ret << (fmt % "Name" % "Cache" % "ServerPolicy" % "Servers") << endl;
- const auto localPools = g_pools.getCopy();
- for (const auto& entry : localPools) {
+ const auto defaultPolicyName = dnsdist::configuration::getCurrentRuntimeConfiguration().d_lbPolicy->getName();
+ const auto pools = dnsdist::configuration::getCurrentRuntimeConfiguration().d_pools;
+ for (const auto& entry : pools) {
const string& name = entry.first;
const std::shared_ptr<ServerPool> pool = entry.second;
string cache = pool->packetCache != nullptr ? pool->packetCache->toString() : "";
- string policy = g_policy.getLocal()->getName();
+ string policy = defaultPolicyName;
if (pool->policy != nullptr) {
policy = pool->policy->getName();
}
setLuaNoSideEffect();
LuaArray<std::string> ret;
int count = 1;
- const auto localPools = g_pools.getCopy();
- for (const auto& entry : localPools) {
+ const auto pools = dnsdist::configuration::getCurrentRuntimeConfiguration().d_pools;
+ for (const auto& entry : pools) {
const string& name = entry.first;
ret.emplace_back(count++, name);
}
if (client) {
return std::make_shared<ServerPool>();
}
- auto localPools = g_pools.getCopy();
- std::shared_ptr<ServerPool> pool = createPoolIfNotExists(localPools, poolName);
- g_pools.setState(localPools);
+ std::shared_ptr<ServerPool> pool = createPoolIfNotExists(poolName);
return pool;
});
#ifndef DISABLE_POLICIES_BINDINGS
luaCtx.writeFunction("setServerPolicy", [](const std::shared_ptr<ServerPolicy>& policy) {
setLuaSideEffect();
- g_policy.setState(*policy);
+ dnsdist::configuration::updateRuntimeConfiguration([&policy](dnsdist::configuration::RuntimeConfiguration& config) {
+ config.d_lbPolicy = policy;
+ });
});
luaCtx.writeFunction("setServerPolicyLua", [](const string& name, ServerPolicy::policyfunc_t policy) {
setLuaSideEffect();
- g_policy.setState(ServerPolicy{name, std::move(policy), true});
+ auto pol = std::make_shared<ServerPolicy>(name, std::move(policy), true);
+ dnsdist::configuration::updateRuntimeConfiguration([&pol](dnsdist::configuration::RuntimeConfiguration& config) {
+ config.d_lbPolicy = std::move(pol);
+ });
});
luaCtx.writeFunction("setServerPolicyLuaFFI", [](const string& name, ServerPolicy::ffipolicyfunc_t policy) {
setLuaSideEffect();
- auto pol = ServerPolicy(name, std::move(policy));
- g_policy.setState(std::move(pol));
+ auto pol = std::make_shared<ServerPolicy>(name, std::move(policy));
+ dnsdist::configuration::updateRuntimeConfiguration([&pol](dnsdist::configuration::RuntimeConfiguration& config) {
+ config.d_lbPolicy = std::move(pol);
+ });
});
luaCtx.writeFunction("setServerPolicyLuaFFIPerThread", [](const string& name, const std::string& policyCode) {
setLuaSideEffect();
- auto pol = ServerPolicy(name, policyCode);
- g_policy.setState(std::move(pol));
+ auto policy = std::make_shared<ServerPolicy>(name, policyCode);
+ dnsdist::configuration::updateRuntimeConfiguration([&policy](dnsdist::configuration::RuntimeConfiguration& config) {
+ config.d_lbPolicy = std::move(policy);
+ });
});
luaCtx.writeFunction("showServerPolicy", []() {
setLuaSideEffect();
- g_outputBuffer = g_policy.getLocal()->getName() + "\n";
+ g_outputBuffer = dnsdist::configuration::getCurrentRuntimeConfiguration().d_lbPolicy->getName() + "\n";
});
luaCtx.writeFunction("setPoolServerPolicy", [](const std::shared_ptr<ServerPolicy>& policy, const string& pool) {
setLuaSideEffect();
- auto localPools = g_pools.getCopy();
- setPoolPolicy(localPools, pool, policy);
- g_pools.setState(localPools);
+ setPoolPolicy(pool, policy);
});
luaCtx.writeFunction("setPoolServerPolicyLua", [](const string& name, ServerPolicy::policyfunc_t policy, const string& pool) {
setLuaSideEffect();
- auto localPools = g_pools.getCopy();
- setPoolPolicy(localPools, pool, std::make_shared<ServerPolicy>(ServerPolicy{name, std::move(policy), true}));
- g_pools.setState(localPools);
+ setPoolPolicy(pool, std::make_shared<ServerPolicy>(ServerPolicy{name, std::move(policy), true}));
});
luaCtx.writeFunction("setPoolServerPolicyLuaFFI", [](const string& name, ServerPolicy::ffipolicyfunc_t policy, const string& pool) {
setLuaSideEffect();
- auto localPools = g_pools.getCopy();
- setPoolPolicy(localPools, pool, std::make_shared<ServerPolicy>(ServerPolicy{name, std::move(policy)}));
- g_pools.setState(localPools);
+ setPoolPolicy(pool, std::make_shared<ServerPolicy>(ServerPolicy{name, std::move(policy)}));
});
luaCtx.writeFunction("setPoolServerPolicyLuaFFIPerThread", [](const string& name, const std::string& policyCode, const std::string& pool) {
setLuaSideEffect();
- auto localPools = g_pools.getCopy();
- setPoolPolicy(localPools, pool, std::make_shared<ServerPolicy>(ServerPolicy{name, policyCode}));
- g_pools.setState(localPools);
+ setPoolPolicy(pool, std::make_shared<ServerPolicy>(ServerPolicy{name, policyCode}));
});
luaCtx.writeFunction("showPoolServerPolicy", [](const std::string& pool) {
setLuaSideEffect();
- auto localPools = g_pools.getCopy();
- auto poolObj = getPool(localPools, pool);
+ auto poolObj = getPool(pool);
if (poolObj->policy == nullptr) {
- g_outputBuffer = g_policy.getLocal()->getName() + "\n";
+ g_outputBuffer = dnsdist::configuration::getCurrentRuntimeConfiguration().d_lbPolicy->getName() + "\n";
}
else {
g_outputBuffer = poolObj->policy->getName() + "\n";
class PoolAvailableRule : public DNSRule
{
public:
- PoolAvailableRule(const std::string& poolname) : d_pools(&g_pools), d_poolname(poolname)
+ PoolAvailableRule(const std::string& poolname) : d_poolname(poolname)
{
}
bool matches(const DNSQuestion* dq) const override
{
- return (getPool(*d_pools, d_poolname)->countServers(true) > 0);
+ return (getPool(d_poolname)->countServers(true) > 0);
}
string toString() const override
return "pool '" + d_poolname + "' is available";
}
private:
- mutable LocalStateHolder<pools_t> d_pools;
std::string d_poolname;
};
class PoolOutstandingRule : public DNSRule
{
public:
- PoolOutstandingRule(const std::string& poolname, const size_t limit) : d_pools(&g_pools), d_poolname(poolname), d_limit(limit)
+ PoolOutstandingRule(const std::string& poolname, const size_t limit) : d_poolname(poolname), d_limit(limit)
{
}
bool matches(const DNSQuestion* dq) const override
{
- return (getPool(*d_pools, d_poolname)->poolLoad()) > d_limit;
+ return (getPool(d_poolname)->poolLoad()) > d_limit;
}
string toString() const override
return "pool '" + d_poolname + "' outstanding > " + std::to_string(d_limit);
}
private:
- mutable LocalStateHolder<pools_t> d_pools;
std::string d_poolname;
size_t d_limit;
};
}
#endif /* HAVE_DNS_OVER_HTTPS */
- auto localPools = g_pools.getLocal();
const string cachebase = "dnsdist_pool_";
output << "# HELP dnsdist_pool_servers " << "Number of servers in that pool" << "\n";
output << "# TYPE dnsdist_pool_servers " << "gauge" << "\n";
output << "# HELP dnsdist_pool_cache_cleanup_count_total " << "Number of times the cache has been scanned to remove expired entries, if any" << "\n";
output << "# TYPE dnsdist_pool_cache_cleanup_count_total " << "counter" << "\n";
- for (const auto& entry : *localPools) {
+ for (const auto& entry : dnsdist::configuration::getCurrentRuntimeConfiguration().d_pools) {
string poolName = entry.first;
if (poolName.empty()) {
{"packetcache-misses", 0},
{"over-capacity-drops", 0},
{"too-old-drops", 0},
- {"server-policy", g_policy.getLocal()->getName()}};
+ {"server-policy", runtimeConfig.d_lbPolicy->getName()}};
addStatsToJSONObject(obj);
Json::array pools;
{
- auto localPools = g_pools.getLocal();
num = 0;
- pools.reserve(localPools->size());
- for (const auto& pool : *localPools) {
+ const auto localPools = dnsdist::configuration::getCurrentRuntimeConfiguration().d_pools;
+ pools.reserve(localPools.size());
+ for (const auto& pool : localPools) {
const auto& cache = pool.second->packetCache;
Json::object entry{
{"id", num++},
resp.status = 200;
Json::array doc;
- auto localPools = g_pools.getLocal();
- const auto poolIt = localPools->find(poolName->second);
- if (poolIt == localPools->end()) {
+ const auto& pools = dnsdist::configuration::getCurrentRuntimeConfiguration().d_pools;
+ const auto poolIt = pools.find(poolName->second);
+ if (poolIt == pools.end()) {
resp.status = 404;
return;
}
{"ecs-source-prefix-v6", static_cast<double>(runtimeConfiguration.d_ECSSourcePrefixV6)},
{"fixup-case", runtimeConfiguration.d_fixupCase},
{"max-outstanding", static_cast<double>(immutableConfig.d_maxUDPOutstanding)},
- {"server-policy", g_policy.getLocal()->getName()},
+ {"server-policy", runtimeConfiguration.d_lbPolicy->getName()},
{"stale-cache-entries-ttl", static_cast<double>(runtimeConfiguration.d_staleCacheEntriesTTL)},
{"tcp-recv-timeout", static_cast<double>(runtimeConfiguration.d_tcpRecvTimeout)},
{"tcp-send-timeout", static_cast<double>(runtimeConfiguration.d_tcpSendTimeout)},
std::shared_ptr<ServerPool> pool;
try {
- pool = getPool(g_pools.getCopy(), poolName->second);
+ pool = getPool(poolName->second);
}
catch (const std::exception& e) {
resp.status = 404;
std::vector<std::shared_ptr<DynBPFFilter>> g_dynBPFFilters;
std::vector<std::unique_ptr<ClientState>> g_frontends;
-GlobalStateHolder<pools_t> g_pools;
std::vector<uint32_t> g_TCPFastOpenKey;
/* UDP: the grand design. Per socket we listen on for incoming queries there is one thread.
Then we have a bunch of connected sockets for talking to downstream servers.
return ProcessQueryResult::SendAnswer;
}
-static void selectBackendForOutgoingQuery(DNSQuestion& dnsQuestion, const std::shared_ptr<ServerPool>& serverPool, LocalHolders& holders, std::shared_ptr<DownstreamState>& selectedBackend)
+static void selectBackendForOutgoingQuery(DNSQuestion& dnsQuestion, const std::shared_ptr<ServerPool>& serverPool, std::shared_ptr<DownstreamState>& selectedBackend)
{
std::shared_ptr<ServerPolicy> poolPolicy = serverPool->policy;
- const auto& policy = poolPolicy != nullptr ? *poolPolicy : *(holders.policy);
+ const auto& policy = poolPolicy != nullptr ? *poolPolicy : *dnsdist::configuration::getCurrentRuntimeConfiguration().d_lbPolicy;
const auto servers = serverPool->getServers();
selectedBackend = policy.getSelectedBackend(*servers, dnsQuestion);
}
if (dnsQuestion.getHeader()->qr) { // something turned it into a response
return handleQueryTurnedIntoSelfAnsweredResponse(dnsQuestion, holders);
}
- std::shared_ptr<ServerPool> serverPool = getPool(*holders.pools, dnsQuestion.ids.poolName);
+ std::shared_ptr<ServerPool> serverPool = getPool(dnsQuestion.ids.poolName);
dnsQuestion.ids.packetCache = serverPool->packetCache;
- selectBackendForOutgoingQuery(dnsQuestion, serverPool, holders, selectedBackend);
+ selectBackendForOutgoingQuery(dnsQuestion, serverPool, selectedBackend);
uint32_t allowExpired = selectedBackend ? 0 : dnsdist::configuration::getCurrentRuntimeConfiguration().d_staleCacheEntriesTTL;
/* let's be nice and allow the selection of a different pool,
but no second cache-lookup for you */
if (dnsQuestion.ids.poolName != existingPool) {
- serverPool = getPool(*holders.pools, dnsQuestion.ids.poolName);
+ serverPool = getPool(dnsQuestion.ids.poolName);
dnsQuestion.ids.packetCache = serverPool->packetCache;
- selectBackendForOutgoingQuery(dnsQuestion, serverPool, holders, selectedBackend);
+ selectBackendForOutgoingQuery(dnsQuestion, serverPool, selectedBackend);
}
}
/* gather all caches actually used by at least one pool, and see
if something prevents us from cleaning the expired entries */
- auto localPools = g_pools.getLocal();
- for (const auto& entry : *localPools) {
+ const auto& pools = dnsdist::configuration::getCurrentRuntimeConfiguration().d_pools;
+ for (const auto& entry : pools) {
const auto& pool = entry.second;
auto packetCache = pool->packetCache;
chain.holder.setState({});
}
g_dstates.setState({});
- g_policy.setState(ServerPolicy());
- g_pools.setState({});
+ dnsdist::configuration::updateRuntimeConfiguration([](dnsdist::configuration::RuntimeConfiguration& config) {
+ config.d_lbPolicy = std::make_shared<ServerPolicy>();
+ config.d_pools.clear();
+ });
clearWebHandlers();
dnsdist::lua::hooks::clearMaintenanceHooks();
}
}
static void setupPools()
{
- auto pools = g_pools.getCopy();
- {
- bool precompute = false;
- if (g_policy.getLocal()->getName() == "chashed") {
- precompute = true;
- }
- else {
- for (const auto& entry : pools) {
- if (entry.second->policy != nullptr && entry.second->policy->getName() == "chashed") {
- precompute = true;
- break;
- }
+ bool precompute = false;
+ if (dnsdist::configuration::getCurrentRuntimeConfiguration().d_lbPolicy->getName() == "chashed") {
+ precompute = true;
+ }
+ else {
+ for (const auto& entry : dnsdist::configuration::getCurrentRuntimeConfiguration().d_pools) {
+ if (entry.second->policy != nullptr && entry.second->policy->getName() == "chashed") {
+ precompute = true;
+ break;
}
}
- if (precompute) {
- vinfolog("Pre-computing hashes for consistent hash load-balancing policy");
- // pre compute hashes
- auto backends = g_dstates.getLocal();
- for (const auto& backend : *backends) {
- if (backend->d_config.d_weight < 100) {
- vinfolog("Warning, the backend '%s' has a very low weight (%d), which will not yield a good distribution of queries with the 'chashed' policy. Please consider raising it to at least '100'.", backend->getName(), backend->d_config.d_weight);
- }
-
- backend->hash();
+ }
+ if (precompute) {
+ vinfolog("Pre-computing hashes for consistent hash load-balancing policy");
+ // pre compute hashes
+ auto backends = g_dstates.getLocal();
+ for (const auto& backend : *backends) {
+ if (backend->d_config.d_weight < 100) {
+ vinfolog("Warning, the backend '%s' has a very low weight (%d), which will not yield a good distribution of queries with the 'chashed' policy. Please consider raising it to at least '100'.", backend->getName(), backend->d_config.d_weight);
}
+
+ backend->hash();
}
}
}
parseParameters(argc, argv, clientAddress);
- ServerPolicy leastOutstandingPol{"leastOutstanding", leastOutstanding, false};
+ dnsdist::configuration::updateRuntimeConfiguration([](dnsdist::configuration::RuntimeConfiguration& config) {
+ config.d_lbPolicy = std::make_shared<ServerPolicy>("leastOutstanding", leastOutstanding, false);
+ });
- g_policy.setState(leastOutstandingPol);
if (g_cmdLine.beClient || !g_cmdLine.command.empty()) {
setupLua(*(g_lua.lock()), true, false, g_cmdLine.config);
if (clientAddress != ComboAddress()) {
todoItem();
}
- auto localPools = g_pools.getCopy();
/* create the default pool no matter what */
- createPoolIfNotExists(localPools, "");
+ createPoolIfNotExists("");
if (!g_cmdLine.remotes.empty()) {
for (const auto& address : g_cmdLine.remotes) {
DownstreamState::Config config;
config.remote = ComboAddress(address, 53);
auto ret = std::make_shared<DownstreamState>(std::move(config), nullptr, true);
- addServerToPool(localPools, "", ret);
+ addServerToPool("", ret);
ret->start();
g_dstates.modify([&ret](servers_t& servers) { servers.push_back(std::move(ret)); });
}
}
- g_pools.setState(localPools);
if (g_dstates.getLocal()->empty()) {
errlog("No downstream servers defined: all packets will get dropped");
extern GlobalStateHolder<SuffixMatchTree<DynBlock>> g_dynblockSMT;
-extern GlobalStateHolder<ServerPolicy> g_policy;
extern GlobalStateHolder<servers_t> g_dstates;
-extern GlobalStateHolder<pools_t> g_pools;
extern std::vector<shared_ptr<TLSFrontend>> g_tlslocals;
extern std::vector<shared_ptr<DOHFrontend>> g_dohlocals;
struct LocalHolders
{
LocalHolders() :
- policy(g_policy.getLocal()), ruleactions(dnsdist::rules::getRuleChainHolder(dnsdist::rules::RuleChain::Rules).getLocal()), cacheMissRuleActions(dnsdist::rules::getRuleChainHolder(dnsdist::rules::RuleChain::CacheMissRules).getLocal()), cacheHitRespRuleactions(dnsdist::rules::getResponseRuleChainHolder(dnsdist::rules::ResponseRuleChain::CacheHitResponseRules).getLocal()), cacheInsertedRespRuleActions(dnsdist::rules::getResponseRuleChainHolder(dnsdist::rules::ResponseRuleChain::CacheInsertedResponseRules).getLocal()), selfAnsweredRespRuleactions(dnsdist::rules::getResponseRuleChainHolder(dnsdist::rules::ResponseRuleChain::SelfAnsweredResponseRules).getLocal()), servers(g_dstates.getLocal()), dynNMGBlock(g_dynblockNMG.getLocal()), dynSMTBlock(g_dynblockSMT.getLocal()), pools(g_pools.getLocal())
+ ruleactions(dnsdist::rules::getRuleChainHolder(dnsdist::rules::RuleChain::Rules).getLocal()), cacheMissRuleActions(dnsdist::rules::getRuleChainHolder(dnsdist::rules::RuleChain::CacheMissRules).getLocal()), cacheHitRespRuleactions(dnsdist::rules::getResponseRuleChainHolder(dnsdist::rules::ResponseRuleChain::CacheHitResponseRules).getLocal()), cacheInsertedRespRuleActions(dnsdist::rules::getResponseRuleChainHolder(dnsdist::rules::ResponseRuleChain::CacheInsertedResponseRules).getLocal()), selfAnsweredRespRuleactions(dnsdist::rules::getResponseRuleChainHolder(dnsdist::rules::ResponseRuleChain::SelfAnsweredResponseRules).getLocal()), servers(g_dstates.getLocal()), dynNMGBlock(g_dynblockNMG.getLocal()), dynSMTBlock(g_dynblockSMT.getLocal())
{
}
- LocalStateHolder<ServerPolicy> policy;
LocalStateHolder<vector<dnsdist::rules::RuleAction>> ruleactions;
LocalStateHolder<vector<dnsdist::rules::RuleAction>> cacheMissRuleActions;
LocalStateHolder<vector<dnsdist::rules::ResponseRuleAction>> cacheHitRespRuleactions;
LocalStateHolder<servers_t> servers;
LocalStateHolder<NetmaskTree<DynBlock, AddressAndPortRange>> dynNMGBlock;
LocalStateHolder<SuffixMatchTree<DynBlock>> dynSMTBlock;
- LocalStateHolder<pools_t> pools;
};
ProcessQueryResult processQuery(DNSQuestion& dnsQuestion, LocalHolders& holders, std::shared_ptr<DownstreamState>& selectedBackend);
testPool->packetCache = packetCache;
std::string poolWithNoCacheName("test-pool-without-cache");
auto testPoolWithNoCache = std::make_shared<ServerPool>();
- auto localPools = g_pools.getCopy();
- localPools.emplace(poolName, testPool);
- localPools.emplace(poolWithNoCacheName, testPoolWithNoCache);
- g_pools.setState(localPools);
+ dnsdist::configuration::updateRuntimeConfiguration([&poolName,&testPool,&poolWithNoCacheName,&testPoolWithNoCache](dnsdist::configuration::RuntimeConfiguration& config) {
+ config.d_pools.emplace(poolName, testPool);
+ config.d_pools.emplace(poolWithNoCacheName, testPoolWithNoCache);
+ });
{
dnsdist_ffi_domain_list_t* list = nullptr;
GlobalStateHolder<SuffixMatchTree<DynBlock>> g_dynblockSMT;
#endif /* BENCH_POLICIES */
-GlobalStateHolder<pools_t> g_pools;
std::vector<std::unique_ptr<ClientState>> g_frontends;
/* add stub implementations, we don't want to include the corresponding object files
{
/* we need to reset this before cleaning the Lua state because the server policy might holds
a reference to a Lua function (Lua policies) */
- g_policy.setState(ServerPolicy("leastOutstanding", leastOutstanding, false));
+ dnsdist::configuration::updateRuntimeConfiguration([](dnsdist::configuration::RuntimeConfiguration& config) {
+ config.d_lbPolicy = std::make_shared<ServerPolicy>("leastOutstanding", leastOutstanding, false);
+ });
+ /* we actually need this line to clear the cached state for this thread */
+ BOOST_REQUIRE_EQUAL(dnsdist::configuration::getCurrentRuntimeConfiguration().d_lbPolicy->getName(), "leastOutstanding");
*(g_lua.lock()) = LuaContext();
}
BOOST_AUTO_TEST_SUITE(dnsdistlbpolicies)
+#if 0
BOOST_AUTO_TEST_CASE(test_firstAvailable)
{
auto dnsQuestion = getDQ();
config.d_verbose = existingVerboseValue;
});
}
+#endif
BOOST_AUTO_TEST_CASE(test_lua)
{
)foo";
resetLuaContext();
g_lua.lock()->writeFunction("setServerPolicyLua", [](const string& name, const ServerPolicy::policyfunc_t& policy) {
- g_policy.setState(ServerPolicy{name, policy, true});
+ auto pol = std::make_shared<ServerPolicy>(name, std::move(policy), true);
+ dnsdist::configuration::updateRuntimeConfiguration([&pol](dnsdist::configuration::RuntimeConfiguration& config) {
+ config.d_lbPolicy = std::move(pol);
+ });
});
g_lua.lock()->executeCode(policySetupStr);
{
- ServerPolicy pol = g_policy.getCopy();
+ const auto& pol = dnsdist::configuration::getCurrentRuntimeConfiguration().d_lbPolicy;
+ BOOST_REQUIRE(pol != nullptr);
+ BOOST_REQUIRE(pol != nullptr);
ServerPolicy::NumberedServerVector servers;
std::map<std::shared_ptr<DownstreamState>, uint64_t> serversMap;
for (size_t idx = 1; idx <= 10; idx++) {
for (const auto& name : names) {
auto dnsQuestion = getDQ(&name);
- auto server = pol.getSelectedBackend(servers, dnsQuestion);
+ auto server = pol->getSelectedBackend(servers, dnsQuestion);
BOOST_REQUIRE(serversMap.count(server) == 1);
++serversMap[server];
}
}
BOOST_CHECK_EQUAL(total, names.size());
- benchPolicy(pol);
+ benchPolicy(*pol);
}
resetLuaContext();
}
-
+#if 0
#ifdef LUAJIT_VERSION
BOOST_AUTO_TEST_CASE(test_lua_ffi_rr)
resetLuaContext();
g_lua.lock()->executeCode(getLuaFFIWrappers());
g_lua.lock()->writeFunction("setServerPolicyLuaFFI", [](const string& name, const ServerPolicy::ffipolicyfunc_t& policy) {
- g_policy.setState(ServerPolicy(name, policy));
+ auto pol = std::make_shared<ServerPolicy>(name, std::move(policy));
+ dnsdist::configuration::updateRuntimeConfiguration([&pol](dnsdist::configuration::RuntimeConfiguration& config) {
+ config.d_lbPolicy = std::move(pol);
+ });
});
g_lua.lock()->executeCode(policySetupStr);
{
- ServerPolicy pol = g_policy.getCopy();
+ const auto& pol = dnsdist::configuration::getCurrentRuntimeConfiguration().d_lbPolicy;
+ BOOST_REQUIRE(pol != nullptr);
ServerPolicy::NumberedServerVector servers;
std::map<std::shared_ptr<DownstreamState>, uint64_t> serversMap;
for (size_t idx = 1; idx <= 10; idx++) {
for (const auto& name : names) {
auto dnsQuestion = getDQ(&name);
- auto server = pol.getSelectedBackend(servers, dnsQuestion);
+ auto server = pol->getSelectedBackend(servers, dnsQuestion);
BOOST_REQUIRE(serversMap.count(server) == 1);
++serversMap[server];
}
}
BOOST_CHECK_EQUAL(total, names.size());
- benchPolicy(pol);
+ benchPolicy(*pol);
}
resetLuaContext();
}
resetLuaContext();
g_lua.lock()->executeCode(getLuaFFIWrappers());
g_lua.lock()->writeFunction("setServerPolicyLuaFFI", [](const string& policyName, ServerPolicy::ffipolicyfunc_t policy) {
- g_policy.setState(ServerPolicy(policyName, std::move(policy)));
+ auto pol = std::make_shared<ServerPolicy>(policyName, std::move(policy));
+ dnsdist::configuration::updateRuntimeConfiguration([&pol](dnsdist::configuration::RuntimeConfiguration& config) {
+ config.d_lbPolicy = std::move(pol);
+ });
});
g_lua.lock()->executeCode(policySetupStr);
{
- ServerPolicy pol = g_policy.getCopy();
+ const auto& pol = dnsdist::configuration::getCurrentRuntimeConfiguration().d_lbPolicy;
+ BOOST_REQUIRE(pol != nullptr);
ServerPolicy::NumberedServerVector servers;
for (size_t idx = 1; idx <= 10; idx++) {
servers.emplace_back(idx, std::make_shared<DownstreamState>(ComboAddress("192.0.2." + std::to_string(idx) + ":53")));
BOOST_REQUIRE_EQUAL(servers.size(), 10U);
auto dnsQuestion = getDQ(&dnsName);
- auto server = pol.getSelectedBackend(servers, dnsQuestion);
+ auto server = pol->getSelectedBackend(servers, dnsQuestion);
BOOST_REQUIRE(server == nullptr);
}
resetLuaContext();
resetLuaContext();
g_lua.lock()->executeCode(getLuaFFIWrappers());
g_lua.lock()->writeFunction("setServerPolicyLuaFFI", [](const string& name, const ServerPolicy::ffipolicyfunc_t& policy) {
- g_policy.setState(ServerPolicy(name, policy));
+ auto pol = std::make_shared<ServerPolicy>(name, std::move(policy));
+ dnsdist::configuration::updateRuntimeConfiguration([&pol](dnsdist::configuration::RuntimeConfiguration& config) {
+ config.d_lbPolicy = std::move(pol);
+ });
});
g_lua.lock()->executeCode(policySetupStr);
{
- ServerPolicy pol = g_policy.getCopy();
+ const auto& pol = dnsdist::configuration::getCurrentRuntimeConfiguration().d_lbPolicy;
+ BOOST_REQUIRE(pol != nullptr);
ServerPolicy::NumberedServerVector servers;
std::map<std::shared_ptr<DownstreamState>, uint64_t> serversMap;
for (size_t idx = 1; idx <= 10; idx++) {
for (const auto& name : names) {
auto dnsQuestion = getDQ(&name);
- auto server = pol.getSelectedBackend(servers, dnsQuestion);
+ auto server = pol->getSelectedBackend(servers, dnsQuestion);
BOOST_REQUIRE(serversMap.count(server) == 1);
++serversMap[server];
}
}
BOOST_CHECK_EQUAL(total, names.size());
- benchPolicy(pol);
+ benchPolicy(*pol);
}
resetLuaContext();
}
resetLuaContext();
g_lua.lock()->executeCode(getLuaFFIWrappers());
g_lua.lock()->writeFunction("setServerPolicyLuaFFI", [](const string& name, const ServerPolicy::ffipolicyfunc_t& policy) {
- g_policy.setState(ServerPolicy(name, policy));
+ auto pol = std::make_shared<ServerPolicy>(name, std::move(policy));
+ dnsdist::configuration::updateRuntimeConfiguration([&pol](dnsdist::configuration::RuntimeConfiguration& config) {
+ config.d_lbPolicy = std::move(pol);
+ });
});
g_lua.lock()->executeCode(policySetupStr);
{
- ServerPolicy pol = g_policy.getCopy();
+ const auto& pol = dnsdist::configuration::getCurrentRuntimeConfiguration().d_lbPolicy;
+ BOOST_REQUIRE(pol != nullptr);
ServerPolicy::NumberedServerVector servers;
std::map<std::shared_ptr<DownstreamState>, uint64_t> serversMap;
for (size_t idx = 1; idx <= 10; idx++) {
for (const auto& name : names) {
auto dnsQuestion = getDQ(&name);
- auto server = pol.getSelectedBackend(servers, dnsQuestion);
+ auto server = pol->getSelectedBackend(servers, dnsQuestion);
BOOST_REQUIRE(serversMap.count(server) == 1);
++serversMap[server];
}
}
BOOST_CHECK_EQUAL(total, names.size());
- benchPolicy(pol);
+ benchPolicy(*pol);
}
resetLuaContext();
}
resetLuaContext();
g_lua.lock()->executeCode(getLuaFFIWrappers());
g_lua.lock()->writeFunction("setServerPolicyLuaFFI", [](const string& name, const ServerPolicy::ffipolicyfunc_t& policy) {
- g_policy.setState(ServerPolicy(name, policy));
+ auto pol = std::make_shared<ServerPolicy>(name, std::move(policy));
+ dnsdist::configuration::updateRuntimeConfiguration([&pol](dnsdist::configuration::RuntimeConfiguration& config) {
+ config.d_lbPolicy = std::move(pol);
+ });
});
g_lua.lock()->executeCode(policySetupStr);
{
- ServerPolicy pol = g_policy.getCopy();
+ const auto& pol = dnsdist::configuration::getCurrentRuntimeConfiguration().d_lbPolicy;
+ BOOST_REQUIRE(pol != nullptr);
ServerPolicy::NumberedServerVector servers;
std::map<std::shared_ptr<DownstreamState>, uint64_t> serversMap;
for (size_t idx = 1; idx <= 10; idx++) {
for (const auto& name : names) {
auto dnsQuestion = getDQ(&name);
- auto server = pol.getSelectedBackend(servers, dnsQuestion);
+ auto server = pol->getSelectedBackend(servers, dnsQuestion);
BOOST_REQUIRE(serversMap.count(server) == 1);
++serversMap[server];
}
}
BOOST_CHECK_EQUAL(total, names.size());
- benchPolicy(pol);
+ benchPolicy(*pol);
}
resetLuaContext();
}
#endif /* LUAJIT_VERSION */
-
+#endif
BOOST_AUTO_TEST_SUITE_END()
BOOST_CHECK_EQUAL(sp.poolLoad(), 400U + 30U);
- auto localPool = g_pools.getCopy();
- addServerToPool(localPool, "test", ds1);
- addServerToPool(localPool, "test", ds2);
- g_pools.setState(localPool);
+ addServerToPool("test", ds1);
+ addServerToPool("test", ds2);
PoolOutstandingRule pOR1("test", 10);
BOOST_CHECK_EQUAL(pOR1.matches(&dq), true);