auto& ids = response->query.d_idstate;
DNSResponse dnsResponse = response->getDR();
- LocalHolders holders;
- auto result = processResponseAfterRules(response->query.d_buffer, *holders.cacheInsertedRespRuleActions, dnsResponse, ids.cs->muted);
+ auto result = processResponseAfterRules(response->query.d_buffer, dnsResponse, ids.cs->muted);
if (!result) {
/* easy */
return true;
#include <string>
#include "dnsdist-query-count.hh"
+#include "dnsdist-rule-chains.hh"
#include "iputils.hh"
/* so what could you do:
a RCU-like mechanism */
struct RuntimeConfiguration
{
+ // ca tient pas la route: meilleure option: stocker un type plus opaque dans la configuration (dnsdist::rules::RuleChains) et
+ // laisser le soin a dnsdist::rules de le gerer
+ /* std::vector<rules::RuleAction> d_cacheMissRuleActions;
+ std::vector<rules::ResponseRuleAction> d_respruleactions;
+ std::vector<rules::ResponseRuleAction> d_cachehitrespruleactions;
+ std::vector<rules::ResponseRuleAction> d_selfansweredrespruleactions;
+ std::vector<rules::ResponseRuleAction> d_cacheInsertedRespRuleActions;
+ std::vector<rules::ResponseRuleAction> d_XFRRespRuleActions;
+ */
+ rules::RuleChains d_ruleChains;
servers_t d_backends;
std::map<std::string, std::shared_ptr<ServerPool>> d_pools;
std::shared_ptr<ServerPolicy> d_lbPolicy;
EDNSExtendedError d_ede;
};
-template <typename T, typename ActionT>
-static void addAction(GlobalStateHolder<vector<T>>* someRuleActions, const luadnsrule_t& var, const std::shared_ptr<ActionT>& action, boost::optional<luaruleparams_t>& params)
+template <typename ActionT, typename IdentifierT>
+static void addAction(IdentifierT identifier, const luadnsrule_t& var, const std::shared_ptr<ActionT>& action, boost::optional<luaruleparams_t>& params)
{
setLuaSideEffect();
checkAllParametersConsumed("addAction", params);
auto rule = makeRule(var, "addAction");
- someRuleActions->modify([&rule, &action, &uuid, creationOrder, &name](vector<T>& ruleactions) {
- ruleactions.push_back({std::move(rule), std::move(action), std::move(name), uuid, creationOrder});
+ dnsdist::configuration::updateRuntimeConfiguration([identifier, &rule, &action, &name, &uuid, creationOrder](dnsdist::configuration::RuntimeConfiguration& config) {
+ dnsdist::rules::add(config.d_ruleChains, identifier, std::move(rule), action, std::move(name), uuid, creationOrder);
});
}
return std::make_shared<dnsdist::rules::RuleAction>(ruleaction);
});
- for (const auto& chain : dnsdist::rules::getRuleChains()) {
+ for (const auto& chain : dnsdist::rules::getRuleChainDescriptions()) {
auto fullName = std::string("add") + chain.prefix + std::string("Action");
luaCtx.writeFunction(fullName, [&fullName, &chain](const luadnsrule_t& var, boost::variant<std::shared_ptr<DNSAction>, std::shared_ptr<DNSResponseAction>> era, boost::optional<luaruleparams_t> params) {
if (era.type() != typeid(std::shared_ptr<DNSAction>)) {
throw std::runtime_error(fullName + "() can only be called with query-related actions, not response-related ones. Are you looking for addResponseAction()?");
}
- addAction(&chain.holder, var, boost::get<std::shared_ptr<DNSAction>>(era), params);
+ addAction(chain.identifier, var, boost::get<std::shared_ptr<DNSAction>>(era), params);
});
fullName = std::string("get") + chain.prefix + std::string("Action");
luaCtx.writeFunction(fullName, [&chain](unsigned int num) {
setLuaNoSideEffect();
boost::optional<std::shared_ptr<DNSAction>> ret;
- auto ruleactions = chain.holder.getCopy();
+ const auto& chains = dnsdist::configuration::getCurrentRuntimeConfiguration().d_ruleChains;
+ const auto& ruleactions = dnsdist::rules::getRuleChain(chains, chain.identifier);
if (num < ruleactions.size()) {
ret = ruleactions[num].d_action;
}
});
}
- for (const auto& chain : dnsdist::rules::getResponseRuleChains()) {
+ for (const auto& chain : dnsdist::rules::getResponseRuleChainDescriptions()) {
const auto fullName = std::string("add") + chain.prefix + std::string("ResponseAction");
luaCtx.writeFunction(fullName, [&fullName, &chain](const luadnsrule_t& var, boost::variant<std::shared_ptr<DNSAction>, std::shared_ptr<DNSResponseAction>> era, boost::optional<luaruleparams_t> params) {
if (era.type() != typeid(std::shared_ptr<DNSResponseAction>)) {
throw std::runtime_error(fullName + "() can only be called with response-related actions, not query-related ones. Are you looking for addAction()?");
}
- addAction(&chain.holder, var, boost::get<std::shared_ptr<DNSResponseAction>>(era), params);
+ addAction(chain.identifier, var, boost::get<std::shared_ptr<DNSResponseAction>>(era), params);
});
}
/* 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) {
- addServerToPool( pool, state);
+ 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) {
return result;
}
-template <typename T>
-static void showRules(GlobalStateHolder<vector<T>>* someRuleActions, boost::optional<ruleparams_t>& vars)
+template <typename IdentifierT>
+static void showRules(IdentifierT identifier, boost::optional<ruleparams_t>& vars)
{
setLuaNoSideEffect();
- auto rules = someRuleActions->getLocal();
- g_outputBuffer += rulesToString(*rules, vars);
+ const auto& chains = dnsdist::configuration::getCurrentRuntimeConfiguration().d_ruleChains;
+ const auto& rules = dnsdist::rules::getRuleChain(chains, identifier);
+ g_outputBuffer += rulesToString(rules, vars);
}
-template <typename T>
-static void rmRule(GlobalStateHolder<vector<T>>* someRuleActions, const boost::variant<unsigned int, std::string>& ruleID)
+template <typename ChainTypeT, typename RuleTypeT>
+static bool removeRuleFromChain(ChainTypeT& rules, const std::function<bool(const RuleTypeT& rule)>& matchFunction)
+{
+ auto removeIt = std::remove_if(rules.begin(),
+ rules.end(),
+ matchFunction);
+ if (removeIt == rules.end()) {
+ g_outputBuffer = "Error: no rule matched\n";
+ return false;
+ }
+ rules.erase(removeIt,
+ rules.end());
+ return true;
+}
+
+template <typename ChainIdentifierT>
+static void rmRule(ChainIdentifierT chainIdentifier, const boost::variant<unsigned int, std::string>& ruleID)
{
- setLuaSideEffect();
- auto rules = someRuleActions->getCopy();
if (const auto* str = boost::get<std::string>(&ruleID)) {
try {
const auto uuid = getUniqueID(*str);
- auto removeIt = std::remove_if(rules.begin(),
- rules.end(),
- [&uuid](const T& rule) { return rule.d_id == uuid; });
- if (removeIt == rules.end()) {
- g_outputBuffer = "Error: no rule matched\n";
- return;
- }
- rules.erase(removeIt,
- rules.end());
+ dnsdist::configuration::updateRuntimeConfiguration([chainIdentifier, &uuid](dnsdist::configuration::RuntimeConfiguration& config) {
+ constexpr bool isResponseChain = std::is_same_v<ChainIdentifierT, dnsdist::rules::ResponseRuleChain>;
+ if constexpr (isResponseChain) {
+ auto& rules = dnsdist::rules::getResponseRuleChain(config.d_ruleChains, chainIdentifier);
+ std::function<bool(const dnsdist::rules::ResponseRuleAction&)> matchFunction = [&uuid](const dnsdist::rules::ResponseRuleAction& rule) -> bool { return rule.d_id == uuid; };
+ removeRuleFromChain(rules, matchFunction);
+ }
+ else {
+ auto& rules = dnsdist::rules::getRuleChain(config.d_ruleChains, chainIdentifier);
+ std::function<bool(const dnsdist::rules::RuleAction&)> matchFunction = [&uuid](const dnsdist::rules::RuleAction& rule) -> bool { return rule.d_id == uuid; };
+ removeRuleFromChain(rules, matchFunction);
+ }
+ });
}
catch (const std::runtime_error& e) {
- /* it was not an UUID, let's see if it was a name instead */
- auto removeIt = std::remove_if(rules.begin(),
- rules.end(),
- [&str](const T& rule) { return rule.d_name == *str; });
- if (removeIt == rules.end()) {
- g_outputBuffer = "Error: no rule matched\n";
- return;
- }
- rules.erase(removeIt,
- rules.end());
+ dnsdist::configuration::updateRuntimeConfiguration([chainIdentifier, &str](dnsdist::configuration::RuntimeConfiguration& config) {
+ constexpr bool isResponseChain = std::is_same_v<ChainIdentifierT, dnsdist::rules::ResponseRuleChain>;
+ if constexpr (isResponseChain) {
+ auto& rules = dnsdist::rules::getResponseRuleChain(config.d_ruleChains, chainIdentifier);
+ std::function<bool(const dnsdist::rules::ResponseRuleAction&)> matchFunction = [&str](const dnsdist::rules::ResponseRuleAction& rule) -> bool { return rule.d_name == *str; };
+ removeRuleFromChain(rules, matchFunction);
+ }
+ else {
+ auto& rules = dnsdist::rules::getRuleChain(config.d_ruleChains, chainIdentifier);
+ std::function<bool(const dnsdist::rules::RuleAction&)> matchFunction = [&str](const dnsdist::rules::RuleAction& rule) -> bool { return rule.d_name == *str; };
+ removeRuleFromChain(rules, matchFunction);
+ }
+ });
}
}
else if (const auto* pos = boost::get<unsigned int>(&ruleID)) {
- if (*pos >= rules.size()) {
- g_outputBuffer = "Error: attempt to delete non-existing rule\n";
- return;
- }
- rules.erase(rules.begin() + *pos);
+ dnsdist::configuration::updateRuntimeConfiguration([chainIdentifier, pos](dnsdist::configuration::RuntimeConfiguration& config) {
+ auto& rules = dnsdist::rules::getRuleChain(config.d_ruleChains, chainIdentifier);
+ if (*pos >= rules.size()) {
+ g_outputBuffer = "Error: attempt to delete non-existing rule\n";
+ return;
+ }
+ rules.erase(rules.begin() + *pos);
+ });
}
- someRuleActions->setState(std::move(rules));
+ setLuaSideEffect();
}
-template <typename T>
-static void moveRuleToTop(GlobalStateHolder<vector<T>>* someRuleActions)
+template <typename IdentifierTypeT>
+static void moveRuleToTop(IdentifierTypeT chainIdentifier)
{
setLuaSideEffect();
- auto rules = someRuleActions->getCopy();
- if (rules.empty()) {
- return;
- }
- auto subject = *rules.rbegin();
- rules.erase(std::prev(rules.end()));
- rules.insert(rules.begin(), subject);
- someRuleActions->setState(std::move(rules));
+ dnsdist::configuration::updateRuntimeConfiguration([chainIdentifier](dnsdist::configuration::RuntimeConfiguration& config) {
+ auto& rules = dnsdist::rules::getRuleChain(config.d_ruleChains, chainIdentifier);
+ if (rules.empty()) {
+ return;
+ }
+ auto subject = *rules.rbegin();
+ rules.erase(std::prev(rules.end()));
+ rules.insert(rules.begin(), subject);
+ });
+ setLuaSideEffect();
}
-template <typename T>
-static void mvRule(GlobalStateHolder<vector<T>>* someRespRuleActions, unsigned int from, unsigned int destination)
+template <typename IdentifierTypeT>
+static void mvRule(IdentifierTypeT chainIdentifier, unsigned int from, unsigned int destination)
{
- setLuaSideEffect();
- auto rules = someRespRuleActions->getCopy();
- if (from >= rules.size() || destination > rules.size()) {
- g_outputBuffer = "Error: attempt to move rules from/to invalid index\n";
- return;
- }
- auto subject = rules[from];
- rules.erase(rules.begin() + from);
- if (destination > rules.size()) {
- rules.push_back(subject);
- }
- else {
- if (from < destination) {
- --destination;
+ dnsdist::configuration::updateRuntimeConfiguration([chainIdentifier, from, &destination](dnsdist::configuration::RuntimeConfiguration& config) {
+ auto& rules = dnsdist::rules::getRuleChain(config.d_ruleChains, chainIdentifier);
+ if (from >= rules.size() || destination > rules.size()) {
+ g_outputBuffer = "Error: attempt to move rules from/to invalid index\n";
+ return;
}
- rules.insert(rules.begin() + destination, subject);
- }
- someRespRuleActions->setState(std::move(rules));
+ auto subject = rules[from];
+ rules.erase(rules.begin() + from);
+ if (destination > rules.size()) {
+ rules.push_back(subject);
+ }
+ else {
+ if (from < destination) {
+ --destination;
+ }
+ rules.insert(rules.begin() + destination, subject);
+ }
+ });
+ setLuaSideEffect();
}
template <typename T>
luaCtx.registerFunction<std::shared_ptr<DNSResponseAction> (dnsdist::rules::ResponseRuleAction::*)() const>("getAction", [](const dnsdist::rules::ResponseRuleAction& rule) { return rule.d_action; });
- for (const auto& chain : dnsdist::rules::getResponseRuleChains()) {
+ for (const auto& chain : dnsdist::rules::getResponseRuleChainDescriptions()) {
luaCtx.writeFunction("show" + chain.prefix + "ResponseRules", [&chain](boost::optional<ruleparams_t> vars) {
- showRules(&chain.holder, vars);
+ showRules(chain.identifier, vars);
});
luaCtx.writeFunction("rm" + chain.prefix + "ResponseRule", [&chain](const boost::variant<unsigned int, std::string>& identifier) {
- rmRule(&chain.holder, identifier);
+ rmRule(chain.identifier, identifier);
});
luaCtx.writeFunction("mv" + chain.prefix + "ResponseRuleToTop", [&chain]() {
- moveRuleToTop(&chain.holder);
+ moveRuleToTop(chain.identifier);
});
luaCtx.writeFunction("mv" + chain.prefix + "ResponseRule", [&chain](unsigned int from, unsigned int dest) {
- mvRule(&chain.holder, from, dest);
+ mvRule(chain.identifier, from, dest);
});
luaCtx.writeFunction("get" + chain.prefix + "ResponseRule", [&chain](const boost::variant<unsigned int, std::string>& selector) -> boost::optional<dnsdist::rules::ResponseRuleAction> {
- auto rules = chain.holder.getLocal();
- return getRuleFromSelector(*rules, selector);
+ const auto& chains = dnsdist::configuration::getCurrentRuntimeConfiguration().d_ruleChains;
+ const auto& rules = dnsdist::rules::getResponseRuleChain(chains, chain.identifier);
+ return getRuleFromSelector(rules, selector);
});
luaCtx.writeFunction("getTop" + chain.prefix + "ResponseRules", [&chain](boost::optional<unsigned int> top) {
setLuaNoSideEffect();
- auto rules = chain.holder.getLocal();
- return toLuaArray(getTopRules(*rules, (top ? *top : 10)));
+ const auto& chains = dnsdist::configuration::getCurrentRuntimeConfiguration().d_ruleChains;
+ const auto& rules = dnsdist::rules::getResponseRuleChain(chains, chain.identifier);
+ return toLuaArray(getTopRules(rules, (top ? *top : 10)));
});
luaCtx.writeFunction("top" + chain.prefix + "ResponseRules", [&chain](boost::optional<unsigned int> top, boost::optional<ruleparams_t> vars) {
setLuaNoSideEffect();
- auto rules = chain.holder.getLocal();
- return rulesToString(getTopRules(*rules, (top ? *top : 10)), vars);
+ const auto& chains = dnsdist::configuration::getCurrentRuntimeConfiguration().d_ruleChains;
+ const auto& rules = dnsdist::rules::getResponseRuleChain(chains, chain.identifier);
+ return rulesToString(getTopRules(rules, (top ? *top : 10)), vars);
});
luaCtx.writeFunction("clear" + chain.prefix + "ResponseRules", [&chain]() {
setLuaSideEffect();
- chain.holder.modify([](std::remove_reference_t<decltype(chain.holder)>::value_type& ruleactions) {
- ruleactions.clear();
+ dnsdist::configuration::updateRuntimeConfiguration([&chain](dnsdist::configuration::RuntimeConfiguration& config) {
+ auto& rules = dnsdist::rules::getRuleChain(config.d_ruleChains, chain.identifier);
+ rules.clear();
});
});
}
- for (const auto& chain : dnsdist::rules::getRuleChains()) {
+ for (const auto& chain : dnsdist::rules::getRuleChainDescriptions()) {
luaCtx.writeFunction("show" + chain.prefix + "Rules", [&chain](boost::optional<ruleparams_t> vars) {
- showRules(&chain.holder, vars);
+ showRules(chain.identifier, vars);
});
luaCtx.writeFunction("rm" + chain.prefix + "Rule", [&chain](const boost::variant<unsigned int, std::string>& identifier) {
- rmRule(&chain.holder, identifier);
+ rmRule(chain.identifier, identifier);
});
luaCtx.writeFunction("mv" + chain.prefix + "RuleToTop", [&chain]() {
- moveRuleToTop(&chain.holder);
+ moveRuleToTop(chain.identifier);
});
luaCtx.writeFunction("mv" + chain.prefix + "Rule", [&chain](unsigned int from, unsigned int dest) {
- mvRule(&chain.holder, from, dest);
+ mvRule(chain.identifier, from, dest);
});
luaCtx.writeFunction("get" + chain.prefix + "Rule", [&chain](const boost::variant<int, std::string>& selector) -> boost::optional<dnsdist::rules::RuleAction> {
- auto rules = chain.holder.getLocal();
- return getRuleFromSelector(*rules, selector);
+ const auto& chains = dnsdist::configuration::getCurrentRuntimeConfiguration().d_ruleChains;
+ const auto& rules = dnsdist::rules::getRuleChain(chains, chain.identifier);
+ return getRuleFromSelector(rules, selector);
});
luaCtx.writeFunction("getTop" + chain.prefix + "Rules", [&chain](boost::optional<unsigned int> top) {
setLuaNoSideEffect();
- auto rules = chain.holder.getLocal();
- return toLuaArray(getTopRules(*rules, (top ? *top : 10)));
+ const auto& chains = dnsdist::configuration::getCurrentRuntimeConfiguration().d_ruleChains;
+ const auto& rules = dnsdist::rules::getRuleChain(chains, chain.identifier);
+ return toLuaArray(getTopRules(rules, (top ? *top : 10)));
});
luaCtx.writeFunction("top" + chain.prefix + "Rules", [&chain](boost::optional<unsigned int> top, boost::optional<ruleparams_t> vars) {
setLuaNoSideEffect();
- auto rules = chain.holder.getLocal();
- return rulesToString(getTopRules(*rules, (top ? *top : 10)), vars);
+ const auto& chains = dnsdist::configuration::getCurrentRuntimeConfiguration().d_ruleChains;
+ const auto& rules = dnsdist::rules::getRuleChain(chains, chain.identifier);
+
+ return rulesToString(getTopRules(rules, (top ? *top : 10)), vars);
});
luaCtx.writeFunction("clear" + chain.prefix + "Rules", [&chain]() {
setLuaSideEffect();
- chain.holder.modify([](std::remove_reference_t<decltype(chain.holder)>::value_type& ruleactions) {
- ruleactions.clear();
+ dnsdist::configuration::updateRuntimeConfiguration([&chain](dnsdist::configuration::RuntimeConfiguration& config) {
+ auto& rules = dnsdist::rules::getRuleChain(config.d_ruleChains, chain.identifier);
+ rules.clear();
});
});
luaCtx.writeFunction("set" + chain.prefix + "Rules", [&chain](const LuaArray<std::shared_ptr<dnsdist::rules::RuleAction>>& newruleactions) {
setLuaSideEffect();
- chain.holder.modify([newruleactions](std::remove_reference_t<decltype(chain.holder)>::value_type& gruleactions) {
- gruleactions.clear();
+ dnsdist::configuration::updateRuntimeConfiguration([&chain, &newruleactions](dnsdist::configuration::RuntimeConfiguration& config) {
+ auto& rules = dnsdist::rules::getRuleChain(config.d_ruleChains, chain.identifier);
+ rules.clear();
for (const auto& pair : newruleactions) {
const auto& newruleaction = pair.second;
if (newruleaction->d_action) {
auto rule = newruleaction->d_rule;
- gruleactions.push_back({std::move(rule), newruleaction->d_action, newruleaction->d_name, newruleaction->d_id, newruleaction->d_creationOrder});
+ rules.push_back({std::move(rule), newruleaction->d_action, newruleaction->d_name, newruleaction->d_id, newruleaction->d_creationOrder});
}
}
});
namespace dnsdist::rules
{
-GlobalStateHolder<std::vector<RuleAction>> s_ruleActions;
-GlobalStateHolder<std::vector<RuleAction>> s_cacheMissRuleActions;
-GlobalStateHolder<std::vector<ResponseRuleAction>> s_respruleactions;
-GlobalStateHolder<std::vector<ResponseRuleAction>> s_cachehitrespruleactions;
-GlobalStateHolder<std::vector<ResponseRuleAction>> s_selfansweredrespruleactions;
-GlobalStateHolder<std::vector<ResponseRuleAction>> s_cacheInsertedRespRuleActions;
-GlobalStateHolder<std::vector<ResponseRuleAction>> s_XFRRespRuleActions;
-
static const std::vector<ResponseRuleChainDescription> s_responseRuleChains{
- {"", "response-rules", s_respruleactions},
- {"CacheHit", "cache-hit-response-rules", s_cachehitrespruleactions},
- {"CacheInserted", "cache-inserted-response-rules", s_selfansweredrespruleactions},
- {"SelfAnswered", "self-answered-response-rules", s_cacheInsertedRespRuleActions},
- {"XFR", "xfr-response-rules", s_XFRRespRuleActions},
+ {"", "response-rules", ResponseRuleChain::ResponseRules},
+ {"CacheHit", "cache-hit-response-rules", ResponseRuleChain::CacheHitResponseRules},
+ {"CacheInserted", "cache-inserted-response-rules", ResponseRuleChain::CacheInsertedResponseRules},
+ {"SelfAnswered", "self-answered-response-rules", ResponseRuleChain::SelfAnsweredResponseRules},
+ {"XFR", "xfr-response-rules", ResponseRuleChain::XFRResponseRules},
};
-const std::vector<ResponseRuleChainDescription>& getResponseRuleChains()
+const std::vector<ResponseRuleChainDescription>& getResponseRuleChainDescriptions()
{
return s_responseRuleChains;
}
-GlobalStateHolder<std::vector<ResponseRuleAction>>& getResponseRuleChainHolder(ResponseRuleChain chain)
-{
- return s_responseRuleChains.at(static_cast<size_t>(chain)).holder;
-}
-
static const std::vector<RuleChainDescription> s_ruleChains{
- {"", "rules", s_ruleActions},
- {"CacheMiss", "cache-miss-rules", s_cacheMissRuleActions},
+ {"", "rules", RuleChain::Rules},
+ {"CacheMiss", "cache-miss-rules", RuleChain::CacheMissRules},
};
-const std::vector<RuleChainDescription>& getRuleChains()
+const std::vector<RuleChainDescription>& getRuleChainDescriptions()
{
return s_ruleChains;
}
-GlobalStateHolder<std::vector<RuleAction>>& getRuleChainHolder(RuleChain chain)
+std::vector<RuleAction>& getRuleChain(RuleChains& chains, RuleChain chain)
+{
+ switch (chain) {
+ case RuleChain::Rules:
+ return chains.d_ruleActions;
+ case RuleChain::CacheMissRules:
+ return chains.d_cacheMissRuleActions;
+ }
+}
+
+const std::vector<RuleAction>& getRuleChain(const RuleChains& chains, RuleChain chain)
+{
+ switch (chain) {
+ case RuleChain::Rules:
+ return chains.d_ruleActions;
+ case RuleChain::CacheMissRules:
+ return chains.d_cacheMissRuleActions;
+ }
+}
+
+std::vector<ResponseRuleAction>& getRuleChain(RuleChains& chains, ResponseRuleChain chain)
+{
+ return getResponseRuleChain(chains, chain);
+}
+
+const std::vector<ResponseRuleAction>& getRuleChain(const RuleChains& chains, ResponseRuleChain chain)
{
- return s_ruleChains.at(static_cast<size_t>(chain)).holder;
+ return getResponseRuleChain(chains, chain);
}
+
+std::vector<ResponseRuleAction>& getResponseRuleChain(RuleChains& chains, ResponseRuleChain chain)
+{
+ switch (chain) {
+ case ResponseRuleChain::ResponseRules:
+ return chains.d_respruleactions;
+ case ResponseRuleChain::CacheHitResponseRules:
+ return chains.d_cachehitrespruleactions;
+ case ResponseRuleChain::CacheInsertedResponseRules:
+ return chains.d_cacheInsertedRespRuleActions;
+ case ResponseRuleChain::SelfAnsweredResponseRules:
+ return chains.d_selfansweredrespruleactions;
+ case ResponseRuleChain::XFRResponseRules:
+ return chains.d_XFRRespRuleActions;
+ }
+}
+
+const std::vector<ResponseRuleAction>& getResponseRuleChain(const RuleChains& chains, ResponseRuleChain chain)
+{
+ switch (chain) {
+ case ResponseRuleChain::ResponseRules:
+ return chains.d_respruleactions;
+ case ResponseRuleChain::CacheHitResponseRules:
+ return chains.d_cachehitrespruleactions;
+ case ResponseRuleChain::CacheInsertedResponseRules:
+ return chains.d_cacheInsertedRespRuleActions;
+ case ResponseRuleChain::SelfAnsweredResponseRules:
+ return chains.d_selfansweredrespruleactions;
+ case ResponseRuleChain::XFRResponseRules:
+ return chains.d_XFRRespRuleActions;
+ }
+}
+
+void add(RuleChains& chains, RuleChain identifier, const std::shared_ptr<DNSRule>& selector, const std::shared_ptr<DNSAction>& action, std::string&& name, const boost::uuids::uuid& uuid, uint64_t creationOrder)
+{
+ auto& chain = getRuleChain(chains, identifier);
+ chain.push_back({selector, action, std::move(name), uuid, creationOrder});
+}
+
+void add(RuleChains& chains, ResponseRuleChain identifier, const std::shared_ptr<DNSRule>& selector, const std::shared_ptr<DNSResponseAction>& action, std::string&& name, const boost::uuids::uuid& uuid, uint64_t creationOrder)
+{
+ auto& chain = getResponseRuleChain(chains, identifier);
+ chain.push_back({selector, action, std::move(name), uuid, creationOrder});
+}
+
}
#include <string>
#include <vector>
-#include "sholder.hh"
#include "uuid-utils.hh"
class DNSRule;
uint64_t d_creationOrder;
};
-struct RuleChainDescription
-{
- std::string prefix;
- std::string metricName;
- GlobalStateHolder<std::vector<RuleAction>>& holder;
-};
-
enum class RuleChain : uint8_t
{
Rules = 0,
CacheMissRules = 1,
};
-const std::vector<RuleChainDescription>& getRuleChains();
-GlobalStateHolder<std::vector<RuleAction>>& getRuleChainHolder(RuleChain chain);
+struct RuleChainDescription
+{
+ const std::string prefix;
+ const std::string metricName;
+ const RuleChain identifier;
+};
struct ResponseRuleAction
{
struct ResponseRuleChainDescription
{
- std::string prefix;
- std::string metricName;
- GlobalStateHolder<std::vector<ResponseRuleAction>>& holder;
+ const std::string prefix;
+ const std::string metricName;
+ const ResponseRuleChain identifier;
};
-const std::vector<ResponseRuleChainDescription>& getResponseRuleChains();
-GlobalStateHolder<std::vector<ResponseRuleAction>>& getResponseRuleChainHolder(ResponseRuleChain chain);
+struct RuleChains
+{
+ std::vector<RuleAction> d_ruleActions;
+ std::vector<RuleAction> d_cacheMissRuleActions;
+ std::vector<ResponseRuleAction> d_respruleactions;
+ std::vector<ResponseRuleAction> d_cachehitrespruleactions;
+ std::vector<ResponseRuleAction> d_selfansweredrespruleactions;
+ std::vector<ResponseRuleAction> d_cacheInsertedRespRuleActions;
+ std::vector<ResponseRuleAction> d_XFRRespRuleActions;
+};
+const std::vector<RuleChainDescription>& getRuleChainDescriptions();
+std::vector<RuleAction>& getRuleChain(RuleChains& chains, RuleChain chain);
+const std::vector<RuleAction>& getRuleChain(const RuleChains& chains, RuleChain chain);
+const std::vector<ResponseRuleChainDescription>& getResponseRuleChainDescriptions();
+std::vector<ResponseRuleAction>& getRuleChain(RuleChains& chains, ResponseRuleChain chain);
+const std::vector<ResponseRuleAction>& getRuleChain(const RuleChains& chains, ResponseRuleChain chain);
+std::vector<ResponseRuleAction>& getResponseRuleChain(RuleChains& chains, ResponseRuleChain chain);
+const std::vector<ResponseRuleAction>& getResponseRuleChain(const RuleChains& chains, ResponseRuleChain chain);
+void add(RuleChains& chains, RuleChain identifier, const std::shared_ptr<DNSRule>& selector, const std::shared_ptr<DNSAction>& action, std::string&& name, const boost::uuids::uuid& uuid, uint64_t creationOrder);
+void add(RuleChains& chains, ResponseRuleChain identifier, const std::shared_ptr<DNSRule>& selector, const std::shared_ptr<DNSResponseAction>& action, std::string&& name, const boost::uuids::uuid& uuid, uint64_t creationOrder);
}
{
public:
TCPClientThreadData():
- localRespRuleActions(dnsdist::rules::getResponseRuleChainHolder(dnsdist::rules::ResponseRuleChain::ResponseRules).getLocal()), localCacheInsertedRespRuleActions(dnsdist::rules::getResponseRuleChainHolder(dnsdist::rules::ResponseRuleChain::CacheInsertedResponseRules).getLocal()), localXFRRespRuleActions(dnsdist::rules::getResponseRuleChainHolder(dnsdist::rules::ResponseRuleChain::XFRResponseRules).getLocal()), mplexer(std::unique_ptr<FDMultiplexer>(FDMultiplexer::getMultiplexerSilent()))
+ mplexer(std::unique_ptr<FDMultiplexer>(FDMultiplexer::getMultiplexerSilent()))
{
}
LocalHolders holders;
- LocalStateHolder<vector<dnsdist::rules::ResponseRuleAction>> localRespRuleActions;
- LocalStateHolder<vector<dnsdist::rules::ResponseRuleAction>> localCacheInsertedRespRuleActions;
- LocalStateHolder<vector<dnsdist::rules::ResponseRuleAction>> localXFRRespRuleActions;
std::unique_ptr<FDMultiplexer> mplexer{nullptr};
pdns::channel::Receiver<ConnectionInfo> queryReceiver;
pdns::channel::Receiver<CrossProtocolQuery> crossProtocolQueryReceiver;
memcpy(&response.d_cleartextDH, dnsResponse.getHeader().get(), sizeof(response.d_cleartextDH));
- if (!processResponse(response.d_buffer, *state->d_threadData.localRespRuleActions, *state->d_threadData.localCacheInsertedRespRuleActions, dnsResponse, false)) {
+ if (!processResponse(response.d_buffer, dnsResponse, false)) {
state->terminateClientConnection();
return;
}
}
}
-static bool processXFRResponse(PacketBuffer& response, const std::vector<dnsdist::rules::ResponseRuleAction>& xfrRespRuleActions, DNSResponse& dnsResponse)
+static bool processXFRResponse(PacketBuffer& response, DNSResponse& dnsResponse)
{
+ const auto& chains = dnsdist::configuration::getCurrentRuntimeConfiguration().d_ruleChains;
+ const auto& xfrRespRuleActions = dnsdist::rules::getResponseRuleChain(chains, dnsdist::rules::ResponseRuleChain::XFRResponseRules);
+
if (!applyRulesToResponse(xfrRespRuleActions, dnsResponse)) {
return false;
}
dnsResponse.d_incomingTCPState = state;
memcpy(&response.d_cleartextDH, dnsResponse.getHeader().get(), sizeof(response.d_cleartextDH));
- if (!processXFRResponse(response.d_buffer, *state->d_threadData.localXFRRespRuleActions, dnsResponse)) {
+ if (!processXFRResponse(response.d_buffer, dnsResponse)) {
state->terminateClientConnection();
return;
}
}
template <typename T>
-static json11::Json::array someResponseRulesToJson(GlobalStateHolder<vector<T>>* someResponseRules)
+static json11::Json::array someResponseRulesToJson(const std::vector<T>& someResponseRules)
{
using namespace json11;
Json::array responseRules;
int num = 0;
- auto localResponseRules = someResponseRules->getLocal();
- responseRules.reserve(localResponseRules->size());
- for (const auto& rule : *localResponseRules) {
+ responseRules.reserve(someResponseRules.size());
+ for (const auto& rule : someResponseRules) {
responseRules.emplace_back(Json::object{
{"id", num++},
{"creationOrder", static_cast<double>(rule.d_creationOrder)},
#ifndef DISABLE_PROMETHEUS
template <typename T>
-static void addRulesToPrometheusOutput(std::ostringstream& output, GlobalStateHolder<vector<T>>& rules)
+static void addRulesToPrometheusOutput(std::ostringstream& output, const std::vector<T>& rules)
{
- auto localRules = rules.getLocal();
- for (const auto& entry : *localRules) {
+ for (const auto& entry : rules) {
std::string identifier = !entry.d_name.empty() ? entry.d_name : boost::uuids::to_string(entry.d_id);
output << "dnsdist_rule_hits{id=\"" << identifier << "\"} " << entry.d_rule->d_matches << "\n";
}
output << "# HELP dnsdist_rule_hits " << "Number of hits of that rule" << "\n";
output << "# TYPE dnsdist_rule_hits " << "counter" << "\n";
- for (const auto& chain : dnsdist::rules::getRuleChains()) {
- addRulesToPrometheusOutput(output, chain.holder);
+ const auto& chains = dnsdist::configuration::getCurrentRuntimeConfiguration().d_ruleChains;
+ for (const auto& chainDescription : dnsdist::rules::getRuleChainDescriptions()) {
+ const auto& chain = dnsdist::rules::getRuleChain(chains, chainDescription.identifier);
+ addRulesToPrometheusOutput(output, chain);
}
- for (const auto& chain : dnsdist::rules::getResponseRuleChains()) {
- addRulesToPrometheusOutput(output, chain.holder);
+ for (const auto& chainDescription : dnsdist::rules::getResponseRuleChainDescriptions()) {
+ const auto& chain = dnsdist::rules::getResponseRuleChain(chains, chainDescription.identifier);
+ addRulesToPrometheusOutput(output, chain);
}
#ifndef DISABLE_DYNBLOCKS
/* unfortunately DNSActions have getStats(),
and DNSResponseActions do not. */
- for (const auto& chain : dnsdist::rules::getRuleChains()) {
+ const auto& chains = dnsdist::configuration::getCurrentRuntimeConfiguration().d_ruleChains;
+ for (const auto& chainDescription : dnsdist::rules::getRuleChainDescriptions()) {
Json::array rules;
- auto localRules = chain.holder.getLocal();
+ const auto& chain = dnsdist::rules::getRuleChain(chains, chainDescription.identifier);
num = 0;
- rules.reserve(localRules->size());
- for (const auto& lrule : *localRules) {
+ rules.reserve(chain.size());
+ for (const auto& lrule : chain) {
Json::object rule{
{"id", num++},
{"creationOrder", (double)lrule.d_creationOrder},
{"action-stats", lrule.d_action->getStats()}};
rules.emplace_back(std::move(rule));
}
- responseObject[chain.metricName] = std::move(rules);
+ responseObject[chainDescription.metricName] = std::move(rules);
}
- for (const auto& chain : dnsdist::rules::getResponseRuleChains()) {
- auto responseRules = someResponseRulesToJson(&chain.holder);
- responseObject[chain.metricName] = std::move(responseRules);
+ for (const auto& chainDescription : dnsdist::rules::getResponseRuleChainDescriptions()) {
+ const auto& chain = dnsdist::rules::getResponseRuleChain(chains, chainDescription.identifier);
+ auto responseRules = someResponseRulesToJson(chain);
+ responseObject[chainDescription.metricName] = std::move(responseRules);
}
resp.headers["Content-Type"] = "application/json";
{
try {
setThreadName("dnsdist/XskResp");
- auto localRespRuleActions = dnsdist::rules::getResponseRuleChainHolder(dnsdist::rules::ResponseRuleChain::ResponseRules).getLocal();
- auto localCacheInsertedRespRuleActions = dnsdist::rules::getResponseRuleChainHolder(dnsdist::rules::ResponseRuleChain::CacheInsertedResponseRules).getLocal();
auto pollfds = getPollFdsForWorker(*xskInfo);
while (!dss->isStopped()) {
poll(pollfds.data(), pollfds.size(), -1);
/* fallback to sending the packet via normal socket */
ids->xskPacketHeader.clear();
}
- if (!processResponderPacket(dss, response, *localRespRuleActions, *localCacheInsertedRespRuleActions, std::move(*ids))) {
+ if (!processResponderPacket(dss, response, std::move(*ids))) {
xskInfo->markAsFree(packet);
vinfolog("XSK packet dropped because processResponderPacket failed");
return;
}
}
-bool XskIsQueryAcceptable(const XskPacket& packet, ClientState& clientState, LocalHolders& holders, bool& expectProxyProtocol)
+bool XskIsQueryAcceptable(const XskPacket& packet, ClientState& clientState, bool& expectProxyProtocol)
{
const auto& from = packet.getFromAddr();
expectProxyProtocol = expectProxyProtocolFrom(from);
namespace dnsdist::xsk
{
void XskResponderThread(std::shared_ptr<DownstreamState> dss, std::shared_ptr<XskWorker> xskInfo);
-bool XskIsQueryAcceptable(const XskPacket& packet, ClientState& clientState, LocalHolders& holders, bool& expectProxyProtocol);
+bool XskIsQueryAcceptable(const XskPacket& packet, ClientState& clientState, bool& expectProxyProtocol);
bool XskProcessQuery(ClientState& clientState, LocalHolders& holders, XskPacket& packet);
void XskRouter(std::shared_ptr<XskSocket> xsk);
void XskClientThread(ClientState* clientState);
return true;
}
-bool processResponseAfterRules(PacketBuffer& response, const std::vector<dnsdist::rules::ResponseRuleAction>& cacheInsertedRespRuleActions, DNSResponse& dnsResponse, bool muted)
+bool processResponseAfterRules(PacketBuffer& response, DNSResponse& dnsResponse, bool muted)
{
bool zeroScope = false;
if (!fixUpResponse(response, dnsResponse.ids.qname, dnsResponse.ids.origFlags, dnsResponse.ids.ednsAdded, dnsResponse.ids.ecsAdded, dnsResponse.ids.useZeroScope ? &zeroScope : nullptr)) {
dnsResponse.ids.packetCache->insert(cacheKey, zeroScope ? boost::none : dnsResponse.ids.subnet, dnsResponse.ids.cacheFlags, dnsResponse.ids.dnssecOK, dnsResponse.ids.qname, dnsResponse.ids.qtype, dnsResponse.ids.qclass, response, dnsResponse.ids.forwardedOverUDP, dnsResponse.getHeader()->rcode, dnsResponse.ids.tempFailureTTL);
+ const auto& chains = dnsdist::configuration::getCurrentRuntimeConfiguration().d_ruleChains;
+ const auto& cacheInsertedRespRuleActions = dnsdist::rules::getResponseRuleChain(chains, dnsdist::rules::ResponseRuleChain::CacheInsertedResponseRules);
if (!applyRulesToResponse(cacheInsertedRespRuleActions, dnsResponse)) {
return false;
}
return true;
}
-bool processResponse(PacketBuffer& response, const std::vector<dnsdist::rules::ResponseRuleAction>& respRuleActions, const std::vector<dnsdist::rules::ResponseRuleAction>& cacheInsertedRespRuleActions, DNSResponse& dnsResponse, bool muted)
+bool processResponse(PacketBuffer& response, DNSResponse& dnsResponse, bool muted)
{
+ const auto& chains = dnsdist::configuration::getCurrentRuntimeConfiguration().d_ruleChains;
+ const auto& respRuleActions = dnsdist::rules::getResponseRuleChain(chains, dnsdist::rules::ResponseRuleChain::ResponseRules);
+
if (!applyRulesToResponse(respRuleActions, dnsResponse)) {
return false;
}
return true;
}
- return processResponseAfterRules(response, cacheInsertedRespRuleActions, dnsResponse, muted);
+ return processResponseAfterRules(response, dnsResponse, muted);
}
static size_t getInitialUDPPacketBufferSize(bool expectProxyProtocol)
doLatencyStats(incomingProtocol, udiff);
}
-static void handleResponseForUDPClient(InternalQueryState& ids, PacketBuffer& response, const std::vector<dnsdist::rules::ResponseRuleAction>& respRuleActions, const std::vector<dnsdist::rules::ResponseRuleAction>& cacheInsertedRespRuleActions, const std::shared_ptr<DownstreamState>& backend, bool isAsync, bool selfGenerated)
+static void handleResponseForUDPClient(InternalQueryState& ids, PacketBuffer& response, const std::shared_ptr<DownstreamState>& backend, bool isAsync, bool selfGenerated)
{
DNSResponse dnsResponse(ids, response, backend);
memcpy(&cleartextDH, dnsResponse.getHeader().get(), sizeof(cleartextDH));
if (!isAsync) {
- if (!processResponse(response, respRuleActions, cacheInsertedRespRuleActions, dnsResponse, ids.cs != nullptr && ids.cs->muted)) {
+ if (!processResponse(response, dnsResponse, ids.cs != nullptr && ids.cs->muted)) {
return;
}
}
}
-bool processResponderPacket(std::shared_ptr<DownstreamState>& dss, PacketBuffer& response, const std::vector<dnsdist::rules::ResponseRuleAction>& localRespRuleActions, const std::vector<dnsdist::rules::ResponseRuleAction>& cacheInsertedRespRuleActions, InternalQueryState&& ids)
+bool processResponderPacket(std::shared_ptr<DownstreamState>& dss, PacketBuffer& response, InternalQueryState&& ids)
{
const dnsheader_aligned dnsHeader(response.data());
return false;
}
- handleResponseForUDPClient(ids, response, localRespRuleActions, cacheInsertedRespRuleActions, dss, false, false);
+ handleResponseForUDPClient(ids, response, dss, false, false);
return true;
}
{
try {
setThreadName("dnsdist/respond");
- auto localRespRuleActions = dnsdist::rules::getResponseRuleChainHolder(dnsdist::rules::ResponseRuleChain::ResponseRules).getLocal();
- auto localCacheInsertedRespRuleActions = dnsdist::rules::getResponseRuleChainHolder(dnsdist::rules::ResponseRuleChain::CacheInsertedResponseRules).getLocal();
const size_t initialBufferSize = getInitialUDPPacketBufferSize(false);
/* allocate one more byte so we can detect truncation */
PacketBuffer response(initialBufferSize + 1);
continue;
}
- if (processResponderPacket(dss, response, *localRespRuleActions, *localCacheInsertedRespRuleActions, std::move(*ids)) && ids->isXSK() && ids->cs->xskInfoResponder) {
+ if (processResponderPacket(dss, response, std::move(*ids)) && ids->isXSK() && ids->cs->xskInfoResponder) {
#ifdef HAVE_XSK
auto& xskInfo = ids->cs->xskInfoResponder;
auto xskPacket = xskInfo->getEmptyFrame();
}
#endif /* DISABLE_DYNBLOCKS */
- return applyRulesChainToQuery(*holders.ruleactions, dnsQuestion);
+ const auto& chains = dnsdist::configuration::getCurrentRuntimeConfiguration().d_ruleChains;
+ const auto& queryRules = dnsdist::rules::getRuleChain(chains, dnsdist::rules::RuleChain::Rules);
+ return applyRulesChainToQuery(queryRules, dnsQuestion);
}
ssize_t udpClientSendRequestToBackend(const std::shared_ptr<DownstreamState>& backend, const int socketDesc, const PacketBuffer& request, bool healthCheck)
#endif
/* self-generated responses or cache hits */
-static bool prepareOutgoingResponse(LocalHolders& holders, const ClientState& clientState, DNSQuestion& dnsQuestion, bool cacheHit)
+static bool prepareOutgoingResponse(const ClientState& clientState, DNSQuestion& dnsQuestion, bool cacheHit)
{
std::shared_ptr<DownstreamState> backend{nullptr};
DNSResponse dnsResponse(dnsQuestion.ids, dnsQuestion.getMutableData(), backend);
dnsResponse.d_incomingTCPState = dnsQuestion.d_incomingTCPState;
dnsResponse.ids.selfGenerated = true;
- if (!applyRulesToResponse(cacheHit ? *holders.cacheHitRespRuleactions : *holders.selfAnsweredRespRuleactions, dnsResponse)) {
+ const auto& chains = dnsdist::configuration::getCurrentRuntimeConfiguration().d_ruleChains;
+ const auto& cacheHitRespRules = dnsdist::rules::getResponseRuleChain(chains, dnsdist::rules::ResponseRuleChain::CacheHitResponseRules);
+ const auto& selfAnsweredRespRules = dnsdist::rules::getResponseRuleChain(chains, dnsdist::rules::ResponseRuleChain::SelfAnsweredResponseRules);
+ if (!applyRulesToResponse(cacheHit ? cacheHitRespRules : selfAnsweredRespRules, dnsResponse)) {
return false;
}
return true;
}
-static ProcessQueryResult handleQueryTurnedIntoSelfAnsweredResponse(DNSQuestion& dnsQuestion, LocalHolders& holders)
+static ProcessQueryResult handleQueryTurnedIntoSelfAnsweredResponse(DNSQuestion& dnsQuestion)
{
fixUpQueryTurnedResponse(dnsQuestion, dnsQuestion.ids.origFlags);
- if (!prepareOutgoingResponse(holders, *dnsQuestion.ids.cs, dnsQuestion, false)) {
+ if (!prepareOutgoingResponse(*dnsQuestion.ids.cs, dnsQuestion, false)) {
return ProcessQueryResult::Drop;
}
try {
if (dnsQuestion.getHeader()->qr) { // something turned it into a response
- return handleQueryTurnedIntoSelfAnsweredResponse(dnsQuestion, holders);
+ return handleQueryTurnedIntoSelfAnsweredResponse(dnsQuestion);
}
std::shared_ptr<ServerPool> serverPool = getPool(dnsQuestion.ids.poolName);
dnsQuestion.ids.packetCache = serverPool->packetCache;
vinfolog("Packet cache hit for query for %s|%s from %s (%s, %d bytes)", dnsQuestion.ids.qname.toLogString(), QType(dnsQuestion.ids.qtype).toString(), dnsQuestion.ids.origRemote.toStringWithPort(), dnsQuestion.ids.protocol.toString(), dnsQuestion.getData().size());
- if (!prepareOutgoingResponse(holders, *dnsQuestion.ids.cs, dnsQuestion, true)) {
+ if (!prepareOutgoingResponse(*dnsQuestion.ids.cs, dnsQuestion, true)) {
return ProcessQueryResult::Drop;
}
vinfolog("Packet cache hit for query for %s|%s from %s (%s, %d bytes)", dnsQuestion.ids.qname.toLogString(), QType(dnsQuestion.ids.qtype).toString(), dnsQuestion.ids.origRemote.toStringWithPort(), dnsQuestion.ids.protocol.toString(), dnsQuestion.getData().size());
- if (!prepareOutgoingResponse(holders, *dnsQuestion.ids.cs, dnsQuestion, true)) {
+ if (!prepareOutgoingResponse(*dnsQuestion.ids.cs, dnsQuestion, true)) {
return ProcessQueryResult::Drop;
}
if (dnsQuestion.ids.protocol == dnsdist::Protocol::DoH && !forwardedOverUDP) {
/* do a second-lookup for UDP responses, but we do not want TC=1 answers */
if (dnsQuestion.ids.packetCache->get(dnsQuestion, dnsQuestion.getHeader()->id, &dnsQuestion.ids.cacheKeyUDP, dnsQuestion.ids.subnet, dnsQuestion.ids.dnssecOK, true, allowExpired, false, false, true)) {
- if (!prepareOutgoingResponse(holders, *dnsQuestion.ids.cs, dnsQuestion, true)) {
+ if (!prepareOutgoingResponse(*dnsQuestion.ids.cs, dnsQuestion, true)) {
return ProcessQueryResult::Drop;
}
++dnsdist::metrics::g_stats.cacheMisses;
const auto existingPool = dnsQuestion.ids.poolName;
- if (!applyRulesChainToQuery(*holders.cacheMissRuleActions, dnsQuestion)) {
+ const auto& chains = dnsdist::configuration::getCurrentRuntimeConfiguration().d_ruleChains;
+ const auto& cacheMissRuleActions = dnsdist::rules::getRuleChain(chains, dnsdist::rules::RuleChain::CacheMissRules);
+
+ if (!applyRulesChainToQuery(cacheMissRuleActions, dnsQuestion)) {
return ProcessQueryResult::Drop;
}
if (dnsQuestion.getHeader()->qr) { // something turned it into a response
- return handleQueryTurnedIntoSelfAnsweredResponse(dnsQuestion, holders);
+ return handleQueryTurnedIntoSelfAnsweredResponse(dnsQuestion);
}
/* let's be nice and allow the selection of a different pool,
but no second cache-lookup for you */
fixUpQueryTurnedResponse(dnsQuestion, dnsQuestion.ids.origFlags);
- if (!prepareOutgoingResponse(holders, *dnsQuestion.ids.cs, dnsQuestion, false)) {
+ if (!prepareOutgoingResponse(*dnsQuestion.ids.cs, dnsQuestion, false)) {
return ProcessQueryResult::Drop;
}
++dnsdist::metrics::g_stats.responses;
auto& ids = response.d_idstate;
- static thread_local LocalStateHolder<vector<dnsdist::rules::ResponseRuleAction>> localRespRuleActions = dnsdist::rules::getResponseRuleChainHolder(dnsdist::rules::ResponseRuleChain::ResponseRules).getLocal();
- static thread_local LocalStateHolder<vector<dnsdist::rules::ResponseRuleAction>> localCacheInsertedRespRuleActions = dnsdist::rules::getResponseRuleChainHolder(dnsdist::rules::ResponseRuleChain::CacheInsertedResponseRules).getLocal();
-
- handleResponseForUDPClient(ids, response.d_buffer, *localRespRuleActions, *localCacheInsertedRespRuleActions, response.d_ds, response.isAsync(), response.d_idstate.selfGenerated);
+ handleResponseForUDPClient(ids, response.d_buffer, response.d_ds, response.isAsync(), response.d_idstate.selfGenerated);
}
void handleXFRResponse(const struct timeval& now, TCPResponse&& response) override
try {
bool expectProxyProtocol = false;
- if (!XskIsQueryAcceptable(packet, clientState, holders, expectProxyProtocol)) {
+ if (!XskIsQueryAcceptable(packet, clientState, expectProxyProtocol)) {
return false;
}
{
/* when our coverage mode is enabled, we need to make sure
that the Lua objects are destroyed before the Lua contexts. */
- for (const auto& chain : dnsdist::rules::getRuleChains()) {
- chain.holder.setState({});
- }
- for (const auto& chain : dnsdist::rules::getResponseRuleChains()) {
- chain.holder.setState({});
- }
dnsdist::configuration::updateRuntimeConfiguration([](dnsdist::configuration::RuntimeConfiguration& config) {
+ config.d_ruleChains = dnsdist::rules::RuleChains();
config.d_lbPolicy = std::make_shared<ServerPolicy>();
config.d_pools.clear();
config.d_backends.clear();
struct LocalHolders
{
LocalHolders() :
- 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()), dynNMGBlock(g_dynblockNMG.getLocal()), dynSMTBlock(g_dynblockSMT.getLocal())
+ dynNMGBlock(g_dynblockNMG.getLocal()), dynSMTBlock(g_dynblockSMT.getLocal())
{
}
- LocalStateHolder<vector<dnsdist::rules::RuleAction>> ruleactions;
- LocalStateHolder<vector<dnsdist::rules::RuleAction>> cacheMissRuleActions;
- LocalStateHolder<vector<dnsdist::rules::ResponseRuleAction>> cacheHitRespRuleactions;
- LocalStateHolder<vector<dnsdist::rules::ResponseRuleAction>> cacheInsertedRespRuleActions;
- LocalStateHolder<vector<dnsdist::rules::ResponseRuleAction>> selfAnsweredRespRuleactions;
LocalStateHolder<NetmaskTree<DynBlock, AddressAndPortRange>> dynNMGBlock;
LocalStateHolder<SuffixMatchTree<DynBlock>> dynSMTBlock;
};
ProcessQueryResult processQuery(DNSQuestion& dnsQuestion, LocalHolders& holders, std::shared_ptr<DownstreamState>& selectedBackend);
ProcessQueryResult processQueryAfterRules(DNSQuestion& dnsQuestion, LocalHolders& holders, std::shared_ptr<DownstreamState>& selectedBackend);
-bool processResponse(PacketBuffer& response, const std::vector<dnsdist::rules::ResponseRuleAction>& respRuleActions, const std::vector<dnsdist::rules::ResponseRuleAction>& cacheInsertedRespRuleActions, DNSResponse& dnsResponse, bool muted);
+bool processResponse(PacketBuffer& response, DNSResponse& dnsResponse, bool muted);
bool processRulesResult(const DNSAction::Action& action, DNSQuestion& dnsQuestion, std::string& ruleresult, bool& drop);
-bool processResponseAfterRules(PacketBuffer& response, const std::vector<dnsdist::rules::ResponseRuleAction>& cacheInsertedRespRuleActions, DNSResponse& dnsResponse, bool muted);
-bool processResponderPacket(std::shared_ptr<DownstreamState>& dss, PacketBuffer& response, const std::vector<dnsdist::rules::ResponseRuleAction>& localRespRuleActions, const std::vector<dnsdist::rules::ResponseRuleAction>& cacheInsertedRespRuleActions, InternalQueryState&& ids);
+bool processResponseAfterRules(PacketBuffer& response, DNSResponse& dnsResponse, bool muted);
+bool processResponderPacket(std::shared_ptr<DownstreamState>& dss, PacketBuffer& response, InternalQueryState&& ids);
bool applyRulesToResponse(const std::vector<dnsdist::rules::ResponseRuleAction>& respRuleActions, DNSResponse& dnsResponse);
bool assignOutgoingUDPQueryToBackend(std::shared_ptr<DownstreamState>& downstream, uint16_t queryID, DNSQuestion& dnsQuestion, PacketBuffer& query, bool actuallySend = true);
memcpy(&cleartextDH, dr.getHeader().get(), sizeof(cleartextDH));
if (!response.isAsync()) {
- static thread_local LocalStateHolder<vector<dnsdist::rules::ResponseRuleAction>> localRespRuleActions = dnsdist::rules::getResponseRuleChainHolder(dnsdist::rules::ResponseRuleChain::ResponseRules).getLocal();
- static thread_local LocalStateHolder<vector<dnsdist::rules::ResponseRuleAction>> localCacheInsertedRespRuleActions = dnsdist::rules::getResponseRuleChainHolder(dnsdist::rules::ResponseRuleChain::CacheInsertedResponseRules).getLocal();
-
dr.ids.du = std::move(dohUnit);
- if (!processResponse(dynamic_cast<DOHUnit*>(dr.ids.du.get())->response, *localRespRuleActions, *localCacheInsertedRespRuleActions, dr, false)) {
+ if (!processResponse(dynamic_cast<DOHUnit*>(dr.ids.du.get())->response, dr, false)) {
if (dr.ids.du) {
dohUnit = getDUFromIDS(dr.ids);
dohUnit->status_code = 503;
}
}
if (!dohUnit->truncated) {
- static thread_local LocalStateHolder<vector<dnsdist::rules::ResponseRuleAction>> localRespRuleActions = dnsdist::rules::getResponseRuleChainHolder(dnsdist::rules::ResponseRuleChain::ResponseRules).getLocal();
- static thread_local LocalStateHolder<vector<dnsdist::rules::ResponseRuleAction>> localCacheInsertedRespRuleActions = dnsdist::rules::getResponseRuleChainHolder(dnsdist::rules::ResponseRuleChain::CacheInsertedResponseRules).getLocal();
-
DNSResponse dnsResponse(dohUnit->ids, udpResponse, dohUnit->downstream);
dnsheader cleartextDH{};
memcpy(&cleartextDH, dnsResponse.getHeader().get(), sizeof(cleartextDH));
dnsResponse.ids.du = std::move(dohUnit);
- if (!processResponse(udpResponse, *localRespRuleActions, *localCacheInsertedRespRuleActions, dnsResponse, false)) {
+ if (!processResponse(udpResponse, dnsResponse, false)) {
if (dnsResponse.ids.du) {
dohUnit = getDUFromIDS(dnsResponse.ids);
dohUnit->status_code = 503;
if (!response.isAsync()) {
- static thread_local LocalStateHolder<vector<dnsdist::rules::ResponseRuleAction>> localRespRuleActions = dnsdist::rules::getResponseRuleChainHolder(dnsdist::rules::ResponseRuleChain::ResponseRules).getLocal();
- static thread_local LocalStateHolder<vector<dnsdist::rules::ResponseRuleAction>> localCacheInsertedRespRuleActions = dnsdist::rules::getResponseRuleChainHolder(dnsdist::rules::ResponseRuleChain::CacheInsertedResponseRules).getLocal();
-
dnsResponse.ids.doh3u = std::move(unit);
- if (!processResponse(dnsResponse.ids.doh3u->response, *localRespRuleActions, *localCacheInsertedRespRuleActions, dnsResponse, false)) {
+ if (!processResponse(dnsResponse.ids.doh3u->response, dnsResponse, false)) {
if (dnsResponse.ids.doh3u) {
sendBackDOH3Unit(std::move(dnsResponse.ids.doh3u), "Response dropped by rules");
memcpy(&cleartextDH, dnsResponse.getHeader().get(), sizeof(cleartextDH));
if (!response.isAsync()) {
-
- static thread_local LocalStateHolder<vector<dnsdist::rules::ResponseRuleAction>> localRespRuleActions = dnsdist::rules::getResponseRuleChainHolder(dnsdist::rules::ResponseRuleChain::ResponseRules).getLocal();
- static thread_local LocalStateHolder<vector<dnsdist::rules::ResponseRuleAction>> localCacheInsertedRespRuleActions = dnsdist::rules::getResponseRuleChainHolder(dnsdist::rules::ResponseRuleChain::CacheInsertedResponseRules).getLocal();
-
dnsResponse.ids.doqu = std::move(unit);
- if (!processResponse(dnsResponse.ids.doqu->response, *localRespRuleActions, *localCacheInsertedRespRuleActions, dnsResponse, false)) {
+ if (!processResponse(dnsResponse.ids.doqu->response, dnsResponse, false)) {
if (dnsResponse.ids.doqu) {
sendBackDOQUnit(std::move(dnsResponse.ids.doqu), "Response dropped by rules");
testPool->packetCache = packetCache;
std::string poolWithNoCacheName("test-pool-without-cache");
auto testPoolWithNoCache = std::make_shared<ServerPool>();
- dnsdist::configuration::updateRuntimeConfiguration([&poolName,&testPool,&poolWithNoCacheName,&testPoolWithNoCache](dnsdist::configuration::RuntimeConfiguration& config) {
+ dnsdist::configuration::updateRuntimeConfiguration([&poolName, &testPool, &poolWithNoCacheName, &testPoolWithNoCache](dnsdist::configuration::RuntimeConfiguration& config) {
config.d_pools.emplace(poolName, testPool);
config.d_pools.emplace(poolWithNoCacheName, testPoolWithNoCache);
});
return ProcessQueryResult::Drop;
}
-bool processResponseAfterRules(PacketBuffer& response, const std::vector<dnsdist::rules::ResponseRuleAction>& cacheInsertedRespRuleActions, DNSResponse& dnsResponse, bool muted)
+bool processResponseAfterRules(PacketBuffer& response, DNSResponse& dnsResponse, bool muted)
{
return false;
}
}
#endif /* HAVE_XSK */
-bool processResponderPacket(std::shared_ptr<DownstreamState>& dss, PacketBuffer& response, const std::vector<dnsdist::rules::ResponseRuleAction>& localRespRuleActions, const std::vector<dnsdist::rules::ResponseRuleAction>& cacheInsertedRespRuleActions, InternalQueryState&& ids)
+bool processResponderPacket(std::shared_ptr<DownstreamState>& dss, PacketBuffer& response, InternalQueryState&& ids)
{
return false;
}
static std::function<bool(PacketBuffer& response, DNSResponse& dr, bool muted)> s_processResponse;
-bool processResponse(PacketBuffer& response, const std::vector<dnsdist::rules::ResponseRuleAction>& respRuleActions, const std::vector<dnsdist::rules::ResponseRuleAction>& cacheInsertedRespRuleActions, DNSResponse& dnsResponse, bool muted)
+bool processResponse(PacketBuffer& response, DNSResponse& dnsResponse, bool muted)
{
if (s_processResponse) {
return s_processResponse(response, dnsResponse, muted);