From: Remi Gacogne Date: Fri, 25 Sep 2020 14:32:22 +0000 (+0200) Subject: dnsdist: Rename topRule() and friends X-Git-Tag: auth-4.4.0-alpha3~3^2~1 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=cf1eab43115889c4531291d3478e3b054b6f3883;p=thirdparty%2Fpdns.git dnsdist: Rename topRule() and friends --- diff --git a/pdns/dnsdist-console.cc b/pdns/dnsdist-console.cc index efabac2788..f7980ad227 100644 --- a/pdns/dnsdist-console.cc +++ b/pdns/dnsdist-console.cc @@ -409,6 +409,10 @@ const std::vector g_consoleKeywords{ { "getServer", true, "id", "returns server with index 'n' or whose uuid matches if 'id' is an UUID string" }, { "getServers", true, "", "returns a table with all defined servers" }, { "getStatisticsCounters", true, "", "returns a map of statistic counters" }, + { "getTopCacheHitResponseRules", true, "[top]", "return the `top` cache-hit response rules" }, + { "getTopResponseRules", true, "[top]", "return the `top` response rules" }, + { "getTopRules", true, "[top]", "return the `top` rules" }, + { "getTopSelfAnsweredResponseRules", true, "[top]", "return the `top` self-answered response rules" }, { "getTLSContext", true, "n", "returns the TLS context with index n" }, { "getTLSFrontend", true, "n", "returns the TLS frontend with index n" }, { "getTLSFrontendCount", true, "", "returns the number of DoT listeners" }, @@ -441,9 +445,13 @@ const std::vector g_consoleKeywords{ { "MaxQPSIPRule", true, "qps, [v4Mask=32 [, v6Mask=64 [, burst=qps [, expiration=300 [, cleanupDelay=60]]]]]", "matches traffic exceeding the qps limit per subnet" }, { "MaxQPSRule", true, "qps", "matches traffic **not** exceeding this qps limit" }, { "mvCacheHitResponseRule", true, "from, to", "move cache hit response rule 'from' to a position where it is in front of 'to'. 'to' can be one larger than the largest rule" }, + { "mvCacheHitResponseRuleToTop", true, "", "move the last cache hit response rule to the first position" }, { "mvResponseRule", true, "from, to", "move response rule 'from' to a position where it is in front of 'to'. 'to' can be one larger than the largest rule" }, + { "mvResponseRuleToTop", true, "", "move the last response rule to the first position" }, { "mvRule", true, "from, to", "move rule 'from' to a position where it is in front of 'to'. 'to' can be one larger than the largest rule, in which case the rule will be moved to the last position" }, + { "mvRuleToTop", true, "", "move the last rule to the first position" }, { "mvSelfAnsweredResponseRule", true, "from, to", "move self-answered response rule 'from' to a position where it is in front of 'to'. 'to' can be one larger than the largest rule" }, + { "mvSelfAnsweredResponseRuleToTop", true, "", "move the last self-answered response rule to the first position" }, { "NetmaskGroupRule", true, "nmg[, src]", "Matches traffic from/to the network range specified in nmg. Set the src parameter to false to match nmg against destination address instead of source address. This can be used to differentiate between clients" }, { "newBPFFilter", true, "maxV4, maxV6, maxQNames", "Return a new eBPF socket filter with a maximum of maxV4 IPv4, maxV6 IPv6 and maxQNames qname entries in the block table" }, { "newCA", true, "address", "Returns a ComboAddress based on `address`" }, @@ -600,13 +608,13 @@ const std::vector g_consoleKeywords{ { "testCrypto", true, "", "test of the crypto all works" }, { "TimedIPSetRule", true, "", "Create a rule which matches a set of IP addresses which expire"}, { "topBandwidth", true, "top", "show top-`top` clients that consume the most bandwidth over length of ringbuffer" }, - { "topCacheHitResponseRule", true, "", "move the last cache hit response rule to the first position" }, + { "topCacheHitResponseRules", true, "[top][, vars]", "show `top` cache-hit response rules" }, { "topClients", true, "n", "show top-`n` clients sending the most queries over length of ringbuffer" }, { "topQueries", true, "n[, labels]", "show top 'n' queries, as grouped when optionally cut down to 'labels' labels" }, { "topResponses", true, "n, kind[, labels]", "show top 'n' responses with RCODE=kind (0=NO Error, 2=ServFail, 3=NXDomain), as grouped when optionally cut down to 'labels' labels" }, - { "topResponseRule", true, "", "move the last response rule to the first position" }, - { "topRule", true, "", "move the last rule to the first position" }, - { "topSelfAnsweredResponseRule", true, "", "move the last self-answered response rule to the first position" }, + { "topResponseRules", true, "[top][, vars]", "show `top` response rules" }, + { "topRules", true, "[top][, vars]", "show `top` rules" }, + { "topSelfAnsweredResponseRules", true, "[top][, vars]", "show `top` self-answered response rules" }, { "topSlow", true, "[top][, limit][, labels]", "show `top` queries slower than `limit` milliseconds, grouped by last `labels` labels" }, { "TrailingDataRule", true, "", "Matches if the query has trailing data" }, { "truncateTC", true, "bool", "if set (defaults to no starting with dnsdist 1.2.0) truncate TC=1 answers so they are actually empty. Fixes an issue for PowerDNS Authoritative Server 2.9.22. Note: turning this on breaks compatibility with RFC 6891." }, diff --git a/pdns/dnsdist-lua-rules.cc b/pdns/dnsdist-lua-rules.cc index 4307b0d131..54b65e770b 100644 --- a/pdns/dnsdist-lua-rules.cc +++ b/pdns/dnsdist-lua-rules.cc @@ -86,11 +86,12 @@ void parseRuleParams(boost::optional params, boost::uuids::uuid typedef std::unordered_map > > > ruleparams_t; template -static void showRules(GlobalStateHolder > *someRulActions, boost::optional vars) { - setLuaNoSideEffect(); - int num=0; +static std::string rulesToString(const std::vector& rules, boost::optional vars) +{ + int num = 0; bool showUUIDs = false; size_t truncateRuleWidth = string::npos; + std::string result; if (vars) { if (vars->count("showUUIDs")) { @@ -101,25 +102,33 @@ static void showRules(GlobalStateHolder > *someRulActions, boost::opti } } - auto rules = someRulActions->getLocal(); if (showUUIDs) { boost::format fmt("%-3d %-38s %9d %9d %-56s %s\n"); - g_outputBuffer += (fmt % "#" % "UUID" % "Cr. Order" % "Matches" % "Rule" % "Action").str(); - for(const auto& lim : *rules) { + result += (fmt % "#" % "UUID" % "Cr. Order" % "Matches" % "Rule" % "Action").str(); + for(const auto& lim : rules) { string name = lim.d_rule->toString().substr(0, truncateRuleWidth); - g_outputBuffer += (fmt % num % boost::uuids::to_string(lim.d_id) % lim.d_creationOrder % lim.d_rule->d_matches % name % lim.d_action->toString()).str(); + result += (fmt % num % boost::uuids::to_string(lim.d_id) % lim.d_creationOrder % lim.d_rule->d_matches % name % lim.d_action->toString()).str(); ++num; } } else { boost::format fmt("%-3d %9d %-56s %s\n"); - g_outputBuffer += (fmt % "#" % "Matches" % "Rule" % "Action").str(); - for(const auto& lim : *rules) { + result += (fmt % "#" % "Matches" % "Rule" % "Action").str(); + for(const auto& lim : rules) { string name = lim.d_rule->toString().substr(0, truncateRuleWidth); - g_outputBuffer += (fmt % num % lim.d_rule->d_matches % name % lim.d_action->toString()).str(); + result += (fmt % num % lim.d_rule->d_matches % name % lim.d_action->toString()).str(); ++num; } } + return result; +} + +template +static void showRules(GlobalStateHolder > *someRulActions, boost::optional vars) { + setLuaNoSideEffect(); + + auto rules = someRulActions->getLocal(); + g_outputBuffer += rulesToString(*rules, vars); } template @@ -147,7 +156,7 @@ static void rmRule(GlobalStateHolder > *someRulActions, boost::variant } template -static void topRule(GlobalStateHolder > *someRulActions) { +static void moveRuleToTop(GlobalStateHolder > *someRulActions) { setLuaSideEffect(); auto rules = someRulActions->getCopy(); if(rules.empty()) @@ -178,6 +187,38 @@ static void mvRule(GlobalStateHolder > *someRespRulActions, unsigned i someRespRulActions->setState(std::move(rules)); } +template +static std::vector getTopRules(const std::vector& rules, unsigned int top) +{ + std::vector> counts; + counts.reserve(rules.size()); + + size_t pos = 0; + for (const auto& rule : rules) { + counts.push_back({rule.d_rule->d_matches.load(), pos}); + pos++; + } + + sort(counts.begin(), counts.end(), [](const decltype(counts)::value_type& a, + const decltype(counts)::value_type& b) { + return b.first < a.first; + }); + + std::vector results; + results.reserve(top); + + size_t count = 0; + for (const auto& entry : counts) { + results.emplace_back(rules.at(entry.second)); + ++count; + if (count == top) { + break; + } + } + + return results; +} + void setupLuaRules(LuaContext& luaCtx) { luaCtx.writeFunction("makeRule", makeRule); @@ -192,8 +233,8 @@ void setupLuaRules(LuaContext& luaCtx) rmRule(&g_resprulactions, id); }); - luaCtx.writeFunction("topResponseRule", []() { - topRule(&g_resprulactions); + luaCtx.writeFunction("mvResponseRuleToTop", []() { + moveRuleToTop(&g_resprulactions); }); luaCtx.writeFunction("mvResponseRule", [](unsigned int from, unsigned int to) { @@ -208,8 +249,8 @@ void setupLuaRules(LuaContext& luaCtx) rmRule(&g_cachehitresprulactions, id); }); - luaCtx.writeFunction("topCacheHitResponseRule", []() { - topRule(&g_cachehitresprulactions); + luaCtx.writeFunction("mvCacheHitResponseRuleToTop", []() { + moveRuleToTop(&g_cachehitresprulactions); }); luaCtx.writeFunction("mvCacheHitResponseRule", [](unsigned int from, unsigned int to) { @@ -224,8 +265,8 @@ void setupLuaRules(LuaContext& luaCtx) rmRule(&g_selfansweredresprulactions, id); }); - luaCtx.writeFunction("topSelfAnsweredResponseRule", []() { - topRule(&g_selfansweredresprulactions); + luaCtx.writeFunction("mvSelfAnsweredResponseRuleToTop", []() { + moveRuleToTop(&g_selfansweredresprulactions); }); luaCtx.writeFunction("mvSelfAnsweredResponseRule", [](unsigned int from, unsigned int to) { @@ -236,8 +277,8 @@ void setupLuaRules(LuaContext& luaCtx) rmRule(&g_rulactions, id); }); - luaCtx.writeFunction("topRule", []() { - topRule(&g_rulactions); + luaCtx.writeFunction("mvRuleToTop", []() { + moveRuleToTop(&g_rulactions); }); luaCtx.writeFunction("mvRule", [](unsigned int from, unsigned int to) { @@ -265,6 +306,54 @@ void setupLuaRules(LuaContext& luaCtx) }); }); + luaCtx.writeFunction("getTopRules", [](boost::optional top) { + setLuaNoSideEffect(); + auto rules = g_rulactions.getLocal(); + return getTopRules(*rules, top.get_value_or(10)); + }); + + luaCtx.writeFunction("topRules", [](boost::optional top, boost::optional vars) { + setLuaNoSideEffect(); + auto rules = g_rulactions.getLocal(); + return rulesToString(getTopRules(*rules, top.get_value_or(10)), vars); + }); + + luaCtx.writeFunction("getCacheHitResponseRules", [](boost::optional top) { + setLuaNoSideEffect(); + auto rules = g_cachehitresprulactions.getLocal(); + return getTopRules(*rules, top.get_value_or(10)); + }); + + luaCtx.writeFunction("topCacheHitRules", [](boost::optional top, boost::optional vars) { + setLuaNoSideEffect(); + auto rules = g_cachehitresprulactions.getLocal(); + return rulesToString(getTopRules(*rules, top.get_value_or(10)), vars); + }); + + luaCtx.writeFunction("getTopResponseRules", [](boost::optional top) { + setLuaNoSideEffect(); + auto rules = g_resprulactions.getLocal(); + return getTopRules(*rules, top.get_value_or(10)); + }); + + luaCtx.writeFunction("topResponseRules", [](boost::optional top, boost::optional vars) { + setLuaNoSideEffect(); + auto rules = g_resprulactions.getLocal(); + return rulesToString(getTopRules(*rules, top.get_value_or(10)), vars); + }); + + luaCtx.writeFunction("getTopSelfAnsweredResponseRules", [](boost::optional top) { + setLuaNoSideEffect(); + auto rules = g_selfansweredresprulactions.getLocal(); + return getTopRules(*rules, top.get_value_or(10)); + }); + + luaCtx.writeFunction("topSelfAnsweredResponseRules", [](boost::optional top, boost::optional vars) { + setLuaNoSideEffect(); + auto rules = g_selfansweredresprulactions.getLocal(); + return rulesToString(getTopRules(*rules, top.get_value_or(10)), vars); + }); + luaCtx.writeFunction("MaxQPSIPRule", [](unsigned int qps, boost::optional ipv4trunc, boost::optional ipv6trunc, boost::optional burst, boost::optional expiration, boost::optional cleanupDelay, boost::optional scanFraction) { return std::shared_ptr(new MaxQPSIPRule(qps, burst.get_value_or(qps), ipv4trunc.get_value_or(32), ipv6trunc.get_value_or(64), expiration.get_value_or(300), cleanupDelay.get_value_or(60), scanFraction.get_value_or(10))); }); diff --git a/pdns/dnsdistdist/docs/reference/config.rst b/pdns/dnsdistdist/docs/reference/config.rst index 359c50877e..f8b44df759 100644 --- a/pdns/dnsdistdist/docs/reference/config.rst +++ b/pdns/dnsdistdist/docs/reference/config.rst @@ -864,6 +864,38 @@ Status, Statistics and More Return the number of TLSFrontend binds. +.. function:: getTopCacheHitResponseRules([top]) + + .. versionadded:: 1.6.0 + + Return the `top` cache-hit response rules that matched the most. + + :param int top: How many response rules to return. + +.. function:: getTopResponseRules([top]) + + .. versionadded:: 1.6.0 + + Return the `top` response rules that matched the most. + + :param int top: How many response rules to return. + +.. function:: getTopRules([top]) + + .. versionadded:: 1.6.0 + + Return the `top` rules that matched the most. + + :param int top: How many rules to return. + +.. function:: getTopSelfAnsweredRules([top]) + + .. versionadded:: 1.6.0 + + Return the `top` self-answered rules that matched the most. + + :param int top: How many rules to return. + .. function:: grepq(selector[, num]) grepq(selectors[, num]) @@ -959,6 +991,19 @@ Status, Statistics and More :param int num: Number to show, defaults to 10. +.. function:: topCacheHitResponseRules([top [, options]]) + + .. versionadded:: 1.6.0 + + This function shows the cache-hit response rules having matched the most. + + :param int top: How many rules to show. + :param table options: A table with key: value pairs with display options. + + Options: + + * ``showUUIDs=false``: bool - Whether to display the UUIDs, defaults to false. + .. function:: topClients([num]) Print the top ``num`` clients sending the most queries over length of ringbuffer @@ -982,6 +1027,45 @@ Status, Statistics and More :param int rcode: :ref:`Response code `, defaults to 0 (No Error) :param int label: Number of labels to cut down to +.. function:: topResponseRules([top [, options]]) + + .. versionadded:: 1.6.0 + + This function shows the response rules having matched the most. + + :param int top: How many rules to show. + :param table options: A table with key: value pairs with display options. + + Options: + + * ``showUUIDs=false``: bool - Whether to display the UUIDs, defaults to false. + +.. function:: topRules([top [, options]]) + + .. versionadded:: 1.6.0 + + This function shows the rules having matched the most. + + :param int top: How many rules to show. + :param table options: A table with key: value pairs with display options. + + Options: + + * ``showUUIDs=false``: bool - Whether to display the UUIDs, defaults to false. + +.. function:: topSelfAnsweredResponseRules([top [, options]]) + + .. versionadded:: 1.6.0 + + This function shows the self-answered response rules having matched the most. + + :param int top: How many rules to show. + :param table options: A table with key: value pairs with display options. + + Options: + + * ``showUUIDs=false``: bool - Whether to display the UUIDs, defaults to false. + .. function:: topSlow([num[, limit[, labels]]]) Print the ``num`` slowest queries that are slower than ``limit`` milliseconds. diff --git a/pdns/dnsdistdist/docs/rules-actions.rst b/pdns/dnsdistdist/docs/rules-actions.rst index 2d5055c71f..2239566ffe 100644 --- a/pdns/dnsdistdist/docs/rules-actions.rst +++ b/pdns/dnsdistdist/docs/rules-actions.rst @@ -313,6 +313,12 @@ For Rules related to the incoming query: :param int from: Rule number to move :param int to: Location to more the Rule to +.. function:: mvRuleToTop() + + .. versionadded:: 1.6.0 + + This function moves the last rule to the first position. Before 1.6.0 this was handled by :func:`topRule`. + .. function:: newRuleAction(rule, action[, options]) .. versionchanged:: 1.3.0 @@ -350,7 +356,10 @@ For Rules related to the incoming query: .. function:: topRule() - Move the last rule to the first position. + .. versionchanged:: 1.6.0 + Replaced by :func:`mvRuleToTop` + + Before 1.6.0 this functions used to move the last rule to the first position, which is now handled by :func:`mvRuleToTop`. .. function:: rmRule(id) @@ -386,6 +395,12 @@ For Rules related to responses: :param int from: Rule number to move :param int to: Location to more the Rule to +.. function:: mvResponseRuleToTop() + + .. versionadded:: 1.6.0 + + This function moves the last response rule to the first position. Before 1.6.0 this was handled by :func:`topResponseRule`. + .. function:: rmResponseRule(id) .. versionchanged:: 1.3.0 @@ -411,7 +426,10 @@ For Rules related to responses: .. function:: topResponseRule() - Move the last response rule to the first position. + .. versionchanged:: 1.6.0 + Replaced by :func:`mvResponseRuleToTop` + + Before 1.6.0, this function used to move the last response rule to the first position, which is now handled by :func:`mvResponseRuleToTop`. Functions for manipulating Cache Hit Response Rules: @@ -442,6 +460,12 @@ Functions for manipulating Cache Hit Response Rules: :param int from: Rule number to move :param int to: Location to more the Rule to +.. function:: mvCacheHitResponseRuleToTop() + + .. versionadded:: 1.6.0 + + This function moves the last cache hit response rule to the first position. Before 1.6.0 this was handled by :func:`topCacheHitResponseRule`. + .. function:: rmCacheHitResponseRule(id) .. versionadded:: 1.2.0 @@ -471,7 +495,10 @@ Functions for manipulating Cache Hit Response Rules: .. versionadded:: 1.2.0 - Move the last cache hit response rule to the first position. + .. versionchanged:: 1.6.0 + Replaced by :func:`mvCacheHitResponseRuleToTop` + + Before 1.6.0, this function used to move the last cache hit response rule to the first position, which is now handled by :func:`mvCacheHitResponseRuleToTop`. Functions for manipulating Self-Answered Response Rules: @@ -494,6 +521,12 @@ Functions for manipulating Self-Answered Response Rules: :param int from: Rule number to move :param int to: Location to more the Rule to +.. function:: mvSelfAnsweredResponseRuleToTop() + + .. versionadded:: 1.6.0 + + This function moves the last self-answered response rule to the first position. Before 1.6.0 this was handled by :func:`topSelfAnsweredResponseRule`. + .. function:: rmSelfAnsweredResponseRule(id) .. versionadded:: 1.3.0 @@ -519,6 +552,11 @@ Functions for manipulating Self-Answered Response Rules: .. versionadded:: 1.3.0 + .. versionchanged:: 1.6.0 + Replaced by :func:`mvSelfAnsweredResponseRuleToTop` + + Before 1.6.0 this function used to move the last cache hit response rule to the first position, which is now handled by :func:`mvSelfAnsweredResponseRuleToTop`. + Move the last self answered response rule to the first position. .. _RulesIntro: