- `NetmaskGroupRule` now accepts a string or list of strings, instead of requiring the use of `newNMG`
- `SuffixMatchNodeRule` also accepts a string or list of strings, instead of requiring the use of `newSuffixMatchNode`
- Passing a string or list of strings to `addAction` is now deprecated
- `makeRule` is now deprecated
parseRuleParams(params, uuid, name, creationOrder);
checkAllParametersConsumed("addAction", params);
- auto rule = makeRule(var);
+ 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), std::move(uuid), creationOrder});
});
parseRuleParams(params, uuid, name, creationOrder);
checkAllParametersConsumed("newRuleAction", params);
- auto rule = makeRule(dnsrule);
+ auto rule = makeRule(dnsrule, "newRuleAction");
DNSDistRuleAction ra({std::move(rule), std::move(action), std::move(name), uuid, creationOrder});
return std::make_shared<DNSDistRuleAction>(ra);
});
#include "dnsdist-rules.hh"
#include "dns_random.hh"
-std::shared_ptr<DNSRule> makeRule(const luadnsrule_t& var)
+std::shared_ptr<DNSRule> makeRule(const luadnsrule_t& var, const std::string& calledFrom)
{
- if (var.type() == typeid(std::shared_ptr<DNSRule>))
+ if (var.type() == typeid(std::shared_ptr<DNSRule>)) {
return *boost::get<std::shared_ptr<DNSRule>>(&var);
+ }
+ bool suffixSeen = false;
SuffixMatchNode smn;
NetmaskGroup nmg;
- auto add=[&](string src) {
+ auto add = [&nmg, &smn, &suffixSeen](string src) {
try {
nmg.addMask(src); // need to try mask first, all masks are domain names!
- } catch(...) {
+ } catch (...) {
+ suffixSeen = true;
smn.add(DNSName(src));
}
};
- if (var.type() == typeid(string))
+ if (var.type() == typeid(string)) {
add(*boost::get<string>(&var));
-
- else if (var.type() == typeid(LuaArray<std::string>))
- for(const auto& a : *boost::get<LuaArray<std::string>>(&var))
- add(a.second);
-
- else if (var.type() == typeid(DNSName))
+ }
+ else if (var.type() == typeid(LuaArray<std::string>)) {
+ for (const auto& str : *boost::get<LuaArray<std::string>>(&var)) {
+ add(str.second);
+ }
+ }
+ else if (var.type() == typeid(DNSName)) {
smn.add(*boost::get<DNSName>(&var));
+ }
+ else if (var.type() == typeid(LuaArray<DNSName>)) {
+ smn = SuffixMatchNode();
+ for (const auto& name : *boost::get<LuaArray<DNSName>>(&var)) {
+ smn.add(name.second);
+ }
+ }
- else if (var.type() == typeid(LuaArray<DNSName>))
- for(const auto& a : *boost::get<LuaArray<DNSName>>(&var))
- smn.add(a.second);
-
- if(nmg.empty())
+ if (nmg.empty()) {
return std::make_shared<SuffixMatchNodeRule>(smn);
- else
- return std::make_shared<NetmaskGroupRule>(nmg, true);
+ }
+ if (suffixSeen) {
+ warnlog("At least one parameter to %s has been parsed as a domain name amongst network masks, and will be ignored!", calledFrom);
+ }
+ return std::make_shared<NetmaskGroupRule>(nmg, true);
}
static boost::uuids::uuid makeRuleID(std::string& id)
void setupLuaRules(LuaContext& luaCtx)
{
- luaCtx.writeFunction("makeRule", makeRule);
+ luaCtx.writeFunction("makeRule", [](const luadnsrule_t& var) -> std::shared_ptr<DNSRule> {
+ return makeRule(var, "makeRule");
+ });
luaCtx.registerFunction<string(std::shared_ptr<DNSRule>::*)()const>("toString", [](const std::shared_ptr<DNSRule>& rule) { return rule->toString(); });
for (const auto& pair : newruleactions) {
const auto& newruleaction = pair.second;
if (newruleaction->d_action) {
- auto rule = makeRule(newruleaction->d_rule);
+ auto rule = newruleaction->d_rule;
gruleactions.push_back({std::move(rule), newruleaction->d_action, newruleaction->d_name, newruleaction->d_id, newruleaction->d_creationOrder});
}
}
return std::shared_ptr<DNSRule>(new SNIRule(name));
});
- luaCtx.writeFunction("SuffixMatchNodeRule", [](const SuffixMatchNode& smn, boost::optional<bool> quiet) {
+ luaCtx.writeFunction("SuffixMatchNodeRule", [](const boost::variant<const SuffixMatchNode&, std::string, const LuaArray<std::string>> names, boost::optional<bool> quiet) {
+ if (names.type() == typeid(string)) {
+ SuffixMatchNode smn;
+ smn.add(DNSName(*boost::get<std::string>(&names)));
return std::shared_ptr<DNSRule>(new SuffixMatchNodeRule(smn, quiet ? *quiet : false));
- });
+ }
- luaCtx.writeFunction("NetmaskGroupRule", [](const NetmaskGroup& nmg, boost::optional<bool> src, boost::optional<bool> quiet) {
+ if (names.type() == typeid(LuaArray<std::string>)) {
+ SuffixMatchNode smn;
+ for (const auto& str : *boost::get<const LuaArray<std::string>>(&names)) {
+ smn.add(DNSName(str.second));
+ }
+ return std::shared_ptr<DNSRule>(new SuffixMatchNodeRule(smn, quiet ? *quiet : false));
+ }
+
+ const auto& smn = *boost::get<const SuffixMatchNode&>(&names);
+ return std::shared_ptr<DNSRule>(new SuffixMatchNodeRule(smn, quiet ? *quiet : false));
+ });
+
+ luaCtx.writeFunction("NetmaskGroupRule", [](const boost::variant<const NetmaskGroup&, std::string, const LuaArray<std::string>> netmasks, boost::optional<bool> src, boost::optional<bool> quiet) {
+ if (netmasks.type() == typeid(string)) {
+ NetmaskGroup nmg;
+ nmg.addMask(*boost::get<std::string>(&netmasks));
return std::shared_ptr<DNSRule>(new NetmaskGroupRule(nmg, src ? *src : true, quiet ? *quiet : false));
- });
+ }
+
+ if (netmasks.type() == typeid(LuaArray<std::string>)) {
+ NetmaskGroup nmg;
+ for (const auto& str : *boost::get<const LuaArray<std::string>>(&netmasks)) {
+ nmg.addMask(str.second);
+ }
+ return std::shared_ptr<DNSRule>(new NetmaskGroupRule(nmg, src ? *src : true, quiet ? *quiet : false));
+ }
+
+ const auto& nmg = *boost::get<const NetmaskGroup&>(&netmasks);
+ return std::shared_ptr<DNSRule>(new NetmaskGroupRule(nmg, src ? *src : true, quiet ? *quiet : false));
+ });
luaCtx.writeFunction("benchRule", [](std::shared_ptr<DNSRule> rule, boost::optional<unsigned int> times_, boost::optional<string> suffix_) {
setLuaNoSideEffect();
template <class T> using LuaAssociativeTable = std::unordered_map<std::string, T>;
template <class T> using LuaTypeOrArrayOf = boost::variant<T, LuaArray<T>>;
-using luadnsrule_t = boost::variant<string, LuaArray<std::string>, std::shared_ptr<DNSRule>, DNSName, LuaArray<DNSName>>;
using luaruleparams_t = LuaAssociativeTable<std::string>;
using nmts_t = NetmaskTree<DynBlock, AddressAndPortRange>;
-std::shared_ptr<DNSRule> makeRule(const luadnsrule_t& var);
+using luadnsrule_t = boost::variant<string, LuaArray<std::string>, std::shared_ptr<DNSRule>, DNSName, LuaArray<DNSName>>;
+std::shared_ptr<DNSRule> makeRule(const luadnsrule_t& var, const std::string& calledFrom);
+
void parseRuleParams(boost::optional<luaruleparams_t>& params, boost::uuids::uuid& uuid, std::string& name, uint64_t& creationOrder);
void checkParameterBound(const std::string& parameter, uint64_t value, size_t max = std::numeric_limits<uint16_t>::max());
Alternatively, if compiled in, :func:`RE2Rule` provides similar functionality, but against libre2.
Note that to check if a name is in a list of domains, :func:`SuffixMatchNodeRule` is preferred over complex regular expressions or multiple instances of :func:`RegexRule`.
-The :func:`makeRule` convenience function can be used to create a :func:`SuffixMatchNodeRule`.
Rule Generators
---------------
.. versionchanged:: 1.6.0
Added ``name`` to the ``options``.
+ .. versionchanged:: 1.9.0
+ Passing a string or list of strings instead of a :class:`DNSRule` is deprecated, use :func:`NetmaskGroupRule` or :func:`SuffixMatchNodeRule` instead
+
Add a Rule and Action to the existing rules.
+ If a string (or list of) is passed as the first parameter instead of a :class:`DNSRule`, it behaves as if the string or list of strings was passed to :func:`NetmaskGroupRule` or :func:`SuffixMatchNodeRule`.
- :param DNSrule rule: A DNSRule, e.g. an :func:`AllRule` or a compounded bunch of rules using e.g. :func:`AndRule`
+ :param DNSrule rule: A :class:`DNSRule`, e.g. an :func:`AllRule`, a compounded bunch of rules using e.g. :func:`AndRule`, or a string (or list of) (deprecated since 1.9.0)
:param action: The action to take
:param table options: A table with key: value pairs with options.
.. versionchanged:: 1.4.0
``quiet`` parameter added
- Matches traffic from/to the network range specified in ``nmg``.
+ .. versionchanged:: 1.9.0
+ The ``nmg`` parameter now accepts a string or a list of strings in addition to a class:`NetmaskGroup` object.
+
+ Matches traffic from/to the network range specified in the ``nmg``, which can be a string, a list of strings,
+ or a :class:`NetmaskGroup` object created via :func:`newNMG`.
Set the ``src`` parameter to false to match ``nmg`` against destination address instead of source address.
This can be used to differentiate between clients
- :param NetMaskGroup nmg: The NetMaskGroup to match on
+ :param NetmaskGroup nmg: The netmasks to match, can be a string, a list of strings or a :class:`NetmaskGroup` object.
:param bool src: Whether to match source or destination address of the packet. Defaults to true (matches source)
:param bool quiet: Do not display the list of matched netmasks in Rules. Default is false.
.. function:: SuffixMatchNodeRule(smn[, quiet])
+ .. versionchanged:: 1.9.0
+ The ``smn`` parameter now accepts a string or a list of strings in addition to a class:`SuffixMatchNode` object.
+
Matches based on a group of domain suffixes for rapid testing of membership.
+ The first parameter, ``smn``, can be a string, list of strings or a class:`SuffixMatchNode` object created with :func:`newSuffixMatchNode`.
Pass true as second parameter to prevent listing of all domains matched.
To match domain names exactly, see :func:`QNameSetRule`.
- :param SuffixMatchNode smn: The SuffixMatchNode to match on
+ :param SuffixMatchNode smn: A string, list of strings, or a :class:`SuffixMatchNode` to match on
:param bool quiet: Do not display the list of matched domains in Rules. Default is false.
.. function:: TagRule(name [, value])
.. function:: makeRule(rule)
- Make a :func:`NetmaskGroupRule` or a :func:`SuffixMatchNodeRule`, depending on it is called.
+ .. versionchanged:: 1.9.0
+ This function is deprecated, please use :func:`NetmaskGroupRule` or :func:`SuffixMatchNodeRule` instead
+
+ Make a :func:`NetmaskGroupRule` or a :func:`SuffixMatchNodeRule`, depending on how it is called.
+ The `rule` parameter can be a string, or a list of strings, that should contain either:
+
+ * netmasks: in which case it will behave as :func:`NetmaskGroupRule`, or
+ * domain names: in which case it will behave as :func:`SuffixMatchNodeRule`
+
+ Mixing both netmasks and domain names is not supported, and will result in domain names being ignored!
+
``makeRule("0.0.0.0/0")`` will for example match all IPv4 traffic, ``makeRule({"be","nl","lu"})`` will match all Benelux DNS traffic.
- :param string rule: A string to convert to a rule.
+ :param string rule: A string, or list of strings, to convert to a rule.
Actions