]> granicus.if.org Git - pdns/commitdiff
lua-auth4: Implement axfrfilter
authorAki Tuomi <cmouse@cmouse.fi>
Mon, 17 Apr 2017 16:47:53 +0000 (19:47 +0300)
committerAki Tuomi <cmouse@cmouse.fi>
Mon, 17 Apr 2017 17:37:18 +0000 (20:37 +0300)
pdns/lua-auth4.cc
pdns/lua-auth4.hh

index 6503e9cbd15d4be7c0afc5bfe77f9e06009a436e..a14c12b3fbfd3d31a95dd251bee68b5910f32409 100644 (file)
@@ -11,6 +11,7 @@
 
 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() { }
 
 #else
@@ -203,6 +204,7 @@ 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; });
@@ -222,8 +224,48 @@ AuthLua4::AuthLua4(const std::string& fname) {
   d_lw->executeCode(ifs);
 
   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);
+
+}
+
+bool AuthLua4::axfrfilter(const ComboAddress& remote, const DNSName& zone, const DNSResourceRecord& in, vector<DNSResourceRecord>& out) {
+  luacall_axfr_filter_t::result_type ret;
+  int rcode;
+
+  if (d_axfr_filter == NULL) return false;
+
+  ret = d_axfr_filter(remote, zone, in);
+  rcode = std::get<0>(ret);
+  if (rcode < 0)
+    return false;
+  else if (rcode == 1)
+    out.push_back(in);
+  else
+    throw PDNSException("Cannot understand return code "+std::to_string(rcode)+" in axfr filter response");
+
+  const auto& rows = std::get<1>(ret);
+
+  for(const auto& row: rows) {
+    DNSResourceRecord rec;
+    for(const auto& col: row.second) {
+      if (col.first == "qtype")
+        rec.qtype = QType(boost::get<unsigned int>(col.second));
+      else if (col.first == "qname")
+        rec.qname = DNSName(boost::get<std::string>(col.second));
+      else if (col.first == "ttl")
+        rec.ttl = boost::get<unsigned int>(col.second);
+      else if (col.first == "content")
+        rec.setContent(boost::get<std::string>(col.second));
+      else
+        throw PDNSException("Cannot understand "+col.first+" in axfr filter response on row "+std::to_string(row.first));
+    }
+    out.push_back(rec);
+  }
+
+  return true;
 }
 
+
 bool AuthLua4::updatePolicy(const DNSName &qname, QType qtype, const DNSName &zonename, DNSPacket *packet) {
   UpdatePolicyQuery upq;
   upq.qname = qname;
index 103460c3d12922f7e1808c8a56d18a3f7efec965..3bad3541f7c79ab300a2fb7f25dbc7870bf13eef 100644 (file)
@@ -5,6 +5,7 @@
 #include "dnsrecords.hh"
 #include "dnspacket.hh"
 #include <unordered_map>
+#include <boost/variant/variant.hpp>
 #ifdef HAVE_CONFIG_H
 #include "config.h"
 #endif
@@ -21,6 +22,7 @@ private:
 public:
   explicit AuthLua4(const std::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
 private:
@@ -35,6 +37,8 @@ private:
   };
 
   typedef std::function<bool(const UpdatePolicyQuery&)> luacall_update_policy_t;
+  typedef std::function<std::tuple<int, std::unordered_map<int, std::unordered_map<std::string,boost::variant<unsigned int,std::string> > > >(const ComboAddress&, const DNSName&, const DNSResourceRecord&)> luacall_axfr_filter_t;
 
   luacall_update_policy_t d_update_policy;
+  luacall_axfr_filter_t d_axfr_filter;
 };