summaryrefslogtreecommitdiffstats
path: root/dnsdist-lua-inspection.cc
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--dnsdist-lua-inspection.cc158
1 files changed, 106 insertions, 52 deletions
diff --git a/dnsdist-lua-inspection.cc b/dnsdist-lua-inspection.cc
index 4fac0e3..ba7dfdb 100644
--- a/dnsdist-lua-inspection.cc
+++ b/dnsdist-lua-inspection.cc
@@ -19,6 +19,8 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
+#include <fcntl.h>
+
#include "dnsdist.hh"
#include "dnsdist-lua.hh"
#include "dnsdist-dynblocks.hh"
@@ -136,17 +138,13 @@ static void statNodeRespRing(statvisitor_t visitor, uint64_t seconds)
continue;
}
- bool hit = c.ds.sin4.sin_family == 0;
- if (!hit && c.ds.isIPv4() && c.ds.sin4.sin_addr.s_addr == 0 && c.ds.sin4.sin_port == 0) {
- hit = true;
- }
-
+ const bool hit = c.isACacheHit();
root.submit(c.name, ((c.dh.rcode == 0 && c.usec == std::numeric_limits<unsigned int>::max()) ? -1 : c.dh.rcode), c.size, hit, boost::none);
}
}
StatNode::Stat node;
- root.visit([visitor](const StatNode* node_, const StatNode::Stat& self, const StatNode::Stat& children) {
+ root.visit([visitor = std::move(visitor)](const StatNode* node_, const StatNode::Stat& self, const StatNode::Stat& children) {
visitor(*node_, self, children);}, node);
}
@@ -408,38 +406,59 @@ void setupLuaInspection(LuaContext& luaCtx)
}
});
- luaCtx.writeFunction("grepq", [](LuaTypeOrArrayOf<std::string> inp, boost::optional<unsigned int> limit) {
+ luaCtx.writeFunction("grepq", [](LuaTypeOrArrayOf<std::string> inp, boost::optional<unsigned int> limit, boost::optional<LuaAssociativeTable<std::string>> options) {
setLuaNoSideEffect();
boost::optional<Netmask> nm;
boost::optional<DNSName> dn;
- int msec=-1;
+ int msec = -1;
+ pdns::UniqueFilePtr outputFile{nullptr};
+
+ if (options) {
+ std::string outputFileName;
+ if (getOptionalValue<std::string>(options, "outputFile", outputFileName) > 0) {
+ int fd = open(outputFileName.c_str(), O_CREAT | O_EXCL | O_WRONLY, 0600);
+ if (fd < 0) {
+ g_outputBuffer = "Error opening dump file for writing: " + stringerror() + "\n";
+ return;
+ }
+ outputFile = pdns::UniqueFilePtr(fdopen(fd, "w"));
+ if (outputFile == nullptr) {
+ g_outputBuffer = "Error opening dump file for writing: " + stringerror() + "\n";
+ close(fd);
+ return;
+ }
+ }
+ checkAllParametersConsumed("grepq", options);
+ }
vector<string> vec;
- auto str=boost::get<string>(&inp);
- if(str)
+ auto str = boost::get<string>(&inp);
+ if (str) {
vec.push_back(*str);
+ }
else {
auto v = boost::get<LuaArray<std::string>>(inp);
- for(const auto& a: v)
+ for (const auto& a: v) {
vec.push_back(a.second);
+ }
}
- for(const auto& s : vec) {
- try
- {
+ for (const auto& s : vec) {
+ try {
nm = Netmask(s);
- }
- catch(...) {
- if(boost::ends_with(s,"ms") && sscanf(s.c_str(), "%ums", &msec)) {
+ }
+ catch (...) {
+ if (boost::ends_with(s,"ms") && sscanf(s.c_str(), "%ums", &msec)) {
;
}
else {
- try { dn=DNSName(s); }
- catch(...)
- {
- g_outputBuffer = "Could not parse '"+s+"' as domain name or netmask";
- return;
- }
+ try {
+ dn = DNSName(s);
+ }
+ catch (...) {
+ g_outputBuffer = "Could not parse '"+s+"' as domain name or netmask";
+ return;
+ }
}
}
}
@@ -477,12 +496,19 @@ void setupLuaInspection(LuaContext& luaCtx)
std::multimap<struct timespec, string> out;
- boost::format fmt("%-7.1f %-47s %-12s %-12s %-5d %-25s %-5s %-6.1f %-2s %-2s %-2s %-s\n");
- g_outputBuffer+= (fmt % "Time" % "Client" % "Protocol" % "Server" % "ID" % "Name" % "Type" % "Lat." % "TC" % "RD" % "AA" % "Rcode").str();
+ boost::format fmt("%-7.1f %-47s %-12s %-12s %-5d %-25s %-5s %-6.1f %-2s %-2s %-2s %-s\n");
+ const auto headLine = (fmt % "Time" % "Client" % "Protocol" % "Server" % "ID" % "Name" % "Type" % "Lat." % "TC" % "RD" % "AA" % "Rcode").str();
+ if (!outputFile) {
+ g_outputBuffer += headLine;
+ }
+ else {
+ fprintf(outputFile.get(), "%s", headLine.c_str());
+ }
- if(msec==-1) {
- for(const auto& c : qr) {
- bool nmmatch=true, dnmatch=true;
+ if (msec == -1) {
+ for (const auto& c : qr) {
+ bool nmmatch = true;
+ bool dnmatch = true;
if (nm) {
nmmatch = nm->match(c.requestor);
}
@@ -502,17 +528,19 @@ void setupLuaInspection(LuaContext& luaCtx)
}
out.emplace(c.when, (fmt % DiffTime(now, c.when) % c.requestor.toStringWithPort() % dnsdist::Protocol(c.protocol).toString() % "" % htons(c.dh.id) % c.name.toString() % qt.toString() % "" % (c.dh.tc ? "TC" : "") % (c.dh.rd ? "RD" : "") % (c.dh.aa ? "AA" : "") % ("Question" + extra)).str());
- if(limit && *limit==++num)
+ if (limit && *limit == ++num) {
break;
+ }
}
}
}
- num=0;
-
+ num = 0;
string extra;
- for(const auto& c : rr) {
- bool nmmatch=true, dnmatch=true, msecmatch=true;
+ for (const auto& c : rr) {
+ bool nmmatch = true;
+ bool dnmatch = true;
+ bool msecmatch = true;
if (nm) {
nmmatch = nm->match(c.requestor);
}
@@ -525,13 +553,13 @@ void setupLuaInspection(LuaContext& luaCtx)
}
}
if (msec != -1) {
- msecmatch=(c.usec/1000 > (unsigned int)msec);
+ msecmatch = (c.usec/1000 > (unsigned int)msec);
}
if (nmmatch && dnmatch && msecmatch) {
QType qt(c.qtype);
if (!c.dh.rcode) {
- extra=". " +std::to_string(htons(c.dh.ancount))+ " answers";
+ extra = ". " +std::to_string(htons(c.dh.ancount)) + " answers";
}
else {
extra.clear();
@@ -556,8 +584,13 @@ void setupLuaInspection(LuaContext& luaCtx)
}
}
- for(const auto& p : out) {
- g_outputBuffer+=p.second;
+ for (const auto& p : out) {
+ if (!outputFile) {
+ g_outputBuffer += p.second;
+ }
+ else {
+ fprintf(outputFile.get(), "%s", p.second.c_str());
+ }
}
});
@@ -596,14 +629,14 @@ void setupLuaInspection(LuaContext& luaCtx)
return;
}
- g_outputBuffer = (boost::format("Average response latency: %.02f msec\n") % (0.001*totlat/size)).str();
+ g_outputBuffer = (boost::format("Average response latency: %.02f ms\n") % (0.001*totlat/size)).str();
double highest=0;
for(auto iter = histo.cbegin(); iter != histo.cend(); ++iter) {
highest=std::max(highest, iter->second*1.0);
}
boost::format fmt("%7.2f\t%s\n");
- g_outputBuffer += (fmt % "msec" % "").str();
+ g_outputBuffer += (fmt % "ms" % "").str();
for(auto iter = histo.cbegin(); iter != histo.cend(); ++iter) {
int stars = (70.0 * iter->second/highest);
@@ -669,7 +702,7 @@ void setupLuaInspection(LuaContext& luaCtx)
errorCounters = &f->tlsFrontend->d_tlsCounters;
}
else if (f->dohFrontend != nullptr) {
- errorCounters = &f->dohFrontend->d_tlsCounters;
+ errorCounters = &f->dohFrontend->d_tlsContext.d_tlsCounters;
}
if (errorCounters == nullptr) {
continue;
@@ -691,7 +724,9 @@ void setupLuaInspection(LuaContext& luaCtx)
luaCtx.writeFunction("requestDoHStatesDump", [] {
setLuaNoSideEffect();
+#if defined(HAVE_DNS_OVER_HTTPS) && defined(HAVE_NGHTTP2)
g_dohStatesDumpRequested += g_dohClientThreads->getThreadsCount();
+#endif
});
luaCtx.writeFunction("dumpStats", [] {
@@ -700,7 +735,7 @@ void setupLuaInspection(LuaContext& luaCtx)
boost::format fmt("%-35s\t%+11s");
g_outputBuffer.clear();
- auto entries = *g_stats.entries.read_lock();
+ auto entries = *dnsdist::metrics::g_stats.entries.read_lock();
sort(entries.begin(), entries.end(),
[](const decltype(entries)::value_type& a, const decltype(entries)::value_type& b) {
return a.d_name < b.d_name;
@@ -708,16 +743,16 @@ void setupLuaInspection(LuaContext& luaCtx)
boost::format flt(" %9.1f");
for (const auto& entry : entries) {
string second;
- if (const auto& val = boost::get<pdns::stat_t*>(&entry.d_value)) {
+ if (const auto& val = std::get_if<pdns::stat_t*>(&entry.d_value)) {
second = std::to_string((*val)->load());
}
- else if (const auto& adval = boost::get<pdns::stat_t_trait<double>*>(&entry.d_value)) {
+ else if (const auto& adval = std::get_if<pdns::stat_t_trait<double>*>(&entry.d_value)) {
second = (flt % (*adval)->load()).str();
}
- else if (const auto& dval = boost::get<double*>(&entry.d_value)) {
+ else if (const auto& dval = std::get_if<double*>(&entry.d_value)) {
second = (flt % (**dval)).str();
}
- else if (const auto& func = boost::get<DNSDistStats::statfunction_t>(&entry.d_value)) {
+ else if (const auto& func = std::get_if<dnsdist::metrics::Stats::statfunction_t>(&entry.d_value)) {
second = std::to_string((*func)(entry.d_name));
}
@@ -780,10 +815,10 @@ void setupLuaInspection(LuaContext& luaCtx)
luaCtx.writeFunction("getRespRing", getRespRing);
/* StatNode */
- luaCtx.registerFunction<StatNode, unsigned int()>("numChildren",
- [](StatNode& sn) -> unsigned int {
- return sn.children.size();
- } );
+ luaCtx.registerFunction<unsigned int(StatNode::*)()const>("numChildren",
+ [](const StatNode& sn) -> unsigned int {
+ return sn.children.size();
+ } );
luaCtx.registerMember("fullname", &StatNode::fullname);
luaCtx.registerMember("labelsCount", &StatNode::labelsCount);
luaCtx.registerMember("servfails", &StatNode::Stat::servfails);
@@ -795,7 +830,7 @@ void setupLuaInspection(LuaContext& luaCtx)
luaCtx.registerMember("hits", &StatNode::Stat::hits);
luaCtx.writeFunction("statNodeRespRing", [](statvisitor_t visitor, boost::optional<uint64_t> seconds) {
- statNodeRespRing(visitor, seconds ? *seconds : 0U);
+ statNodeRespRing(std::move(visitor), seconds ? *seconds : 0U);
});
#endif /* DISABLE_DEPRECATED_DYNBLOCK */
@@ -813,12 +848,17 @@ void setupLuaInspection(LuaContext& luaCtx)
});
luaCtx.registerFunction<void(std::shared_ptr<DynBlockRulesGroup>::*)(unsigned int, const std::string&, unsigned int, boost::optional<DNSAction::Action>, DynBlockRulesGroup::smtVisitor_t)>("setSuffixMatchRule", [](std::shared_ptr<DynBlockRulesGroup>& group, unsigned int seconds, const std::string& reason, unsigned int blockDuration, boost::optional<DNSAction::Action> action, DynBlockRulesGroup::smtVisitor_t visitor) {
if (group) {
- group->setSuffixMatchRule(seconds, reason, blockDuration, action ? *action : DNSAction::Action::None, visitor);
+ group->setSuffixMatchRule(seconds, reason, blockDuration, action ? *action : DNSAction::Action::None, std::move(visitor));
}
});
luaCtx.registerFunction<void(std::shared_ptr<DynBlockRulesGroup>::*)(unsigned int, const std::string&, unsigned int, boost::optional<DNSAction::Action>, dnsdist_ffi_stat_node_visitor_t)>("setSuffixMatchRuleFFI", [](std::shared_ptr<DynBlockRulesGroup>& group, unsigned int seconds, const std::string& reason, unsigned int blockDuration, boost::optional<DNSAction::Action> action, dnsdist_ffi_stat_node_visitor_t visitor) {
if (group) {
- group->setSuffixMatchRuleFFI(seconds, reason, blockDuration, action ? *action : DNSAction::Action::None, visitor);
+ group->setSuffixMatchRuleFFI(seconds, reason, blockDuration, action ? *action : DNSAction::Action::None, std::move(visitor));
+ }
+ });
+ luaCtx.registerFunction<void(std::shared_ptr<DynBlockRulesGroup>::*)(const dnsdist_ffi_dynamic_block_inserted_hook&)>("setNewBlockInsertedHook", [](std::shared_ptr<DynBlockRulesGroup>& group, const dnsdist_ffi_dynamic_block_inserted_hook& hook) {
+ if (group) {
+ group->setNewBlockHook(hook);
}
});
luaCtx.registerFunction<void(std::shared_ptr<DynBlockRulesGroup>::*)(uint8_t, unsigned int, unsigned int, const std::string&, unsigned int, boost::optional<DNSAction::Action>, boost::optional<unsigned int>)>("setRCodeRate", [](std::shared_ptr<DynBlockRulesGroup>& group, uint8_t rcode, unsigned int rate, unsigned int seconds, const std::string& reason, unsigned int blockDuration, boost::optional<DNSAction::Action> action, boost::optional<unsigned int> warningRate) {
@@ -836,6 +876,11 @@ void setupLuaInspection(LuaContext& luaCtx)
group->setQTypeRate(qtype, rate, warningRate ? *warningRate : 0, seconds, reason, blockDuration, action ? *action : DNSAction::Action::None);
}
});
+ luaCtx.registerFunction<void(std::shared_ptr<DynBlockRulesGroup>::*)(double, unsigned int, const std::string&, unsigned int, size_t, double, boost::optional<DNSAction::Action>, boost::optional<double>)>("setCacheMissRatio", [](std::shared_ptr<DynBlockRulesGroup>& group, double ratio, unsigned int seconds, const std::string& reason, unsigned int blockDuration, size_t minimumNumberOfResponses, double minimumGlobalCacheHitRatio, boost::optional<DNSAction::Action> action, boost::optional<double> warningRatio) {
+ if (group) {
+ group->setCacheMissRatio(ratio, warningRatio ? *warningRatio : 0.0, seconds, reason, blockDuration, action ? *action : DNSAction::Action::None, minimumNumberOfResponses, minimumGlobalCacheHitRatio);
+ }
+ });
luaCtx.registerFunction<void(std::shared_ptr<DynBlockRulesGroup>::*)(uint8_t, uint8_t, uint8_t)>("setMasks", [](std::shared_ptr<DynBlockRulesGroup>& group, uint8_t v4, uint8_t v6, uint8_t port) {
if (group) {
if (v4 > 32) {
@@ -907,5 +952,14 @@ void setupLuaInspection(LuaContext& luaCtx)
});
luaCtx.registerFunction("setQuiet", &DynBlockRulesGroup::setQuiet);
luaCtx.registerFunction("toString", &DynBlockRulesGroup::toString);
+
+ /* DynBlock object accessors */
+ luaCtx.registerMember("reason", &DynBlock::reason);
+ luaCtx.registerMember("domain", &DynBlock::domain);
+ luaCtx.registerMember("until", &DynBlock::until);
+ luaCtx.registerMember<DynBlock, unsigned int>("blocks", [](const DynBlock& block) { return block.blocks.load(); }, [](DynBlock& block, [[maybe_unused]] unsigned int blocks) { });
+ luaCtx.registerMember("action", &DynBlock::action);
+ luaCtx.registerMember("warning", &DynBlock::warning);
+ luaCtx.registerMember("bpf", &DynBlock::bpf);
#endif /* DISABLE_DYNBLOCKS */
}