]> granicus.if.org Git - pdns/commitdiff
Use BaseLua4 with both auth and recursor
authorAki Tuomi <cmouse@cmouse.fi>
Sun, 11 Jun 2017 21:08:55 +0000 (00:08 +0300)
committerAki Tuomi <cmouse@cmouse.fi>
Mon, 18 Dec 2017 10:53:57 +0000 (12:53 +0200)
pdns/Makefile.am
pdns/lua-auth4.cc
pdns/lua-auth4.hh
pdns/lua-base4.cc
pdns/lua-recursor4.cc
pdns/lua-recursor4.hh
pdns/recursordist/Makefile.am
pdns/recursordist/lua-base4.cc [new symlink]
pdns/recursordist/lua-base4.hh [new symlink]

index b570a0ffb265036b4d2a746b02c7e3e17d8048e1..29c26dd259e5abd1cdd2252220b4b91aafced065 100644 (file)
@@ -179,6 +179,7 @@ pdns_server_SOURCES = \
        json.cc json.hh \
        lock.hh \
        logger.cc logger.hh \
+       lua-base4.cc lua-base4.hh \
        lua-auth.cc lua-auth.hh \
        lua-auth4.cc lua-auth4.hh \
        lua-pdns.cc lua-pdns.hh lua-iputils.cc \
index 773d71090d8c73995f6ef6ce5ff4513e4130b7f5..fd035b4d80682a8a38eade41900c441f9274e2c0 100644 (file)
@@ -7,9 +7,11 @@
 #include "ednssubnet.hh"
 #include <unordered_set>
 
+AuthLua4::AuthLua4(const std::string &fname) : BaseLua4(fname) {
+}
+
 #if !defined(HAVE_LUA)
 
-AuthLua4::AuthLua4(const std::string& fname) { }
 bool AuthLua4::updatePolicy(const DNSName &qname, QType qtype, const DNSName &zonename, DNSPacket *packet) { return false; }
 bool AuthLua4::axfrfilter(const ComboAddress& remote, const DNSName& zone, const DNSResourceRecord& in, vector<DNSResourceRecord>& out) { return false; }
 AuthLua4::~AuthLua4() { }
@@ -19,178 +21,8 @@ AuthLua4::~AuthLua4() { }
 #undef L
 #include "ext/luawrapper/include/LuaContext.hpp"
 
-AuthLua4::AuthLua4(const std::string& fname) {
-  d_lw = std::unique_ptr<LuaContext>(new LuaContext);
+void AuthLua4::postPrepareContext() {
   stubParseResolveConf();
-  d_lw->registerFunction<int(dnsheader::*)()>("getID", [](dnsheader& dh) { return dh.id; });
-  d_lw->registerFunction<bool(dnsheader::*)()>("getCD", [](dnsheader& dh) { return dh.cd; });
-  d_lw->registerFunction<bool(dnsheader::*)()>("getTC", [](dnsheader& dh) { return dh.tc; });
-  d_lw->registerFunction<bool(dnsheader::*)()>("getRA", [](dnsheader& dh) { return dh.ra; });
-  d_lw->registerFunction<bool(dnsheader::*)()>("getAD", [](dnsheader& dh) { return dh.ad; });
-  d_lw->registerFunction<bool(dnsheader::*)()>("getAA", [](dnsheader& dh) { return dh.aa; });
-  d_lw->registerFunction<bool(dnsheader::*)()>("getRD", [](dnsheader& dh) { return dh.rd; });
-  d_lw->registerFunction<int(dnsheader::*)()>("getRCODE", [](dnsheader& dh) { return dh.rcode; });
-  d_lw->registerFunction<int(dnsheader::*)()>("getOPCODE", [](dnsheader& dh) { return dh.opcode; });
-  d_lw->registerFunction<int(dnsheader::*)()>("getQDCOUNT", [](dnsheader& dh) { return ntohs(dh.qdcount); });
-  d_lw->registerFunction<int(dnsheader::*)()>("getANCOUNT", [](dnsheader& dh) { return ntohs(dh.ancount); });
-  d_lw->registerFunction<int(dnsheader::*)()>("getNSCOUNT", [](dnsheader& dh) { return ntohs(dh.nscount); });
-  d_lw->registerFunction<int(dnsheader::*)()>("getARCOUNT", [](dnsheader& dh) { return ntohs(dh.arcount); });
-
-  d_lw->writeFunction("newDN", [](const std::string& dom){ return DNSName(dom); });
-  d_lw->registerFunction("isPartOf", &DNSName::isPartOf);
-  d_lw->registerFunction<bool(DNSName::*)(const std::string&)>("equal",
-                                                              [](const DNSName& lhs, const std::string& rhs) { return lhs==DNSName(rhs); });
-  d_lw->registerFunction("__eq", &DNSName::operator==);
-
-  d_lw->registerFunction("__eq", &DNSResourceRecord::operator==);
-  d_lw->registerFunction("__lt", &DNSResourceRecord::operator<);
-
-  d_lw->registerFunction<string(DNSResourceRecord::*)()>("toString", [](const DNSResourceRecord& rec) { return rec.getZoneRepresentation();} );
-
-  d_lw->registerFunction<DNSName(DNSResourceRecord::*)()>("qname", [](DNSResourceRecord& rec) { return rec.qname; });
-  d_lw->registerFunction<DNSName(DNSResourceRecord::*)()>("wildcardname", [](DNSResourceRecord& rec) { return rec.wildcardname; });
-  d_lw->registerFunction<string(DNSResourceRecord::*)()>("content", [](DNSResourceRecord& rec) { return rec.content; });
-  d_lw->registerFunction<time_t(DNSResourceRecord::*)()>("last_modified", [](DNSResourceRecord& rec) { return rec.last_modified; });
-  d_lw->registerFunction<uint32_t(DNSResourceRecord::*)()>("ttl", [](DNSResourceRecord& rec) { return rec.ttl; });
-  d_lw->registerFunction<uint32_t(DNSResourceRecord::*)()>("signttl", [](DNSResourceRecord& rec) { return rec.signttl; });
-  d_lw->registerFunction<int(DNSResourceRecord::*)()>("domain_id", [](DNSResourceRecord& rec) { return rec.domain_id; });
-  d_lw->registerFunction<uint16_t(DNSResourceRecord::*)()>("qtype", [](DNSResourceRecord& rec) { return rec.qtype.getCode(); });
-  d_lw->registerFunction<uint16_t(DNSResourceRecord::*)()>("qclass", [](DNSResourceRecord& rec) { return rec.qclass; });
-  d_lw->registerFunction<uint8_t(DNSResourceRecord::*)()>("scopeMask", [](DNSResourceRecord& rec) { return rec.scopeMask; });
-  d_lw->registerFunction<bool(DNSResourceRecord::*)()>("auth", [](DNSResourceRecord& rec) { return rec.auth; });
-  d_lw->registerFunction<bool(DNSResourceRecord::*)()>("disabled", [](DNSResourceRecord& rec) { return rec.disabled; });
-
-  d_lw->registerFunction<string(ComboAddress::*)()>("toString", [](const ComboAddress& ca) { return ca.toString(); });
-  d_lw->registerFunction<string(ComboAddress::*)()>("toStringWithPort", [](const ComboAddress& ca) { return ca.toStringWithPort(); });
-  d_lw->registerFunction<uint16_t(ComboAddress::*)()>("getPort", [](const ComboAddress& ca) { return ntohs(ca.sin4.sin_port); } );
-  d_lw->registerFunction<string(ComboAddress::*)()>("getRaw", [](const ComboAddress& ca) {
-      if(ca.sin4.sin_family == AF_INET) {
-        auto t=ca.sin4.sin_addr.s_addr; return string((const char*)&t, 4);
-      }
-      else
-        return string((const char*)&ca.sin6.sin6_addr.s6_addr, 16);
-    } );
-
-  d_lw->writeFunction("newCA", [](const std::string& a) { return ComboAddress(a); });
-  typedef std::unordered_set<ComboAddress,ComboAddress::addressOnlyHash,ComboAddress::addressOnlyEqual> cas_t;
-  d_lw->writeFunction("newCAS", []{ return cas_t(); });
-
-
-  d_lw->registerFunction<void(cas_t::*)(boost::variant<string,ComboAddress, vector<pair<unsigned int,string> > >)>("add",
-                                                                                   [](cas_t& cas, const boost::variant<string,ComboAddress,vector<pair<unsigned int,string> > >& in)
-                                                                                   {
-                                                                                     try {
-                                                                                     if(auto s = boost::get<string>(&in)) {
-                                                                                       cas.insert(ComboAddress(*s));
-                                                                                     }
-                                                                                     else if(auto v = boost::get<vector<pair<unsigned int, string> > >(&in)) {
-                                                                                       for(const auto& str : *v)
-                                                                                         cas.insert(ComboAddress(str.second));
-                                                                                     }
-                                                                                     else
-                                                                                       cas.insert(boost::get<ComboAddress>(in));
-                                                                                     }
-                                                                                     catch(std::exception& e) { theL() <<Logger::Error<<e.what()<<endl; }
-                                                                                   });
-
-  d_lw->registerFunction<bool(cas_t::*)(const ComboAddress&)>("check",[](const cas_t& cas, const ComboAddress&ca) {
-      return (bool)cas.count(ca);
-    });
-
-
-
-  d_lw->registerFunction<bool(ComboAddress::*)(const ComboAddress&)>("equal", [](const ComboAddress& lhs, const ComboAddress& rhs) {
-      return ComboAddress::addressOnlyEqual()(lhs, rhs);
-    });
-
-
-  d_lw->registerFunction<ComboAddress(Netmask::*)()>("getNetwork", [](const Netmask& nm) { return nm.getNetwork(); } ); // const reference makes this necessary
-  d_lw->registerFunction("toString", &Netmask::toString);
-  d_lw->registerFunction("empty", &Netmask::empty);
-
-  d_lw->writeFunction("newNMG", []() { return NetmaskGroup(); });
-  d_lw->registerFunction<void(NetmaskGroup::*)(const std::string&mask)>("addMask", [](NetmaskGroup&nmg, const std::string& mask)
-                         {
-                           nmg.addMask(mask);
-                         });
-
-  d_lw->registerFunction<void(NetmaskGroup::*)(const vector<pair<unsigned int, std::string>>&)>("addMasks", [](NetmaskGroup&nmg, const vector<pair<unsigned int, std::string>>& masks)
-                         {
-                           for(const auto& mask: masks)
-                             nmg.addMask(mask.second);
-                         });
-
-
-  d_lw->registerFunction("match", (bool (NetmaskGroup::*)(const ComboAddress&) const)&NetmaskGroup::match);
-  d_lw->registerFunction<string(DNSName::*)()>("toString", [](const DNSName&dn ) { return dn.toString(); });
-  d_lw->registerFunction<string(DNSName::*)()>("toStringNoDot", [](const DNSName&dn ) { return dn.toStringNoDot(); });
-  d_lw->registerFunction<bool(DNSName::*)()>("chopOff", [](DNSName&dn ) { return dn.chopOff(); });
-  d_lw->registerMember("name", &DNSRecord::d_name);
-  d_lw->registerMember("type", &DNSRecord::d_type);
-  d_lw->registerMember("ttl", &DNSRecord::d_ttl);
-
-
-  d_lw->registerFunction<string(DNSRecord::*)()>("getContent", [](const DNSRecord& dr) { return dr.d_content->getZoneRepresentation(); });
-  d_lw->registerFunction<boost::optional<ComboAddress>(DNSRecord::*)()>("getCA", [](const DNSRecord& dr) {
-      boost::optional<ComboAddress> ret;
-
-      if(auto rec = std::dynamic_pointer_cast<ARecordContent>(dr.d_content))
-        ret=rec->getCA(53);
-      else if(auto aaaarec = std::dynamic_pointer_cast<AAAARecordContent>(dr.d_content))
-        ret=aaaarec->getCA(53);
-      return ret;
-    });
-
-
-  d_lw->registerFunction<void(DNSRecord::*)(const std::string&)>("changeContent", [](DNSRecord& dr, const std::string& newContent) { dr.d_content = DNSRecordContent::mastermake(dr.d_type, 1, newContent); });
-
-  d_lw->writeFunction("pdnslog", [](const std::string& msg, boost::optional<int> loglevel) {
-      theL() << (Logger::Urgency)loglevel.get_value_or(Logger::Warning) << msg<<endl;
-    });
-  typedef vector<pair<string, int> > in_t;
-  vector<pair<string, boost::variant<int, in_t, struct timeval* > > >  pd{
-    {"PASS", (int)PolicyDecision::PASS}, {"DROP",  (int)PolicyDecision::DROP},
-    {"TRUNCATE", (int)PolicyDecision::TRUNCATE}
-  };
-
-  vector<pair<string, int> > rcodes = {{"NOERROR",  RCode::NoError  },
-                                       {"FORMERR",  RCode::FormErr  },
-                                       {"SERVFAIL", RCode::ServFail },
-                                       {"NXDOMAIN", RCode::NXDomain },
-                                       {"NOTIMP",   RCode::NotImp   },
-                                       {"REFUSED",  RCode::Refused  },
-                                       {"YXDOMAIN", RCode::YXDomain },
-                                       {"YXRRSET",  RCode::YXRRSet  },
-                                       {"NXRRSET",  RCode::NXRRSet  },
-                                       {"NOTAUTH",  RCode::NotAuth  },
-                                       {"NOTZONE",  RCode::NotZone  }};
-  for(const auto& rcode : rcodes)
-    pd.push_back({rcode.first, rcode.second});
-
-  pd.push_back({"place", in_t{
-    {"QUESTION", 0},
-    {"ANSWER", 1},
-    {"AUTHORITY", 2},
-    {"ADDITIONAL", 3}
-  }});
-
-  pd.push_back({"loglevels", in_t{
-        {"Alert", LOG_ALERT},
-        {"Critical", LOG_CRIT},
-        {"Debug", LOG_DEBUG},
-        {"Emergency", LOG_EMERG},
-        {"Info", LOG_INFO},
-        {"Notice", LOG_NOTICE},
-        {"Warning", LOG_WARNING},
-        {"Error", LOG_ERR}
-          }});
-
-  for(const auto& n : QType::names)
-    pd.push_back({n.first, n.second});
-  d_lw->registerMember("tv_sec", &timeval::tv_sec);
-  d_lw->registerMember("tv_usec", &timeval::tv_usec);
-
-  d_lw->writeVariable("pdns", pd);
 
   d_lw->writeFunction("resolve", [](const std::string& qname, uint16_t qtype) {
       std::vector<DNSZoneRecord> ret;
@@ -204,7 +36,6 @@ AuthLua4::AuthLua4(const std::string& fname) {
       return luaResult;
   });
 
-
 /* update policy */
   d_lw->registerFunction<DNSName(UpdatePolicyQuery::*)()>("getQName", [](UpdatePolicyQuery& upq) { return upq.qname; });
   d_lw->registerFunction<DNSName(UpdatePolicyQuery::*)()>("getZoneName", [](UpdatePolicyQuery& upq) { return upq.zonename; });
@@ -215,14 +46,9 @@ AuthLua4::AuthLua4(const std::string& fname) {
   d_lw->registerFunction<DNSName(UpdatePolicyQuery::*)()>("getTsigName", [](UpdatePolicyQuery& upq) { return upq.tsigName; });
   d_lw->registerFunction<std::string(UpdatePolicyQuery::*)()>("getPeerPrincipal", [](UpdatePolicyQuery& upq) { return upq.peerPrincipal; });
 /* end of update policy */
+}
 
-  ifstream ifs(fname);
-  if(!ifs) {
-    theL()<<Logger::Error<<"Unable to read configuration file from '"<<fname<<"': "<<strerror(errno)<<endl;
-    return;
-  }
-  d_lw->executeCode(ifs);
-
+void AuthLua4::postLoad() {
   d_update_policy = d_lw->readVariable<boost::optional<luacall_update_policy_t>>("updatepolicy").get_value_or(0);
   d_axfr_filter = d_lw->readVariable<boost::optional<luacall_axfr_filter_t>>("axfrfilter").get_value_or(0);
 
index 3bad3541f7c79ab300a2fb7f25dbc7870bf13eef..efa521934eb8e58b8df1df3004ced05355d9c5b5 100644 (file)
@@ -1,30 +1,25 @@
 #pragma once
 #include "iputils.hh"
 #include "dnsname.hh"
-#include "namespaces.hh"
-#include "dnsrecords.hh"
 #include "dnspacket.hh"
+#include "dnsparser.hh"
 #include <unordered_map>
-#include <boost/variant/variant.hpp>
 #ifdef HAVE_CONFIG_H
 #include "config.h"
 #endif
+#include "lua-base4.hh"
 
-class LuaContext;
-
-class AuthLua4 : public boost::noncopyable
+class AuthLua4 : public BaseLua4
 {
-private:
-#ifdef HAVE_LUA
-  std::unique_ptr<LuaContext> d_lw; // this is way on top because it must get destroyed _last_
-#endif
-
 public:
-  explicit AuthLua4(const std::string& fname);
+  explicit AuthLua4(const string &fname);
   bool updatePolicy(const DNSName &qname, QType qtype, const DNSName &zonename, DNSPacket *packet);
   bool axfrfilter(const ComboAddress&, const DNSName&, const DNSResourceRecord&, std::vector<DNSResourceRecord>&);
 
   ~AuthLua4(); // this is so unique_ptr works with an incomplete type
+protected:
+  void postPrepareContext() override;
+  void postLoad() override;
 private:
   struct UpdatePolicyQuery {
     DNSName qname;
index 0114cd49e4edc8a148446b870ce15861dd9a4882..987dadbfecbbeb93e08902cadcdf1ecabd2569c5 100644 (file)
@@ -104,19 +104,21 @@ void BaseLua4::prepareContext() {
   d_lw->writeFunction("newCAS", []{ return cas_t(); });
 
   // cas_t
-  d_lw->registerFunction<void(cas_t::*)(boost::variant<string,ComboAddress, vector<pair<unsigned int,string> > >)>("add", [](cas_t& cas, const boost::variant<string,ComboAddress,vector<pair<unsigned int,string> > >& in)
+  d_lw->registerFunction<void(cas_t::*)(boost::variant<string,ComboAddress, vector<pair<unsigned int,string> > >)>("add",
+    [](cas_t& cas, const boost::variant<string,ComboAddress,vector<pair<unsigned int,string> > >& in)
     {
       try {
-        if(auto s = boost::get<string>(&in)) {
-          cas.insert(ComboAddress(*s));
-        }
-        else if(auto v = boost::get<vector<pair<unsigned int, string> > >(&in)) {
-          for(const auto& s : *v)
-            cas.insert(ComboAddress(s.second));
-        }
-        else
-          cas.insert(boost::get<ComboAddress>(in));
-      } catch(std::exception& e) { theL() <<Logger::Error<<e.what()<<endl; }
+      if(auto s = boost::get<string>(&in)) {
+        cas.insert(ComboAddress(*s));
+      }
+      else if(auto v = boost::get<vector<pair<unsigned int, string> > >(&in)) {
+        for(const auto& str : *v)
+          cas.insert(ComboAddress(str.second));
+      }
+      else
+        cas.insert(boost::get<ComboAddress>(in));
+      }
+      catch(std::exception& e) { theL() <<Logger::Error<<e.what()<<endl; }
     });
   d_lw->registerFunction<bool(cas_t::*)(const ComboAddress&)>("check",[](const cas_t& cas, const ComboAddress&ca) { return cas.count(ca)>0; });
   d_lw->registerFunction<bool(ComboAddress::*)(const ComboAddress&)>("equal", [](const ComboAddress& lhs, const ComboAddress& rhs) { return ComboAddress::addressOnlyEqual()(lhs, rhs); });
@@ -132,6 +134,7 @@ void BaseLua4::prepareContext() {
   d_lw->registerFunction("empty", &Netmask::empty);
   d_lw->registerFunction("match", (bool (Netmask::*)(const string&) const)&Netmask::match);
   d_lw->registerEqFunction(&Netmask::operator==);
+  d_lw->registerToStringFunction(&Netmask::toString);
 
   // NetmaskGroup
   d_lw->writeFunction("newNMG", []() { return NetmaskGroup(); });
index 2d64a23980668da732fa3643931a5887b0a49aa5..9ee3b44fce8a41d638e5110f1bd59aea2e00ffca 100644 (file)
@@ -32,6 +32,9 @@
 #include "rec-snmp.hh"
 #include <unordered_set>
 
+RecursorLua4::RecursorLua4(const std::string &fname) : BaseLua4(fname) {
+}
+
 static int followCNAMERecords(vector<DNSRecord>& ret, const QType& qtype)
 {
   vector<DNSRecord> resolved;
@@ -214,124 +217,8 @@ struct DynMetric
   void set(unsigned long val) { *ptr =val; }
 };
 
-RecursorLua4::RecursorLua4(const std::string& fname)
+void RecursorLua4::postPrepareContext()
 {
-  d_lw = std::unique_ptr<LuaContext>(new LuaContext);
-
-  d_lw->registerFunction<int(dnsheader::*)()>("getID", [](dnsheader& dh) { return dh.id; });
-  d_lw->registerFunction<bool(dnsheader::*)()>("getCD", [](dnsheader& dh) { return dh.cd; });
-  d_lw->registerFunction<bool(dnsheader::*)()>("getTC", [](dnsheader& dh) { return dh.tc; });
-  d_lw->registerFunction<bool(dnsheader::*)()>("getRA", [](dnsheader& dh) { return dh.ra; });
-  d_lw->registerFunction<bool(dnsheader::*)()>("getAD", [](dnsheader& dh) { return dh.ad; });
-  d_lw->registerFunction<bool(dnsheader::*)()>("getAA", [](dnsheader& dh) { return dh.aa; });
-  d_lw->registerFunction<bool(dnsheader::*)()>("getRD", [](dnsheader& dh) { return dh.rd; });
-  d_lw->registerFunction<int(dnsheader::*)()>("getRCODE", [](dnsheader& dh) { return dh.rcode; });
-  d_lw->registerFunction<int(dnsheader::*)()>("getOPCODE", [](dnsheader& dh) { return dh.opcode; });
-  d_lw->registerFunction<int(dnsheader::*)()>("getQDCOUNT", [](dnsheader& dh) { return ntohs(dh.qdcount); });
-  d_lw->registerFunction<int(dnsheader::*)()>("getANCOUNT", [](dnsheader& dh) { return ntohs(dh.ancount); });
-  d_lw->registerFunction<int(dnsheader::*)()>("getNSCOUNT", [](dnsheader& dh) { return ntohs(dh.nscount); });
-  d_lw->registerFunction<int(dnsheader::*)()>("getARCOUNT", [](dnsheader& dh) { return ntohs(dh.arcount); });
-
-  d_lw->writeFunction("newDN", [](boost::variant<const std::string, const DNSName> dom){
-    if(dom.which() == 0)
-      return DNSName(boost::get<const std::string>(dom));
-    else
-      return DNSName(boost::get<const DNSName>(dom));
-  });
-  d_lw->registerFunction("isPartOf", &DNSName::isPartOf);
-  d_lw->registerFunction<unsigned int(DNSName::*)()>("countLabels", [](const DNSName& name) { return name.countLabels(); });
-  d_lw->registerFunction<size_t(DNSName::*)()>("wirelength", [](const DNSName& name) { return name.wirelength(); });
-  d_lw->registerFunction<bool(DNSName::*)(const std::string&)>(
-    "equal",
-     [](const DNSName& lhs, const std::string& rhs) {
-       return lhs==DNSName(rhs);
-    }
-  );
-  d_lw->registerFunction("__eq", &DNSName::operator==);
-
-  d_lw->registerFunction<string(ComboAddress::*)()>("toString", [](const ComboAddress& ca) { return ca.toString(); });
-  d_lw->registerFunction<string(ComboAddress::*)()>("toStringWithPort", [](const ComboAddress& ca) { return ca.toStringWithPort(); });
-  d_lw->registerFunction<uint16_t(ComboAddress::*)()>("getPort", [](const ComboAddress& ca) { return ntohs(ca.sin4.sin_port); } );
-  d_lw->registerFunction<string(ComboAddress::*)()>("getRaw", [](const ComboAddress& ca) { 
-      if(ca.sin4.sin_family == AF_INET) {
-        auto t=ca.sin4.sin_addr.s_addr; return string((const char*)&t, 4); 
-      }
-      else 
-        return string((const char*)&ca.sin6.sin6_addr.s6_addr, 16);
-    } );
-  d_lw->registerFunction<bool(ComboAddress::*)()>("isIPv4", [](const ComboAddress& ca) { return ca.sin4.sin_family == AF_INET; });
-  d_lw->registerFunction<bool(ComboAddress::*)()>("isIPv6", [](const ComboAddress& ca) { return ca.sin4.sin_family == AF_INET6; });
-  d_lw->registerFunction<bool(ComboAddress::*)()>("isMappedIPv4", [](const ComboAddress& ca) { return ca.isMappedIPv4(); });
-  d_lw->registerFunction<ComboAddress(ComboAddress::*)()>("mapToIPv4", [](const ComboAddress& ca) { return ca.mapToIPv4(); });
-  d_lw->registerFunction<void(ComboAddress::*)(unsigned int)>("truncate", [](ComboAddress& ca, unsigned int bits) { ca.truncate(bits); });
-
-  d_lw->writeFunction("newCA", [](const std::string& a) { return ComboAddress(a); });
-  typedef std::unordered_set<ComboAddress,ComboAddress::addressOnlyHash,ComboAddress::addressOnlyEqual> cas_t;
-  d_lw->writeFunction("newCAS", []{ return cas_t(); });
-
-
-  d_lw->registerFunction<void(cas_t::*)(boost::variant<string,ComboAddress, vector<pair<unsigned int,string> > >)>(
-    "add",
-    [](cas_t& cas, const boost::variant<string,ComboAddress,vector<pair<unsigned int,string> > >& in)
-    {
-      try {
-        if(auto s = boost::get<string>(&in)) {
-          cas.insert(ComboAddress(*s));
-        }
-        else if(auto v = boost::get<vector<pair<unsigned int, string> > >(&in)) {
-          for(const auto&entry : *v)
-            cas.insert(ComboAddress(entry.second));
-          }
-        else {
-          cas.insert(boost::get<ComboAddress>(in));
-        }
-      }
-      catch(std::exception& e) { theL() <<Logger::Error<<e.what()<<endl; }
-    });
-
-  d_lw->registerFunction<bool(cas_t::*)(const ComboAddress&)>("check",[](const cas_t& cas, const ComboAddress&ca) {
-      return (bool)cas.count(ca);
-    });
-
-  d_lw->registerFunction<bool(ComboAddress::*)(const ComboAddress&)>(
-    "equal",
-    [](const ComboAddress& lhs, const ComboAddress& rhs) {
-      return ComboAddress::addressOnlyEqual()(lhs, rhs);
-    }
-  );
-  
-  d_lw->writeFunction("newNetmask", [](const string& s) { return Netmask(s); });
-  d_lw->registerFunction<ComboAddress(Netmask::*)()>("getNetwork", [](const Netmask& nm) { return nm.getNetwork(); } ); // const reference makes this necessary
-  d_lw->registerFunction<ComboAddress(Netmask::*)()>("getMaskedNetwork", [](const Netmask& nm) { return nm.getMaskedNetwork(); } );
-  d_lw->registerFunction("isIpv4", &Netmask::isIpv4);
-  d_lw->registerFunction("isIpv6", &Netmask::isIpv6);
-  d_lw->registerFunction("getBits", &Netmask::getBits);
-  d_lw->registerFunction("toString", &Netmask::toString);
-  d_lw->registerFunction("empty", &Netmask::empty);
-  d_lw->registerFunction("match", (bool (Netmask::*)(const string&) const)&Netmask::match);
-  d_lw->registerFunction("__eq", &Netmask::operator==);
-
-  d_lw->writeFunction("newNMG", []() { return NetmaskGroup(); });
-  d_lw->registerFunction<void(NetmaskGroup::*)(const std::string&mask)>(
-    "addMask", [](NetmaskGroup&nmg, const std::string& mask){
-      nmg.addMask(mask);
-    }
-  );
-
-  d_lw->registerFunction<void(NetmaskGroup::*)(const vector<pair<unsigned int, std::string>>&)>(
-    "addMasks",
-    [](NetmaskGroup&nmg, const vector<pair<unsigned int, std::string>>& masks){
-      for(const auto& mask: masks)
-        nmg.addMask(mask.second);
-    }
-  );
-
-
-  d_lw->registerFunction("match", (bool (NetmaskGroup::*)(const ComboAddress&) const)&NetmaskGroup::match);
-  d_lw->registerFunction<string(DNSName::*)()>("toString", [](const DNSName&dn ) { return dn.toString(); });
-  d_lw->registerFunction<string(DNSName::*)()>("toStringNoDot", [](const DNSName&dn ) { return dn.toStringNoDot(); });
-  d_lw->registerFunction<bool(DNSName::*)()>("chopOff", [](DNSName&dn ) { return dn.chopOff(); });
-
   d_lw->registerMember<const DNSName (DNSQuestion::*)>("qname", [](const DNSQuestion& dq) -> const DNSName& { return dq.qname; }, [](DNSQuestion& dq, const DNSName& newName) { (void) newName; });
   d_lw->registerMember<uint16_t (DNSQuestion::*)>("qtype", [](const DNSQuestion& dq) -> uint16_t { return dq.qtype; }, [](DNSQuestion& dq, uint16_t newType) { (void) newType; });
   d_lw->registerMember<bool (DNSQuestion::*)>("isTcp", [](const DNSQuestion& dq) -> bool { return dq.isTcp; }, [](DNSQuestion& dq, bool newTcp) { (void) newTcp; });
@@ -459,41 +346,7 @@ RecursorLua4::RecursorLua4(const std::string& fname)
   d_lw->registerFunction("check",(bool (SuffixMatchNode::*)(const DNSName&) const) &SuffixMatchNode::check);
   d_lw->registerFunction("toString",(string (SuffixMatchNode::*)() const) &SuffixMatchNode::toString);
 
-
-  d_lw->writeFunction("pdnslog", [](const std::string& msg, boost::optional<int> loglevel) {
-      theL() << (Logger::Urgency)loglevel.get_value_or(Logger::Warning) << msg<<endl;
-    });
-  typedef vector<pair<string, int> > in_t;
-  vector<pair<string, boost::variant<int, in_t, struct timeval* > > >  pd{
-    {"DROP",  (int)PolicyDecision::DROP}
-  };
-
-  vector<pair<string, int> > rcodes = {{"NOERROR",  RCode::NoError  },
-                                       {"FORMERR",  RCode::FormErr  },
-                                       {"SERVFAIL", RCode::ServFail },
-                                       {"NXDOMAIN", RCode::NXDomain },
-                                       {"NOTIMP",   RCode::NotImp   },
-                                       {"REFUSED",  RCode::Refused  },
-                                       {"YXDOMAIN", RCode::YXDomain },
-                                       {"YXRRSET",  RCode::YXRRSet  },
-                                       {"NXRRSET",  RCode::NXRRSet  },
-                                       {"NOTAUTH",  RCode::NotAuth  },
-                                       {"NOTZONE",  RCode::NotZone  }};
-  for(const auto& rcode : rcodes)
-    pd.push_back({rcode.first, rcode.second});
-
-  pd.push_back({"loglevels", in_t{
-        {"Alert", LOG_ALERT},
-       {"Critical", LOG_CRIT},
-       {"Debug", LOG_DEBUG},
-        {"Emergency", LOG_EMERG},
-       {"Info", LOG_INFO},
-       {"Notice", LOG_NOTICE},
-       {"Warning", LOG_WARNING},
-       {"Error", LOG_ERR}
-         }});
-
-  pd.push_back({"policykinds", in_t {
+  d_pd.push_back({"policykinds", in_t {
     {"NoAction", (int)DNSFilterEngine::PolicyKind::NoAction},
     {"Drop",     (int)DNSFilterEngine::PolicyKind::Drop    },
     {"NXDOMAIN", (int)DNSFilterEngine::PolicyKind::NXDOMAIN},
@@ -503,20 +356,16 @@ RecursorLua4::RecursorLua4(const std::string& fname)
     }});
 
   for(const auto& n : QType::names)
-    pd.push_back({n.first, n.second});
+    d_pd.push_back({n.first, n.second});
 
-  pd.push_back({"validationstates", in_t{
+  d_pd.push_back({"validationstates", in_t{
         {"Indeterminate", Indeterminate },
         {"Bogus", Bogus },
         {"Insecure", Insecure },
         {"Secure", Secure },
   }});
 
-  pd.push_back({"now", &g_now});
-  d_lw->registerMember("tv_sec", &timeval::tv_sec);
-  d_lw->registerMember("tv_usec", &timeval::tv_usec);
-
-  d_lw->writeVariable("pdns", pd);
+  d_pd.push_back({"now", &g_now});
 
   d_lw->writeFunction("getMetric", [](const std::string& str) {
       return DynMetric{getDynMetric(str)};
@@ -545,13 +394,9 @@ RecursorLua4::RecursorLua4(const std::string& fname)
         g_snmpAgent->sendCustomTrap(str);
       }
     });
-  
-  ifstream ifs(fname);
-  if(!ifs) {
-    throw std::runtime_error("Unable to read configuration file from '"+fname+"': "+strerror(errno));
-  }    
-  d_lw->executeCode(ifs);
+}
 
+void RecursorLua4::postLoad() {
   d_prerpz = d_lw->readVariable<boost::optional<luacall_t>>("prerpz").get_value_or(0);
   d_preresolve = d_lw->readVariable<boost::optional<luacall_t>>("preresolve").get_value_or(0);
   d_nodata = d_lw->readVariable<boost::optional<luacall_t>>("nodata").get_value_or(0);
index f7ef48e7edd857bd2f2cde864535c4181c454089..362683daf577d2fdb89face26a83fe40bae80244 100644 (file)
@@ -21,8 +21,6 @@
  */
 #pragma once
 
-#include <unordered_map>
-
 #ifdef HAVE_CONFIG_H
 #include "config.h"
 #endif
 #include "filterpo.hh"
 #include "ednsoptions.hh"
 #include "validate.hh"
+#include "lua-base4.hh"
+#include <unordered_map>
 
 string GenUDPQueryResponse(const ComboAddress& dest, const string& query);
 unsigned int getRecursorThreadId();
 
-class LuaContext;
-
-#if defined(HAVE_LUA)
-#undef L
-#include "ext/luawrapper/include/LuaContext.hpp"
-#define L theL()
-#endif
-
-class RecursorLua4 : public boost::noncopyable
+class RecursorLua4 : public BaseLua4
 {
-private:
-  std::unique_ptr<LuaContext> d_lw; // this is way on top because it must get destroyed _last_
-
 public:
-  explicit RecursorLua4(const std::stringfname);
+  explicit RecursorLua4(const std::string &fname);
   ~RecursorLua4(); // this is so unique_ptr works with an incomplete type
 
   struct DNSQuestion
@@ -128,7 +117,9 @@ public:
 
   typedef std::function<std::tuple<unsigned int,boost::optional<std::unordered_map<int,string> >,boost::optional<LuaContext::LuaObject>,boost::optional<std::string>,boost::optional<std::string> >(ComboAddress, Netmask, ComboAddress, DNSName, uint16_t, const std::map<uint16_t, EDNSOptionView>&, bool)> gettag_t;
   gettag_t d_gettag; // public so you can query if we have this hooked
-
+protected:
+  void postPrepareContext() override;
+  void postLoad() override;
 private:
   typedef std::function<bool(DNSQuestion*)> luacall_t;
   luacall_t d_prerpz, d_preresolve, d_nxdomain, d_nodata, d_postresolve, d_preoutquery, d_postoutquery;
index f732e5cf1bf5f2535b23b8cd78c991471402daab..8c2070ae22111a8c98bd5e17249e43a015a1d0b9 100644 (file)
@@ -111,6 +111,7 @@ pdns_recursor_SOURCES = \
        lazy_allocator.hh \
        lock.hh \
        logger.hh logger.cc \
+       lua-base4.cc lua-base4.hh \
        lua-recursor4.cc lua-recursor4.hh \
        lwres.cc lwres.hh \
        misc.hh misc.cc \
diff --git a/pdns/recursordist/lua-base4.cc b/pdns/recursordist/lua-base4.cc
new file mode 120000 (symlink)
index 0000000..4ed706f
--- /dev/null
@@ -0,0 +1 @@
+../lua-base4.cc
\ No newline at end of file
diff --git a/pdns/recursordist/lua-base4.hh b/pdns/recursordist/lua-base4.hh
new file mode 120000 (symlink)
index 0000000..2994ed9
--- /dev/null
@@ -0,0 +1 @@
+../lua-base4.hh
\ No newline at end of file