]> git.ipfire.org Git - thirdparty/pdns.git/commitdiff
Report Lua(Response)Action failures
authorChris Hofstaedtler <chris.hofstaedtler@deduktiva.com>
Mon, 19 Feb 2018 18:03:34 +0000 (19:03 +0100)
committerChris Hofstaedtler <chris.hofstaedtler@deduktiva.com>
Mon, 19 Feb 2018 18:05:28 +0000 (19:05 +0100)
pdns/dnsdist-lua-vars.cc
pdns/dnsdist-lua.hh
pdns/dnsdist-snmp.cc
pdns/dnsdist.cc
pdns/dnsdist.hh
pdns/dnsdistdist/DNSDIST-MIB.txt
pdns/dnsdistdist/docs/rules-actions.rst
pdns/dnsdistdist/docs/statistics.rst

index 76e43058c7337da6ad3d26891a2bf0d84eaf768d..8c9ec6fce3e28872f48a156b5a4aab410d4aa682 100644 (file)
@@ -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<string,int>{
       {"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         }
     });
 
index ee5a9ba6c3932243a5be1474753728c58d61a0f2..49751916680127ea908069c9f1f6187ec55ac501 100644 (file)
@@ -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<std::mutex> 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<std::mutex> 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
index 1b061293f753e26393d4b1fb86b2fa0984533966..4d3adf51a570045ebd6177d6647eb80ab63f4822 100644 (file)
@@ -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<oid, DNSDistStats::entry_t> 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);
index 1f021027bc8c58bb2e23e461ac744f9412ffa8f8..b324fb13df68b6f9bf0dc0d72efda91f435746de 100644 (file)
@@ -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<vector<DNSDistResponseRuleAction> >& 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<int>(pdns_stou(ruleresult)); // sorry
index b8d7111282a96d357e90cda7ba4609dedab5d9f7..e062c654362d4fb20609f86f25abc7152579b6d1 100644 (file)
@@ -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}, 
index bf1097c0fa1339ff288dbfbfc039feff2126be64..fdc3e5d8067d0c3c54fe96ae9052147ca18e8065 100644 (file)
@@ -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
index d603db49bf0bb9357d36c33ff2972162ea838458..b69185ea159073721c199557d72a7640d17eb854 100644 (file)
@@ -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
 
index a9b1a0ed5503ab3a9c3bc9e624196efb3a1b8a56..41c046a695edb6eade43d8039558889ff2b8f1ac 100644 (file)
@@ -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.