From: Chris Hofstaedtler Date: Mon, 19 Feb 2018 18:03:34 +0000 (+0100) Subject: Report Lua(Response)Action failures X-Git-Tag: dnsdist-1.3.0~95^2~1 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=5f23eb98c5b83481ec68e22471c6e281d7fce113;p=thirdparty%2Fpdns.git Report Lua(Response)Action failures --- diff --git a/pdns/dnsdist-lua-vars.cc b/pdns/dnsdist-lua-vars.cc index 76e43058c7..8c9ec6fce3 100644 --- a/pdns/dnsdist-lua-vars.cc +++ b/pdns/dnsdist-lua-vars.cc @@ -33,13 +33,15 @@ void setupLuaVars() {"Pool", (int)DNSAction::Action::Pool}, {"None",(int)DNSAction::Action::None}, {"Delay", (int)DNSAction::Action::Delay}, - {"Truncate", (int)DNSAction::Action::Truncate} + {"Truncate", (int)DNSAction::Action::Truncate}, + {"ServFail", (int)DNSAction::Action::ServFail} }); g_lua.writeVariable("DNSResponseAction", std::unordered_map{ {"Allow", (int)DNSResponseAction::Action::Allow }, {"Delay", (int)DNSResponseAction::Action::Delay }, {"HeaderModify", (int)DNSResponseAction::Action::HeaderModify }, + {"ServFail", (int)DNSResponseAction::Action::ServFail }, {"None", (int)DNSResponseAction::Action::None } }); diff --git a/pdns/dnsdist-lua.hh b/pdns/dnsdist-lua.hh index ee5a9ba6c3..4975191668 100644 --- a/pdns/dnsdist-lua.hh +++ b/pdns/dnsdist-lua.hh @@ -21,6 +21,8 @@ */ #pragma once +#include "dolog.hh" + class LuaAction : public DNSAction { public: @@ -31,10 +33,17 @@ public: Action operator()(DNSQuestion* dq, string* ruleresult) const override { std::lock_guard lock(g_luamutex); - auto ret = d_func(dq); - if(ruleresult) - *ruleresult=std::get<1>(ret); - return (Action)std::get<0>(ret); + try { + auto ret = d_func(dq); + if(ruleresult) + *ruleresult=std::get<1>(ret); + return (Action)std::get<0>(ret); + } catch (std::exception &e) { + warnlog("LuaAction failed inside lua, returning ServFail: %s", e.what()); + } catch (...) { + warnlog("LuaAction failed inside lua, returning ServFail: [unknown exception]"); + } + return DNSAction::Action::ServFail; } string toString() const override @@ -56,10 +65,17 @@ public: Action operator()(DNSResponse* dr, string* ruleresult) const override { std::lock_guard lock(g_luamutex); - auto ret = d_func(dr); - if(ruleresult) - *ruleresult=std::get<1>(ret); - return (Action)std::get<0>(ret); + try { + auto ret = d_func(dr); + if(ruleresult) + *ruleresult=std::get<1>(ret); + return (Action)std::get<0>(ret); + } catch (std::exception &e) { + warnlog("LuaResponseAction failed inside lua, returning ServFail: %s", e.what()); + } catch (...) { + warnlog("LuaResponseAction failed inside lua, returning ServFail: [unknown exception]"); + } + return DNSResponseAction::Action::ServFail; } string toString() const override diff --git a/pdns/dnsdist-snmp.cc b/pdns/dnsdist-snmp.cc index 1b061293f7..4d3adf51a5 100644 --- a/pdns/dnsdist-snmp.cc +++ b/pdns/dnsdist-snmp.cc @@ -46,6 +46,7 @@ static const oid cpuSysMSecOID[] = { DNSDIST_STATS_OID, 33 }; static const oid fdUsageOID[] = { DNSDIST_STATS_OID, 34 }; static const oid dynBlockedOID[] = { DNSDIST_STATS_OID, 35 }; static const oid dynBlockedNMGSizeOID[] = { DNSDIST_STATS_OID, 36 }; +static const oid ruleServFailOID[] = { DNSDIST_STATS_OID, 37 }; static std::unordered_map s_statsMap; @@ -547,6 +548,7 @@ DNSDistSNMPAgent::DNSDistSNMPAgent(const std::string& name, const std::string& m registerCounter64Stat("ruleDrop", ruleDropOID, OID_LENGTH(ruleDropOID), &g_stats.ruleDrop); registerCounter64Stat("ruleNXDomain", ruleNXDomainOID, OID_LENGTH(ruleNXDomainOID), &g_stats.ruleNXDomain); registerCounter64Stat("ruleRefused", ruleRefusedOID, OID_LENGTH(ruleRefusedOID), &g_stats.ruleRefused); + registerCounter64Stat("ruleServFail", ruleServFailOID, OID_LENGTH(ruleServFailOID), &g_stats.ruleServFail); registerCounter64Stat("selfAnswered", selfAnsweredOID, OID_LENGTH(selfAnsweredOID), &g_stats.selfAnswered); registerCounter64Stat("downstreamTimeouts", downstreamTimeoutsOID, OID_LENGTH(downstreamTimeoutsOID), &g_stats.downstreamTimeouts); registerCounter64Stat("downstreamSendErrors", downstreamSendErrorsOID, OID_LENGTH(downstreamSendErrorsOID), &g_stats.downstreamSendErrors); diff --git a/pdns/dnsdist.cc b/pdns/dnsdist.cc index 1f021027bc..b324fb13df 100644 --- a/pdns/dnsdist.cc +++ b/pdns/dnsdist.cc @@ -992,6 +992,12 @@ bool processQuery(LocalHolders& holders, DNSQuestion& dq, string& poolname, int* g_stats.ruleRefused++; return true; break; + case DNSAction::Action::ServFail: + dq.dh->rcode = RCode::ServFail; + dq.dh->qr=true; + g_stats.ruleServFail++; + return true; + break; case DNSAction::Action::Spoof: spoofResponseFromString(dq, ruleresult); return true; @@ -1039,6 +1045,10 @@ bool processResponse(LocalStateHolder >& local case DNSResponseAction::Action::HeaderModify: return true; break; + case DNSResponseAction::Action::ServFail: + dr.dh->rcode = RCode::ServFail; + return true; + break; /* non-terminal actions follow */ case DNSResponseAction::Action::Delay: *delayMsec = static_cast(pdns_stou(ruleresult)); // sorry diff --git a/pdns/dnsdist.hh b/pdns/dnsdist.hh index b8d7111282..e062c65436 100644 --- a/pdns/dnsdist.hh +++ b/pdns/dnsdist.hh @@ -169,7 +169,7 @@ struct DNSResponse : DNSQuestion class DNSAction { public: - enum class Action { Drop, Nxdomain, Refused, Spoof, Allow, HeaderModify, Pool, Delay, Truncate, None}; + enum class Action { Drop, Nxdomain, Refused, Spoof, Allow, HeaderModify, Pool, Delay, Truncate, ServFail, None}; virtual Action operator()(DNSQuestion*, string* ruleresult) const =0; virtual ~DNSAction() { @@ -184,7 +184,7 @@ public: class DNSResponseAction { public: - enum class Action { Allow, Delay, Drop, HeaderModify, None }; + enum class Action { Allow, Delay, Drop, HeaderModify, ServFail, None }; virtual Action operator()(DNSResponse*, string* ruleresult) const =0; virtual ~DNSResponseAction() { @@ -230,6 +230,7 @@ struct DNSDistStats stat_t ruleDrop{0}; stat_t ruleNXDomain{0}; stat_t ruleRefused{0}; + stat_t ruleServFail{0}; stat_t selfAnswered{0}; stat_t downstreamTimeouts{0}; stat_t downstreamSendErrors{0}; @@ -250,6 +251,7 @@ struct DNSDistStats {"rule-drop", &ruleDrop}, {"rule-nxdomain", &ruleNXDomain}, {"rule-refused", &ruleRefused}, + {"rule-servfail", &ruleServFail}, {"self-answered", &selfAnswered}, {"downstream-timeouts", &downstreamTimeouts}, {"downstream-send-errors", &downstreamSendErrors}, diff --git a/pdns/dnsdistdist/DNSDIST-MIB.txt b/pdns/dnsdistdist/DNSDIST-MIB.txt index bf1097c0fa..fdc3e5d806 100644 --- a/pdns/dnsdistdist/DNSDIST-MIB.txt +++ b/pdns/dnsdistdist/DNSDIST-MIB.txt @@ -318,6 +318,14 @@ dynBlockNMGSize OBJECT-TYPE "Dynamic blocks (NMG) size" ::= { stats 36 } +ruleServFail OBJECT-TYPE + SYNTAX Counter64 + MAX-ACCESS read-only + STATUS current + DESCRIPTION + "Number of ServFail responses returned because of a rule" + ::= { stats 37 } + backendStatTable OBJECT-TYPE SYNTAX SEQUENCE OF BackendStatEntry MAX-ACCESS not-accessible diff --git a/pdns/dnsdistdist/docs/rules-actions.rst b/pdns/dnsdistdist/docs/rules-actions.rst index d603db49bf..b69185ea15 100644 --- a/pdns/dnsdistdist/docs/rules-actions.rst +++ b/pdns/dnsdistdist/docs/rules-actions.rst @@ -150,7 +150,7 @@ Rule Generators Invoke a Lua function that accepts a :class:`DNSQuestion`. This function works similar to using :func:`LuaAction`. - The ``function`` should return a :ref:`DNSAction`. + The ``function`` should return a :ref:`DNSAction`. If the Lua code fails, ServFail is returned. :param DNSRule: match queries based on this rule :param string function: the name of a Lua function @@ -165,10 +165,9 @@ Rule Generators .. versionchanged:: 1.3.0 Added the optional parameter ``options``. - Invoke a Lua function that accepts a :class:`DNSQuestion` on the response. - This function works similar to using :func:`LuaAction`. - - The ``function`` should return a :ref:`DNSAction`. + Invoke a Lua function that accepts a :class:`DNSResponse`. + This function works similar to using :func:`LuaResponseAction`. + The ``function`` should return a :ref:`DNSResponseAction`. If the Lua code fails, ServFail is returned. :param DNSRule: match queries based on this rule :param string function: the name of a Lua function @@ -785,7 +784,7 @@ The following actions exist. Invoke a Lua function that accepts a :class:`DNSQuestion`. - The ``function`` should return a :ref:`DNSAction`. + The ``function`` should return a :ref:`DNSAction`. If the Lua code fails, ServFail is returned. :param string function: the name of a Lua function @@ -793,7 +792,7 @@ The following actions exist. Invoke a Lua function that accepts a :class:`DNSResponse`. - The ``function`` should return a :ref:`DNSResponseAction`. + The ``function`` should return a :ref:`DNSResponseAction`. If the Lua code fails, ServFail is returned. :param string function: the name of a Lua function diff --git a/pdns/dnsdistdist/docs/statistics.rst b/pdns/dnsdistdist/docs/statistics.rst index a9b1a0ed55..41c046a695 100644 --- a/pdns/dnsdistdist/docs/statistics.rst +++ b/pdns/dnsdistdist/docs/statistics.rst @@ -134,6 +134,10 @@ rule-refused ------------ Number of Refused answers returned because of a rule. +rule-servfail +------------- +Number of ServFail answers returned because of a rule. + self-answered ------------- Number of self-answered responses.