Enables EDNS subnet processing, for backends that support it.
+.. _setting-enable-lua-records:
+
+``enable-lua-records``
+--------------------------
+
+- Boolean
+- Default: no
+
+Enable globally the LUA records feature
+
.. _setting-entropy-source:
``entropy-source``
.. note::
The systemd unit file supplied with the source code already disables timestamp printing
+.. _setting-lua-record-exec-limit:
+
+``lua-record-exec-limit``
+-----------------------------
+
+- Integer
+- Default: 1000
+
+Limit LUA record scripts to ``lua-record-exec-limit`` instructions.
+Setting this to any value less than or equal to 0 will set no limit.
+
.. _setting-non-local-bind:
``non-local-bind``
bool g_8bitDNS;
#ifdef HAVE_LUA_RECORDS
bool g_doLuaRecord;
+int g_luaRecordExecLimit;
#endif
typedef Distributor<DNSPacket,DNSPacket,PacketHandler> DNSDistributor;
::arg().setSwitch("expand-alias", "Expand ALIAS records")="no";
::arg().setSwitch("outgoing-axfr-expand-alias", "Expand ALIAS records during outgoing AXFR")="no";
::arg().setSwitch("8bit-dns", "Allow 8bit dns queries")="no";
+#ifdef HAVE_LUA_RECORDS
::arg().setSwitch("enable-lua-record", "Process LUA record for all zones (metadata overrides this)")="no";
+ ::arg().set("lua-record-exec-limit", "LUA record scripts execution limit (instructions count). Values <= 0 mean no limit")="1000";
+#endif
::arg().setSwitch("axfr-lower-serial", "Also AXFR a zone from a master with a lower serial")="no";
::arg().set("lua-axfr-script", "Script to be used to edit incoming AXFRs")="";
g_8bitDNS = ::arg().mustDo("8bit-dns");
#ifdef HAVE_LUA_RECORDS
g_doLuaRecord = ::arg().mustDo("enable-lua-record");
+ g_luaRecordExecLimit = ::arg().asNum("lua-record-exec-limit");
#endif
DNSPacket::s_udpTruncationThreshold = std::max(512, ::arg().asNum("udp-truncation-threshold"));
void* carbonDumpThread(void*);
extern bool g_anyToTcp;
extern bool g_8bitDNS;
+#ifdef HAVE_LUA_RECORDS
extern bool g_doLuaRecord;
+#endif // HAVE_LUA_RECORDS
#endif // COMMON_STARTUP_HH
Pool checks ?
*/
+extern int g_luaRecordExecLimit;
+
using iplist_t = vector<pair<int, string> >;
using wiplist_t = std::unordered_map<int, string>;
using ipunitlist_t = vector<pair<int, iplist_t> >;
lua.writeFunction("report", [&counter](string event, boost::optional<string> line){
throw std::runtime_error("Script took too long");
});
- lua.executeCode("debug.sethook(report, '', 1000000)");
+ if (g_luaRecordExecLimit > 0) {
+ lua.executeCode(boost::str(boost::format("debug.sethook(report, '', %d)") % g_luaRecordExecLimit));
+ }
// TODO: make this better. Accept netmask/CA objects; provide names for the attr constants
lua.writeFunction("geoiplookup", [](const string &ip, const GeoIPInterface::GeoIPQueryAttribute attr) {
v6.rand.example.org. 3600 IN LUA AAAA "pickrandom({{'2001:db8:a0b:12f0::1', 'fe80::2a1:9bff:fe9b:f268'}})"
closest.geo 3600 IN LUA A "pickclosest({{'1.1.1.2','1.2.3.4'}})"
empty.rand.example.org. 3600 IN LUA A "pickrandom()"
+timeout.example.org. 3600 IN LUA A "; local i = 0 ; while i < 500 do i = i + 1 end return '1.2.3.4'"
wrand.example.org. 3600 IN LUA A "pickwrandom({{ {{30, '{prefix}.102'}}, {{15, '{prefix}.103'}} }})"
config IN LUA LUA ("settings={{stringmatch='Programming in Lua'}} "
self.assertRcodeEqual(res, dns.rcode.NOERROR)
self.assertRRsetInAnswer(res, first.answer[0])
+ def testTimeout(self):
+ """
+ Test if LUA scripts are aborted if script execution takes too long
+ """
+ query = dns.message.make_query('timeout.example.org', 'A')
+
+ first = self.sendUDPQuery(query)
+ self.assertRcodeEqual(first, dns.rcode.SERVFAIL)
+
if __name__ == '__main__':
unittest.main()
exit(0)