]> granicus.if.org Git - pdns/commitdiff
dnsdist: Split dnsdist-lua-bindings.cc
authorRemi Gacogne <remi.gacogne@powerdns.com>
Thu, 29 Aug 2019 13:15:04 +0000 (15:15 +0200)
committerRemi Gacogne <remi.gacogne@powerdns.com>
Thu, 29 Aug 2019 13:15:04 +0000 (15:15 +0200)
Hopefully this will reduce the memory usage needed to compile it.

pdns/dnsdist-lua-bindings.cc
pdns/dnsdist-lua.cc
pdns/dnsdist-lua.hh
pdns/dnsdistdist/Makefile.am
pdns/dnsdistdist/dnsdist-lua-bindings-dnscrypt.cc [new file with mode: 0644]
pdns/dnsdistdist/dnsdist-lua-bindings-kvs.cc [new file with mode: 0644]
pdns/dnsdistdist/dnsdist-lua-bindings-packetcache.cc [new file with mode: 0644]
pdns/dnsdistdist/dnsdist-lua-bindings-protobuf.cc [new file with mode: 0644]

index fc51198b0c6bc2bd92bd34c8e4f4a3c3cf608691..9ad4b70d370c2625d530f5643f6c8a1ecd176e51 100644 (file)
  * along with this program; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
  */
-#include <fcntl.h>
-#include <sys/stat.h>
-#include <sys/types.h>
-
 #include "config.h"
 #include "dnsdist.hh"
-#include "dnsdist-kvs.hh"
 #include "dnsdist-lua.hh"
-#include "dnsdist-protobuf.hh"
 
-#include "dnstap.hh"
 #include "dolog.hh"
-#include "fstrm_logger.hh"
-#include "remote_logger.hh"
-
-#ifdef HAVE_LIBCRYPTO
-#include "ipcipher.hh"
-#endif /* HAVE_LIBCRYPTO */
 
 void setupLuaBindings(bool client)
 {
@@ -172,19 +159,6 @@ void setupLuaBindings(bool client)
   g_lua.registerFunction<ComboAddress(ComboAddress::*)()>("mapToIPv4", [](const ComboAddress& ca) { return ca.mapToIPv4(); });
   g_lua.registerFunction<bool(nmts_t::*)(const ComboAddress&)>("match", [](nmts_t& s, const ComboAddress& ca) { return s.match(ca); });
 
-#ifdef HAVE_LIBCRYPTO
-  g_lua.registerFunction<ComboAddress(ComboAddress::*)(const std::string& key)>("ipencrypt", [](const ComboAddress& ca, const std::string& key) {
-      return encryptCA(ca, key);
-    });
-  g_lua.registerFunction<ComboAddress(ComboAddress::*)(const std::string& key)>("ipdecrypt", [](const ComboAddress& ca, const std::string& key) {
-      return decryptCA(ca, key);
-    });
-
-  g_lua.writeFunction("makeIPCipherKey", [](const std::string& password) {
-      return makeIPCipherKey(password);
-    });
-#endif /* HAVE_LIBCRYPTO */
-
   /* DNSName */
   g_lua.registerFunction("isPartOf", &DNSName::isPartOf);
   g_lua.registerFunction<bool(DNSName::*)()>("chopOff", [](DNSName&dn ) { return dn.chopOff(); });
@@ -273,326 +247,6 @@ void setupLuaBindings(bool client)
     });
 #endif /* HAVE_EBPF */
 
-  /* PacketCache */
-  g_lua.writeFunction("newPacketCache", [](size_t maxEntries, boost::optional<std::unordered_map<std::string, boost::variant<bool, size_t>>> vars) {
-
-      bool keepStaleData = false;
-      size_t maxTTL = 86400;
-      size_t minTTL = 0;
-      size_t tempFailTTL = 60;
-      size_t maxNegativeTTL = 3600;
-      size_t staleTTL = 60;
-      size_t numberOfShards = 1;
-      bool dontAge = false;
-      bool deferrableInsertLock = true;
-      bool ecsParsing = false;
-
-      if (vars) {
-
-        if (vars->count("deferrableInsertLock")) {
-          deferrableInsertLock = boost::get<bool>((*vars)["deferrableInsertLock"]);
-        }
-
-        if (vars->count("dontAge")) {
-          dontAge = boost::get<bool>((*vars)["dontAge"]);
-        }
-
-        if (vars->count("keepStaleData")) {
-          keepStaleData = boost::get<bool>((*vars)["keepStaleData"]);
-        }
-
-        if (vars->count("maxNegativeTTL")) {
-          maxNegativeTTL = boost::get<size_t>((*vars)["maxNegativeTTL"]);
-        }
-
-        if (vars->count("maxTTL")) {
-          maxTTL = boost::get<size_t>((*vars)["maxTTL"]);
-        }
-
-        if (vars->count("minTTL")) {
-          minTTL = boost::get<size_t>((*vars)["minTTL"]);
-        }
-
-        if (vars->count("numberOfShards")) {
-          numberOfShards = boost::get<size_t>((*vars)["numberOfShards"]);
-        }
-
-        if (vars->count("parseECS")) {
-          ecsParsing = boost::get<bool>((*vars)["parseECS"]);
-        }
-
-        if (vars->count("staleTTL")) {
-          staleTTL = boost::get<size_t>((*vars)["staleTTL"]);
-        }
-
-        if (vars->count("temporaryFailureTTL")) {
-          tempFailTTL = boost::get<size_t>((*vars)["temporaryFailureTTL"]);
-        }
-      }
-
-      auto res = std::make_shared<DNSDistPacketCache>(maxEntries, maxTTL, minTTL, tempFailTTL, maxNegativeTTL, staleTTL, dontAge, numberOfShards, deferrableInsertLock, ecsParsing);
-
-      res->setKeepStaleData(keepStaleData);
-
-      return res;
-    });
-  g_lua.registerFunction("toString", &DNSDistPacketCache::toString);
-  g_lua.registerFunction("isFull", &DNSDistPacketCache::isFull);
-  g_lua.registerFunction("purgeExpired", &DNSDistPacketCache::purgeExpired);
-  g_lua.registerFunction("expunge", &DNSDistPacketCache::expunge);
-  g_lua.registerFunction<void(std::shared_ptr<DNSDistPacketCache>::*)(const DNSName& dname, boost::optional<uint16_t> qtype, boost::optional<bool> suffixMatch)>("expungeByName", [](
-              std::shared_ptr<DNSDistPacketCache> cache,
-              const DNSName& dname,
-              boost::optional<uint16_t> qtype,
-              boost::optional<bool> suffixMatch) {
-                if (cache) {
-                  g_outputBuffer="Expunged " + std::to_string(cache->expungeByName(dname, qtype ? *qtype : QType(QType::ANY).getCode(), suffixMatch ? *suffixMatch : false)) + " records\n";
-                }
-    });
-  g_lua.registerFunction<void(std::shared_ptr<DNSDistPacketCache>::*)()>("printStats", [](const std::shared_ptr<DNSDistPacketCache> cache) {
-      if (cache) {
-        g_outputBuffer="Entries: " + std::to_string(cache->getEntriesCount()) + "/" + std::to_string(cache->getMaxEntries()) + "\n";
-        g_outputBuffer+="Hits: " + std::to_string(cache->getHits()) + "\n";
-        g_outputBuffer+="Misses: " + std::to_string(cache->getMisses()) + "\n";
-        g_outputBuffer+="Deferred inserts: " + std::to_string(cache->getDeferredInserts()) + "\n";
-        g_outputBuffer+="Deferred lookups: " + std::to_string(cache->getDeferredLookups()) + "\n";
-        g_outputBuffer+="Lookup Collisions: " + std::to_string(cache->getLookupCollisions()) + "\n";
-        g_outputBuffer+="Insert Collisions: " + std::to_string(cache->getInsertCollisions()) + "\n";
-        g_outputBuffer+="TTL Too Shorts: " + std::to_string(cache->getTTLTooShorts()) + "\n";
-      }
-    });
-  g_lua.registerFunction<std::unordered_map<std::string, uint64_t>(std::shared_ptr<DNSDistPacketCache>::*)()>("getStats", [](const std::shared_ptr<DNSDistPacketCache> cache) {
-      std::unordered_map<std::string, uint64_t> stats;
-      if (cache) {
-        stats["entries"] = cache->getEntriesCount();
-        stats["maxEntries"] = cache->getMaxEntries();
-        stats["hits"] = cache->getHits();
-        stats["misses"] = cache->getMisses();
-        stats["deferredInserts"] = cache->getDeferredInserts();
-        stats["deferredLookups"] = cache->getDeferredLookups();
-        stats["lookupCollisions"] = cache->getLookupCollisions();
-        stats["insertCollisions"] = cache->getInsertCollisions();
-        stats["ttlTooShorts"] = cache->getTTLTooShorts();
-      }
-      return stats;
-    });
-  g_lua.registerFunction<void(std::shared_ptr<DNSDistPacketCache>::*)(const std::string& fname)>("dump", [](const std::shared_ptr<DNSDistPacketCache> cache, const std::string& fname) {
-      if (cache) {
-
-        int fd = open(fname.c_str(), O_CREAT | O_EXCL | O_WRONLY, 0660);
-        if (fd < 0) {
-          g_outputBuffer = "Error opening dump file for writing: " + string(strerror(errno)) + "\n";
-          return;
-        }
-
-        uint64_t records = 0;
-        try {
-          records = cache->dump(fd);
-        }
-        catch (const std::exception& e) {
-          close(fd);
-          throw;
-        }
-
-        close(fd);
-
-        g_outputBuffer += "Dumped " + std::to_string(records) + " records\n";
-      }
-    });
-
-  /* ProtobufMessage */
-  g_lua.registerFunction<void(DNSDistProtoBufMessage::*)(std::string)>("setTag", [](DNSDistProtoBufMessage& message, const std::string& strValue) {
-      message.addTag(strValue);
-    });
-  g_lua.registerFunction<void(DNSDistProtoBufMessage::*)(vector<pair<int, string>>)>("setTagArray", [](DNSDistProtoBufMessage& message, const vector<pair<int, string>>&tags) {
-      for (const auto& tag : tags) {
-        message.addTag(tag.second);
-      }
-    });
-  g_lua.registerFunction<void(DNSDistProtoBufMessage::*)(boost::optional <time_t> sec, boost::optional <uint32_t> uSec)>("setProtobufResponseType",
-                                        [](DNSDistProtoBufMessage& message, boost::optional <time_t> sec, boost::optional <uint32_t> uSec) {
-      message.setType(DNSProtoBufMessage::Response);
-      message.setQueryTime(sec?*sec:0, uSec?*uSec:0);
-    });
-  g_lua.registerFunction<void(DNSDistProtoBufMessage::*)(const std::string& strQueryName, uint16_t uType, uint16_t uClass, uint32_t uTTL, const std::string& strBlob)>("addResponseRR", [](DNSDistProtoBufMessage& message,
-                                                            const std::string& strQueryName, uint16_t uType, uint16_t uClass, uint32_t uTTL, const std::string& strBlob) {
-      message.addRR(DNSName(strQueryName), uType, uClass, uTTL, strBlob);
-    });
-  g_lua.registerFunction<void(DNSDistProtoBufMessage::*)(const Netmask&)>("setEDNSSubnet", [](DNSDistProtoBufMessage& message, const Netmask& subnet) { message.setEDNSSubnet(subnet); });
-  g_lua.registerFunction<void(DNSDistProtoBufMessage::*)(const DNSName&, uint16_t, uint16_t)>("setQuestion", [](DNSDistProtoBufMessage& message, const DNSName& qname, uint16_t qtype, uint16_t qclass) { message.setQuestion(qname, qtype, qclass); });
-  g_lua.registerFunction<void(DNSDistProtoBufMessage::*)(size_t)>("setBytes", [](DNSDistProtoBufMessage& message, size_t bytes) { message.setBytes(bytes); });
-  g_lua.registerFunction<void(DNSDistProtoBufMessage::*)(time_t, uint32_t)>("setTime", [](DNSDistProtoBufMessage& message, time_t sec, uint32_t usec) { message.setTime(sec, usec); });
-  g_lua.registerFunction<void(DNSDistProtoBufMessage::*)(time_t, uint32_t)>("setQueryTime", [](DNSDistProtoBufMessage& message, time_t sec, uint32_t usec) { message.setQueryTime(sec, usec); });
-  g_lua.registerFunction<void(DNSDistProtoBufMessage::*)(uint8_t)>("setResponseCode", [](DNSDistProtoBufMessage& message, uint8_t rcode) { message.setResponseCode(rcode); });
-  g_lua.registerFunction<std::string(DNSDistProtoBufMessage::*)()>("toDebugString", [](const DNSDistProtoBufMessage& message) { return message.toDebugString(); });
-  g_lua.registerFunction<void(DNSDistProtoBufMessage::*)(const ComboAddress&)>("setRequestor", [](DNSDistProtoBufMessage& message, const ComboAddress& addr) {
-      message.setRequestor(addr);
-    });
-  g_lua.registerFunction<void(DNSDistProtoBufMessage::*)(const std::string&)>("setRequestorFromString", [](DNSDistProtoBufMessage& message, const std::string& str) {
-      message.setRequestor(str);
-    });
-  g_lua.registerFunction<void(DNSDistProtoBufMessage::*)(const ComboAddress&)>("setResponder", [](DNSDistProtoBufMessage& message, const ComboAddress& addr) {
-      message.setResponder(addr);
-    });
-  g_lua.registerFunction<void(DNSDistProtoBufMessage::*)(const std::string&)>("setResponderFromString", [](DNSDistProtoBufMessage& message, const std::string& str) {
-      message.setResponder(str);
-    });
-  g_lua.registerFunction<void(DNSDistProtoBufMessage::*)(const std::string&)>("setServerIdentity", [](DNSDistProtoBufMessage& message, const std::string& str) {
-      message.setServerIdentity(str);
-    });
-
-  g_lua.registerFunction<std::string(DnstapMessage::*)()>("toDebugString", [](const DnstapMessage& message) { return message.toDebugString(); });
-  g_lua.registerFunction<void(DnstapMessage::*)(const std::string&)>("setExtra", [](DnstapMessage& message, const std::string& str) {
-      message.setExtra(str);
-    });
-
-  /* RemoteLogger */
-  g_lua.writeFunction("newRemoteLogger", [client](const std::string& remote, boost::optional<uint16_t> timeout, boost::optional<uint64_t> maxQueuedEntries, boost::optional<uint8_t> reconnectWaitTime) {
-      return std::shared_ptr<RemoteLoggerInterface>(new RemoteLogger(ComboAddress(remote), timeout ? *timeout : 2, maxQueuedEntries ? (*maxQueuedEntries*100) : 10000, reconnectWaitTime ? *reconnectWaitTime : 1, client));
-    });
-
-  g_lua.writeFunction("newFrameStreamUnixLogger", [client](const std::string& address) {
-#ifdef HAVE_FSTRM
-      return std::shared_ptr<RemoteLoggerInterface>(new FrameStreamLogger(AF_UNIX, address, !client));
-#else
-      throw std::runtime_error("fstrm support is required to build an AF_UNIX FrameStreamLogger");
-#endif /* HAVE_FSTRM */
-    });
-
-  g_lua.writeFunction("newFrameStreamTcpLogger", [client](const std::string& address) {
-#if defined(HAVE_FSTRM) && defined(HAVE_FSTRM_TCP_WRITER_INIT)
-      return std::shared_ptr<RemoteLoggerInterface>(new FrameStreamLogger(AF_INET, address, !client));
-#else
-      throw std::runtime_error("fstrm with TCP support is required to build an AF_INET FrameStreamLogger");
-#endif /* HAVE_FSTRM */
-    });
-
-  g_lua.registerFunction("toString", &RemoteLoggerInterface::toString);
-
-#ifdef HAVE_DNSCRYPT
-    /* DNSCryptContext bindings */
-    g_lua.registerFunction<std::string(DNSCryptContext::*)()>("getProviderName", [](const DNSCryptContext& ctx) { return ctx.getProviderName().toStringNoDot(); });
-    g_lua.registerFunction("markActive", &DNSCryptContext::markActive);
-    g_lua.registerFunction("markInactive", &DNSCryptContext::markInactive);
-    g_lua.registerFunction("removeInactiveCertificate", &DNSCryptContext::removeInactiveCertificate);
-    g_lua.registerFunction<void(std::shared_ptr<DNSCryptContext>::*)(const std::string& certFile, const std::string& keyFile, boost::optional<bool> active)>("loadNewCertificate", [](std::shared_ptr<DNSCryptContext> ctx, const std::string& certFile, const std::string& keyFile, boost::optional<bool> active) {
-
-      if (ctx == nullptr) {
-        throw std::runtime_error("DNSCryptContext::loadNewCertificate() called on a nil value");
-      }
-
-      ctx->loadNewCertificate(certFile, keyFile, active ? *active : true);
-    });
-    g_lua.registerFunction<void(std::shared_ptr<DNSCryptContext>::*)(const DNSCryptCert& newCert, const DNSCryptPrivateKey& newKey, boost::optional<bool> active)>("addNewCertificate", [](std::shared_ptr<DNSCryptContext> ctx, const DNSCryptCert& newCert, const DNSCryptPrivateKey& newKey, boost::optional<bool> active) {
-
-      if (ctx == nullptr) {
-        throw std::runtime_error("DNSCryptContext::addNewCertificate() called on a nil value");
-      }
-
-      ctx->addNewCertificate(newCert, newKey, active ? *active : true);
-    });
-    g_lua.registerFunction<std::map<int, std::shared_ptr<DNSCryptCertificatePair>>(std::shared_ptr<DNSCryptContext>::*)()>("getCertificatePairs", [](std::shared_ptr<DNSCryptContext> ctx) {
-      std::map<int, std::shared_ptr<DNSCryptCertificatePair>> result;
-
-      if (ctx != nullptr) {
-        size_t idx = 1;
-        for (auto pair : ctx->getCertificates()) {
-          result[idx++] = pair;
-        }
-      }
-
-      return result;
-    });
-
-    g_lua.registerFunction<std::shared_ptr<DNSCryptCertificatePair>(std::shared_ptr<DNSCryptContext>::*)(size_t idx)>("getCertificatePair", [](std::shared_ptr<DNSCryptContext> ctx, size_t idx) {
-
-      if (ctx == nullptr) {
-        throw std::runtime_error("DNSCryptContext::getCertificatePair() called on a nil value");
-      }
-
-      std::shared_ptr<DNSCryptCertificatePair> result = nullptr;
-      auto pairs = ctx->getCertificates();
-      if (idx < pairs.size()) {
-        result = pairs.at(idx);
-      }
-
-      return result;
-    });
-
-    g_lua.registerFunction<const DNSCryptCert(std::shared_ptr<DNSCryptContext>::*)(size_t idx)>("getCertificate", [](std::shared_ptr<DNSCryptContext> ctx, size_t idx) {
-
-      if (ctx == nullptr) {
-        throw std::runtime_error("DNSCryptContext::getCertificate() called on a nil value");
-      }
-
-      auto pairs = ctx->getCertificates();
-      if (idx < pairs.size()) {
-        return pairs.at(idx)->cert;
-      }
-
-      throw std::runtime_error("This DNSCrypt context has no certificate at index " + std::to_string(idx));
-    });
-
-    g_lua.registerFunction<std::string(std::shared_ptr<DNSCryptContext>::*)()>("printCertificates", [](const std::shared_ptr<DNSCryptContext> ctx) {
-      ostringstream ret;
-
-      if (ctx != nullptr) {
-        size_t idx = 1;
-        boost::format fmt("%1$-3d %|5t|%2$-8d %|10t|%3$-7d %|20t|%4$-21.21s %|41t|%5$-21.21s");
-        ret << (fmt % "#" % "Serial" % "Version" % "From" % "To" ) << endl;
-
-        for (auto pair : ctx->getCertificates()) {
-          const auto cert = pair->cert;
-          const DNSCryptExchangeVersion version = DNSCryptContext::getExchangeVersion(cert);
-
-          ret << (fmt % idx % cert.getSerial() % (version == DNSCryptExchangeVersion::VERSION1 ? 1 : 2) % DNSCryptContext::certificateDateToStr(cert.getTSStart()) % DNSCryptContext::certificateDateToStr(cert.getTSEnd())) << endl;
-        }
-      }
-
-      return ret.str();
-    });
-
-    g_lua.registerFunction<void(DNSCryptContext::*)(const std::string& providerPrivateKeyFile, uint32_t serial, time_t begin, time_t end, boost::optional<DNSCryptExchangeVersion> version)>("generateAndLoadInMemoryCertificate", [](DNSCryptContext& ctx, const std::string& providerPrivateKeyFile, uint32_t serial, time_t begin, time_t end, boost::optional<DNSCryptExchangeVersion> version) {
-        DNSCryptPrivateKey privateKey;
-        DNSCryptCert cert;
-
-        try {
-          if (generateDNSCryptCertificate(providerPrivateKeyFile, serial, begin, end, version ? *version : DNSCryptExchangeVersion::VERSION1, cert, privateKey)) {
-            ctx.addNewCertificate(cert, privateKey);
-          }
-        }
-        catch(const std::exception& e) {
-          errlog(e.what());
-          g_outputBuffer="Error: "+string(e.what())+"\n";
-        }
-    });
-
-    /* DNSCryptCertificatePair */
-    g_lua.registerFunction<const DNSCryptCert(std::shared_ptr<DNSCryptCertificatePair>::*)()>("getCertificate", [](const std::shared_ptr<DNSCryptCertificatePair> pair) {
-      if (pair == nullptr) {
-        throw std::runtime_error("DNSCryptCertificatePair::getCertificate() called on a nil value");
-      }
-      return pair->cert;
-    });
-    g_lua.registerFunction<bool(std::shared_ptr<DNSCryptCertificatePair>::*)()>("isActive", [](const std::shared_ptr<DNSCryptCertificatePair> pair) {
-      if (pair == nullptr) {
-        throw std::runtime_error("DNSCryptCertificatePair::isActive() called on a nil value");
-      }
-      return pair->active;
-    });
-
-    /* DNSCryptCert */
-    g_lua.registerFunction<std::string(DNSCryptCert::*)()>("getMagic", [](const DNSCryptCert& cert) { return std::string(reinterpret_cast<const char*>(cert.magic), sizeof(cert.magic)); });
-    g_lua.registerFunction<std::string(DNSCryptCert::*)()>("getEsVersion", [](const DNSCryptCert& cert) { return std::string(reinterpret_cast<const char*>(cert.esVersion), sizeof(cert.esVersion)); });
-    g_lua.registerFunction<std::string(DNSCryptCert::*)()>("getProtocolMinorVersion", [](const DNSCryptCert& cert) { return std::string(reinterpret_cast<const char*>(cert.protocolMinorVersion), sizeof(cert.protocolMinorVersion)); });
-    g_lua.registerFunction<std::string(DNSCryptCert::*)()>("getSignature", [](const DNSCryptCert& cert) { return std::string(reinterpret_cast<const char*>(cert.signature), sizeof(cert.signature)); });
-    g_lua.registerFunction<std::string(DNSCryptCert::*)()>("getResolverPublicKey", [](const DNSCryptCert& cert) { return std::string(reinterpret_cast<const char*>(cert.signedData.resolverPK), sizeof(cert.signedData.resolverPK)); });
-    g_lua.registerFunction<std::string(DNSCryptCert::*)()>("getClientMagic", [](const DNSCryptCert& cert) { return std::string(reinterpret_cast<const char*>(cert.signedData.clientMagic), sizeof(cert.signedData.clientMagic)); });
-    g_lua.registerFunction<uint32_t(DNSCryptCert::*)()>("getSerial", [](const DNSCryptCert& cert) { return cert.getSerial(); });
-    g_lua.registerFunction<uint32_t(DNSCryptCert::*)()>("getTSStart", [](const DNSCryptCert& cert) { return ntohl(cert.getTSStart()); });
-    g_lua.registerFunction<uint32_t(DNSCryptCert::*)()>("getTSEnd", [](const DNSCryptCert& cert) { return ntohl(cert.getTSEnd()); });
-#endif
-
   /* BPF Filter */
 #ifdef HAVE_EBPF
   g_lua.writeFunction("newBPFFilter", [client](uint32_t maxV4, uint32_t maxV6, uint32_t maxQNames) {
@@ -715,92 +369,4 @@ void setupLuaBindings(bool client)
     return values;
   });
 
-  /* Key Value Store objects */
-  g_lua.writeFunction("KeyValueLookupKeySourceIP", []() {
-    return std::shared_ptr<KeyValueLookupKey>(new KeyValueLookupKeySourceIP());
-  });
-  g_lua.writeFunction("KeyValueLookupKeyQName", [](boost::optional<bool> wireFormat) {
-    return std::shared_ptr<KeyValueLookupKey>(new KeyValueLookupKeyQName(wireFormat ? *wireFormat : true));
-  });
-  g_lua.writeFunction("KeyValueLookupKeySuffix", [](boost::optional<size_t> minLabels, boost::optional<bool> wireFormat) {
-    return std::shared_ptr<KeyValueLookupKey>(new KeyValueLookupKeySuffix(minLabels ? *minLabels : 0, wireFormat ? *wireFormat : true));
-  });
-  g_lua.writeFunction("KeyValueLookupKeyTag", [](const std::string& tag) {
-    return std::shared_ptr<KeyValueLookupKey>(new KeyValueLookupKeyTag(tag));
-  });
-
-#ifdef HAVE_LMDB
-  g_lua.writeFunction("newLMDBKVStore", [client](const std::string& fname, const std::string& dbName) {
-    if (client) {
-      return std::shared_ptr<KeyValueStore>(nullptr);
-    }
-    return std::shared_ptr<KeyValueStore>(new LMDBKVStore(fname, dbName));
-  });
-#endif /* HAVE_LMDB */
-
-#ifdef HAVE_CDB
-  g_lua.writeFunction("newCDBKVStore", [client](const std::string& fname, time_t refreshDelay) {
-    if (client) {
-      return std::shared_ptr<KeyValueStore>(nullptr);
-    }
-    return std::shared_ptr<KeyValueStore>(new CDBKVStore(fname, refreshDelay));
-  });
-#endif /* HAVE_CDB */
-
-  g_lua.registerFunction<std::string(std::shared_ptr<KeyValueStore>::*)(const boost::variant<ComboAddress, DNSName, std::string>, boost::optional<bool> wireFormat)>("lookup", [](std::shared_ptr<KeyValueStore>& kvs, const boost::variant<ComboAddress, DNSName, std::string> keyVar, boost::optional<bool> wireFormat) {
-    std::string result;
-    if (!kvs) {
-      return result;
-    }
-
-    if (keyVar.type() == typeid(ComboAddress)) {
-      const auto ca = *boost::get<ComboAddress>(&keyVar);
-      KeyValueLookupKeySourceIP lookup;
-      for (const auto& key : lookup.getKeys(ca)) {
-        if (kvs->getValue(key, result)) {
-          return result;
-        }
-      }
-    }
-    else if (keyVar.type() == typeid(DNSName)) {
-      DNSName dn = *boost::get<DNSName>(&keyVar);
-      KeyValueLookupKeyQName lookup(wireFormat ? *wireFormat : true);
-      for (const auto& key : lookup.getKeys(dn)) {
-        if (kvs->getValue(key, result)) {
-          return result;
-        }
-      }
-    }
-    else if (keyVar.type() == typeid(std::string)) {
-      std::string keyStr = *boost::get<std::string>(&keyVar);
-      kvs->getValue(keyStr, result);
-    }
-
-    return result;
-  });
-
-  g_lua.registerFunction<std::string(std::shared_ptr<KeyValueStore>::*)(const DNSName&, boost::optional<size_t> minLabels, boost::optional<bool> wireFormat)>("lookupSuffix", [](std::shared_ptr<KeyValueStore>& kvs, const DNSName& dn, boost::optional<size_t> minLabels, boost::optional<bool> wireFormat) {
-    std::string result;
-    if (!kvs) {
-      return result;
-    }
-
-    KeyValueLookupKeySuffix lookup(minLabels ? *minLabels : 0, wireFormat ? *wireFormat : true);
-    for (const auto& key : lookup.getKeys(dn)) {
-      if (kvs->getValue(key, result)) {
-        return result;
-      }
-    }
-
-    return result;
-  });
-
-  g_lua.registerFunction<bool(std::shared_ptr<KeyValueStore>::*)()>("reload", [](std::shared_ptr<KeyValueStore>& kvs) {
-    if (!kvs) {
-      return false;
-    }
-
-    return kvs->reload();
-  });
-
 }
index f448e6c6fddcf797a89eef906db85dc4812ee314..a1aba5321f40f8dd06dc621644153d1c9c9fb0ce 100644 (file)
@@ -2067,7 +2067,11 @@ vector<std::function<void(void)>> setupLua(bool client, const std::string& confi
   setupLuaActions();
   setupLuaConfig(client);
   setupLuaBindings(client);
+  setupLuaBindingsDNSCrypt();
   setupLuaBindingsDNSQuestion();
+  setupLuaBindingsKVS(client);
+  setupLuaBindingsPacketCache();
+  setupLuaBindingsProtoBuf(client);
   setupLuaInspection();
   setupLuaRules();
   setupLuaVars();
index 7ab5d963ca442e03347d0f94029586b10ca9936f..9bd33266de0eb43eee257ed0f155a9e73990e00b 100644 (file)
@@ -86,7 +86,11 @@ typedef NetmaskTree<DynBlock> nmts_t;
 
 void setupLuaActions();
 void setupLuaBindings(bool client);
+void setupLuaBindingsDNSCrypt();
 void setupLuaBindingsDNSQuestion();
+void setupLuaBindingsKVS(bool client);
+void setupLuaBindingsPacketCache();
+void setupLuaBindingsProtoBuf(bool client);
 void setupLuaRules();
 void setupLuaInspection();
 void setupLuaVars();
index 92b15603411f8bf6b50799c759bd45d4353878e1..101a57932b94c4edeae228084d9db9420d215c40 100644 (file)
@@ -125,7 +125,11 @@ dnsdist_SOURCES = \
        dnsdist-lua.hh dnsdist-lua.cc \
        dnsdist-lua-actions.cc \
        dnsdist-lua-bindings.cc \
+       dnsdist-lua-bindings-dnscrypt.cc \
        dnsdist-lua-bindings-dnsquestion.cc \
+       dnsdist-lua-bindings-kvs.cc \
+       dnsdist-lua-bindings-packetcache.cc \
+       dnsdist-lua-bindings-protobuf.cc \
        dnsdist-lua-inspection.cc \
        dnsdist-lua-inspection-ffi.cc dnsdist-lua-inspection-ffi.hh \
        dnsdist-lua-rules.cc \
diff --git a/pdns/dnsdistdist/dnsdist-lua-bindings-dnscrypt.cc b/pdns/dnsdistdist/dnsdist-lua-bindings-dnscrypt.cc
new file mode 100644 (file)
index 0000000..6a25dcf
--- /dev/null
@@ -0,0 +1,154 @@
+/*
+ * This file is part of PowerDNS or dnsdist.
+ * Copyright -- PowerDNS.COM B.V. and its contributors
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of version 2 of the GNU General Public License as
+ * published by the Free Software Foundation.
+ *
+ * In addition, for the avoidance of any doubt, permission is granted to
+ * link this program with OpenSSL and to (re)distribute the binaries
+ * produced as the result of such linking.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#include "config.h"
+#include "dnsdist.hh"
+#include "dnsdist-lua.hh"
+
+#include "dolog.hh"
+
+void setupLuaBindingsDNSCrypt()
+{
+#ifdef HAVE_DNSCRYPT
+    /* DNSCryptContext bindings */
+    g_lua.registerFunction<std::string(DNSCryptContext::*)()>("getProviderName", [](const DNSCryptContext& ctx) { return ctx.getProviderName().toStringNoDot(); });
+    g_lua.registerFunction("markActive", &DNSCryptContext::markActive);
+    g_lua.registerFunction("markInactive", &DNSCryptContext::markInactive);
+    g_lua.registerFunction("removeInactiveCertificate", &DNSCryptContext::removeInactiveCertificate);
+    g_lua.registerFunction<void(std::shared_ptr<DNSCryptContext>::*)(const std::string& certFile, const std::string& keyFile, boost::optional<bool> active)>("loadNewCertificate", [](std::shared_ptr<DNSCryptContext> ctx, const std::string& certFile, const std::string& keyFile, boost::optional<bool> active) {
+
+      if (ctx == nullptr) {
+        throw std::runtime_error("DNSCryptContext::loadNewCertificate() called on a nil value");
+      }
+
+      ctx->loadNewCertificate(certFile, keyFile, active ? *active : true);
+    });
+    g_lua.registerFunction<void(std::shared_ptr<DNSCryptContext>::*)(const DNSCryptCert& newCert, const DNSCryptPrivateKey& newKey, boost::optional<bool> active)>("addNewCertificate", [](std::shared_ptr<DNSCryptContext> ctx, const DNSCryptCert& newCert, const DNSCryptPrivateKey& newKey, boost::optional<bool> active) {
+
+      if (ctx == nullptr) {
+        throw std::runtime_error("DNSCryptContext::addNewCertificate() called on a nil value");
+      }
+
+      ctx->addNewCertificate(newCert, newKey, active ? *active : true);
+    });
+    g_lua.registerFunction<std::map<int, std::shared_ptr<DNSCryptCertificatePair>>(std::shared_ptr<DNSCryptContext>::*)()>("getCertificatePairs", [](std::shared_ptr<DNSCryptContext> ctx) {
+      std::map<int, std::shared_ptr<DNSCryptCertificatePair>> result;
+
+      if (ctx != nullptr) {
+        size_t idx = 1;
+        for (auto pair : ctx->getCertificates()) {
+          result[idx++] = pair;
+        }
+      }
+
+      return result;
+    });
+
+    g_lua.registerFunction<std::shared_ptr<DNSCryptCertificatePair>(std::shared_ptr<DNSCryptContext>::*)(size_t idx)>("getCertificatePair", [](std::shared_ptr<DNSCryptContext> ctx, size_t idx) {
+
+      if (ctx == nullptr) {
+        throw std::runtime_error("DNSCryptContext::getCertificatePair() called on a nil value");
+      }
+
+      std::shared_ptr<DNSCryptCertificatePair> result = nullptr;
+      auto pairs = ctx->getCertificates();
+      if (idx < pairs.size()) {
+        result = pairs.at(idx);
+      }
+
+      return result;
+    });
+
+    g_lua.registerFunction<const DNSCryptCert(std::shared_ptr<DNSCryptContext>::*)(size_t idx)>("getCertificate", [](std::shared_ptr<DNSCryptContext> ctx, size_t idx) {
+
+      if (ctx == nullptr) {
+        throw std::runtime_error("DNSCryptContext::getCertificate() called on a nil value");
+      }
+
+      auto pairs = ctx->getCertificates();
+      if (idx < pairs.size()) {
+        return pairs.at(idx)->cert;
+      }
+
+      throw std::runtime_error("This DNSCrypt context has no certificate at index " + std::to_string(idx));
+    });
+
+    g_lua.registerFunction<std::string(std::shared_ptr<DNSCryptContext>::*)()>("printCertificates", [](const std::shared_ptr<DNSCryptContext> ctx) {
+      ostringstream ret;
+
+      if (ctx != nullptr) {
+        size_t idx = 1;
+        boost::format fmt("%1$-3d %|5t|%2$-8d %|10t|%3$-7d %|20t|%4$-21.21s %|41t|%5$-21.21s");
+        ret << (fmt % "#" % "Serial" % "Version" % "From" % "To" ) << endl;
+
+        for (auto pair : ctx->getCertificates()) {
+          const auto cert = pair->cert;
+          const DNSCryptExchangeVersion version = DNSCryptContext::getExchangeVersion(cert);
+
+          ret << (fmt % idx % cert.getSerial() % (version == DNSCryptExchangeVersion::VERSION1 ? 1 : 2) % DNSCryptContext::certificateDateToStr(cert.getTSStart()) % DNSCryptContext::certificateDateToStr(cert.getTSEnd())) << endl;
+        }
+      }
+
+      return ret.str();
+    });
+
+    g_lua.registerFunction<void(DNSCryptContext::*)(const std::string& providerPrivateKeyFile, uint32_t serial, time_t begin, time_t end, boost::optional<DNSCryptExchangeVersion> version)>("generateAndLoadInMemoryCertificate", [](DNSCryptContext& ctx, const std::string& providerPrivateKeyFile, uint32_t serial, time_t begin, time_t end, boost::optional<DNSCryptExchangeVersion> version) {
+        DNSCryptPrivateKey privateKey;
+        DNSCryptCert cert;
+
+        try {
+          if (generateDNSCryptCertificate(providerPrivateKeyFile, serial, begin, end, version ? *version : DNSCryptExchangeVersion::VERSION1, cert, privateKey)) {
+            ctx.addNewCertificate(cert, privateKey);
+          }
+        }
+        catch(const std::exception& e) {
+          errlog(e.what());
+          g_outputBuffer="Error: "+string(e.what())+"\n";
+        }
+    });
+
+    /* DNSCryptCertificatePair */
+    g_lua.registerFunction<const DNSCryptCert(std::shared_ptr<DNSCryptCertificatePair>::*)()>("getCertificate", [](const std::shared_ptr<DNSCryptCertificatePair> pair) {
+      if (pair == nullptr) {
+        throw std::runtime_error("DNSCryptCertificatePair::getCertificate() called on a nil value");
+      }
+      return pair->cert;
+    });
+    g_lua.registerFunction<bool(std::shared_ptr<DNSCryptCertificatePair>::*)()>("isActive", [](const std::shared_ptr<DNSCryptCertificatePair> pair) {
+      if (pair == nullptr) {
+        throw std::runtime_error("DNSCryptCertificatePair::isActive() called on a nil value");
+      }
+      return pair->active;
+    });
+
+    /* DNSCryptCert */
+    g_lua.registerFunction<std::string(DNSCryptCert::*)()>("getMagic", [](const DNSCryptCert& cert) { return std::string(reinterpret_cast<const char*>(cert.magic), sizeof(cert.magic)); });
+    g_lua.registerFunction<std::string(DNSCryptCert::*)()>("getEsVersion", [](const DNSCryptCert& cert) { return std::string(reinterpret_cast<const char*>(cert.esVersion), sizeof(cert.esVersion)); });
+    g_lua.registerFunction<std::string(DNSCryptCert::*)()>("getProtocolMinorVersion", [](const DNSCryptCert& cert) { return std::string(reinterpret_cast<const char*>(cert.protocolMinorVersion), sizeof(cert.protocolMinorVersion)); });
+    g_lua.registerFunction<std::string(DNSCryptCert::*)()>("getSignature", [](const DNSCryptCert& cert) { return std::string(reinterpret_cast<const char*>(cert.signature), sizeof(cert.signature)); });
+    g_lua.registerFunction<std::string(DNSCryptCert::*)()>("getResolverPublicKey", [](const DNSCryptCert& cert) { return std::string(reinterpret_cast<const char*>(cert.signedData.resolverPK), sizeof(cert.signedData.resolverPK)); });
+    g_lua.registerFunction<std::string(DNSCryptCert::*)()>("getClientMagic", [](const DNSCryptCert& cert) { return std::string(reinterpret_cast<const char*>(cert.signedData.clientMagic), sizeof(cert.signedData.clientMagic)); });
+    g_lua.registerFunction<uint32_t(DNSCryptCert::*)()>("getSerial", [](const DNSCryptCert& cert) { return cert.getSerial(); });
+    g_lua.registerFunction<uint32_t(DNSCryptCert::*)()>("getTSStart", [](const DNSCryptCert& cert) { return ntohl(cert.getTSStart()); });
+    g_lua.registerFunction<uint32_t(DNSCryptCert::*)()>("getTSEnd", [](const DNSCryptCert& cert) { return ntohl(cert.getTSEnd()); });
+#endif
+}
diff --git a/pdns/dnsdistdist/dnsdist-lua-bindings-kvs.cc b/pdns/dnsdistdist/dnsdist-lua-bindings-kvs.cc
new file mode 100644 (file)
index 0000000..5050879
--- /dev/null
@@ -0,0 +1,115 @@
+/*
+ * This file is part of PowerDNS or dnsdist.
+ * Copyright -- PowerDNS.COM B.V. and its contributors
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of version 2 of the GNU General Public License as
+ * published by the Free Software Foundation.
+ *
+ * In addition, for the avoidance of any doubt, permission is granted to
+ * link this program with OpenSSL and to (re)distribute the binaries
+ * produced as the result of such linking.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+#include "dnsdist.hh"
+#include "dnsdist-kvs.hh"
+#include "dnsdist-lua.hh"
+
+void setupLuaBindingsKVS(bool client)
+{
+  /* Key Value Store objects */
+  g_lua.writeFunction("KeyValueLookupKeySourceIP", []() {
+    return std::shared_ptr<KeyValueLookupKey>(new KeyValueLookupKeySourceIP());
+  });
+  g_lua.writeFunction("KeyValueLookupKeyQName", [](boost::optional<bool> wireFormat) {
+    return std::shared_ptr<KeyValueLookupKey>(new KeyValueLookupKeyQName(wireFormat ? *wireFormat : true));
+  });
+  g_lua.writeFunction("KeyValueLookupKeySuffix", [](boost::optional<size_t> minLabels, boost::optional<bool> wireFormat) {
+    return std::shared_ptr<KeyValueLookupKey>(new KeyValueLookupKeySuffix(minLabels ? *minLabels : 0, wireFormat ? *wireFormat : true));
+  });
+  g_lua.writeFunction("KeyValueLookupKeyTag", [](const std::string& tag) {
+    return std::shared_ptr<KeyValueLookupKey>(new KeyValueLookupKeyTag(tag));
+  });
+
+#ifdef HAVE_LMDB
+  g_lua.writeFunction("newLMDBKVStore", [client](const std::string& fname, const std::string& dbName) {
+    if (client) {
+      return std::shared_ptr<KeyValueStore>(nullptr);
+    }
+    return std::shared_ptr<KeyValueStore>(new LMDBKVStore(fname, dbName));
+  });
+#endif /* HAVE_LMDB */
+
+#ifdef HAVE_CDB
+  g_lua.writeFunction("newCDBKVStore", [client](const std::string& fname, time_t refreshDelay) {
+    if (client) {
+      return std::shared_ptr<KeyValueStore>(nullptr);
+    }
+    return std::shared_ptr<KeyValueStore>(new CDBKVStore(fname, refreshDelay));
+  });
+#endif /* HAVE_CDB */
+
+  g_lua.registerFunction<std::string(std::shared_ptr<KeyValueStore>::*)(const boost::variant<ComboAddress, DNSName, std::string>, boost::optional<bool> wireFormat)>("lookup", [](std::shared_ptr<KeyValueStore>& kvs, const boost::variant<ComboAddress, DNSName, std::string> keyVar, boost::optional<bool> wireFormat) {
+    std::string result;
+    if (!kvs) {
+      return result;
+    }
+
+    if (keyVar.type() == typeid(ComboAddress)) {
+      const auto ca = *boost::get<ComboAddress>(&keyVar);
+      KeyValueLookupKeySourceIP lookup;
+      for (const auto& key : lookup.getKeys(ca)) {
+        if (kvs->getValue(key, result)) {
+          return result;
+        }
+      }
+    }
+    else if (keyVar.type() == typeid(DNSName)) {
+      DNSName dn = *boost::get<DNSName>(&keyVar);
+      KeyValueLookupKeyQName lookup(wireFormat ? *wireFormat : true);
+      for (const auto& key : lookup.getKeys(dn)) {
+        if (kvs->getValue(key, result)) {
+          return result;
+        }
+      }
+    }
+    else if (keyVar.type() == typeid(std::string)) {
+      std::string keyStr = *boost::get<std::string>(&keyVar);
+      kvs->getValue(keyStr, result);
+    }
+
+    return result;
+  });
+
+  g_lua.registerFunction<std::string(std::shared_ptr<KeyValueStore>::*)(const DNSName&, boost::optional<size_t> minLabels, boost::optional<bool> wireFormat)>("lookupSuffix", [](std::shared_ptr<KeyValueStore>& kvs, const DNSName& dn, boost::optional<size_t> minLabels, boost::optional<bool> wireFormat) {
+    std::string result;
+    if (!kvs) {
+      return result;
+    }
+
+    KeyValueLookupKeySuffix lookup(minLabels ? *minLabels : 0, wireFormat ? *wireFormat : true);
+    for (const auto& key : lookup.getKeys(dn)) {
+      if (kvs->getValue(key, result)) {
+        return result;
+      }
+    }
+
+    return result;
+  });
+
+  g_lua.registerFunction<bool(std::shared_ptr<KeyValueStore>::*)()>("reload", [](std::shared_ptr<KeyValueStore>& kvs) {
+    if (!kvs) {
+      return false;
+    }
+
+    return kvs->reload();
+  });
+}
diff --git a/pdns/dnsdistdist/dnsdist-lua-bindings-packetcache.cc b/pdns/dnsdistdist/dnsdist-lua-bindings-packetcache.cc
new file mode 100644 (file)
index 0000000..e54841b
--- /dev/null
@@ -0,0 +1,158 @@
+/*
+ * This file is part of PowerDNS or dnsdist.
+ * Copyright -- PowerDNS.COM B.V. and its contributors
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of version 2 of the GNU General Public License as
+ * published by the Free Software Foundation.
+ *
+ * In addition, for the avoidance of any doubt, permission is granted to
+ * link this program with OpenSSL and to (re)distribute the binaries
+ * produced as the result of such linking.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+#include <fcntl.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+
+#include "config.h"
+#include "dnsdist.hh"
+#include "dnsdist-lua.hh"
+
+void setupLuaBindingsPacketCache()
+{
+  /* PacketCache */
+  g_lua.writeFunction("newPacketCache", [](size_t maxEntries, boost::optional<std::unordered_map<std::string, boost::variant<bool, size_t>>> vars) {
+
+      bool keepStaleData = false;
+      size_t maxTTL = 86400;
+      size_t minTTL = 0;
+      size_t tempFailTTL = 60;
+      size_t maxNegativeTTL = 3600;
+      size_t staleTTL = 60;
+      size_t numberOfShards = 1;
+      bool dontAge = false;
+      bool deferrableInsertLock = true;
+      bool ecsParsing = false;
+
+      if (vars) {
+
+        if (vars->count("deferrableInsertLock")) {
+          deferrableInsertLock = boost::get<bool>((*vars)["deferrableInsertLock"]);
+        }
+
+        if (vars->count("dontAge")) {
+          dontAge = boost::get<bool>((*vars)["dontAge"]);
+        }
+
+        if (vars->count("keepStaleData")) {
+          keepStaleData = boost::get<bool>((*vars)["keepStaleData"]);
+        }
+
+        if (vars->count("maxNegativeTTL")) {
+          maxNegativeTTL = boost::get<size_t>((*vars)["maxNegativeTTL"]);
+        }
+
+        if (vars->count("maxTTL")) {
+          maxTTL = boost::get<size_t>((*vars)["maxTTL"]);
+        }
+
+        if (vars->count("minTTL")) {
+          minTTL = boost::get<size_t>((*vars)["minTTL"]);
+        }
+
+        if (vars->count("numberOfShards")) {
+          numberOfShards = boost::get<size_t>((*vars)["numberOfShards"]);
+        }
+
+        if (vars->count("parseECS")) {
+          ecsParsing = boost::get<bool>((*vars)["parseECS"]);
+        }
+
+        if (vars->count("staleTTL")) {
+          staleTTL = boost::get<size_t>((*vars)["staleTTL"]);
+        }
+
+        if (vars->count("temporaryFailureTTL")) {
+          tempFailTTL = boost::get<size_t>((*vars)["temporaryFailureTTL"]);
+        }
+      }
+
+      auto res = std::make_shared<DNSDistPacketCache>(maxEntries, maxTTL, minTTL, tempFailTTL, maxNegativeTTL, staleTTL, dontAge, numberOfShards, deferrableInsertLock, ecsParsing);
+
+      res->setKeepStaleData(keepStaleData);
+
+      return res;
+    });
+  g_lua.registerFunction("toString", &DNSDistPacketCache::toString);
+  g_lua.registerFunction("isFull", &DNSDistPacketCache::isFull);
+  g_lua.registerFunction("purgeExpired", &DNSDistPacketCache::purgeExpired);
+  g_lua.registerFunction("expunge", &DNSDistPacketCache::expunge);
+  g_lua.registerFunction<void(std::shared_ptr<DNSDistPacketCache>::*)(const DNSName& dname, boost::optional<uint16_t> qtype, boost::optional<bool> suffixMatch)>("expungeByName", [](
+              std::shared_ptr<DNSDistPacketCache> cache,
+              const DNSName& dname,
+              boost::optional<uint16_t> qtype,
+              boost::optional<bool> suffixMatch) {
+                if (cache) {
+                  g_outputBuffer="Expunged " + std::to_string(cache->expungeByName(dname, qtype ? *qtype : QType(QType::ANY).getCode(), suffixMatch ? *suffixMatch : false)) + " records\n";
+                }
+    });
+  g_lua.registerFunction<void(std::shared_ptr<DNSDistPacketCache>::*)()>("printStats", [](const std::shared_ptr<DNSDistPacketCache> cache) {
+      if (cache) {
+        g_outputBuffer="Entries: " + std::to_string(cache->getEntriesCount()) + "/" + std::to_string(cache->getMaxEntries()) + "\n";
+        g_outputBuffer+="Hits: " + std::to_string(cache->getHits()) + "\n";
+        g_outputBuffer+="Misses: " + std::to_string(cache->getMisses()) + "\n";
+        g_outputBuffer+="Deferred inserts: " + std::to_string(cache->getDeferredInserts()) + "\n";
+        g_outputBuffer+="Deferred lookups: " + std::to_string(cache->getDeferredLookups()) + "\n";
+        g_outputBuffer+="Lookup Collisions: " + std::to_string(cache->getLookupCollisions()) + "\n";
+        g_outputBuffer+="Insert Collisions: " + std::to_string(cache->getInsertCollisions()) + "\n";
+        g_outputBuffer+="TTL Too Shorts: " + std::to_string(cache->getTTLTooShorts()) + "\n";
+      }
+    });
+  g_lua.registerFunction<std::unordered_map<std::string, uint64_t>(std::shared_ptr<DNSDistPacketCache>::*)()>("getStats", [](const std::shared_ptr<DNSDistPacketCache> cache) {
+      std::unordered_map<std::string, uint64_t> stats;
+      if (cache) {
+        stats["entries"] = cache->getEntriesCount();
+        stats["maxEntries"] = cache->getMaxEntries();
+        stats["hits"] = cache->getHits();
+        stats["misses"] = cache->getMisses();
+        stats["deferredInserts"] = cache->getDeferredInserts();
+        stats["deferredLookups"] = cache->getDeferredLookups();
+        stats["lookupCollisions"] = cache->getLookupCollisions();
+        stats["insertCollisions"] = cache->getInsertCollisions();
+        stats["ttlTooShorts"] = cache->getTTLTooShorts();
+      }
+      return stats;
+    });
+  g_lua.registerFunction<void(std::shared_ptr<DNSDistPacketCache>::*)(const std::string& fname)>("dump", [](const std::shared_ptr<DNSDistPacketCache> cache, const std::string& fname) {
+      if (cache) {
+
+        int fd = open(fname.c_str(), O_CREAT | O_EXCL | O_WRONLY, 0660);
+        if (fd < 0) {
+          g_outputBuffer = "Error opening dump file for writing: " + string(strerror(errno)) + "\n";
+          return;
+        }
+
+        uint64_t records = 0;
+        try {
+          records = cache->dump(fd);
+        }
+        catch (const std::exception& e) {
+          close(fd);
+          throw;
+        }
+
+        close(fd);
+
+        g_outputBuffer += "Dumped " + std::to_string(records) + " records\n";
+      }
+    });
+}
diff --git a/pdns/dnsdistdist/dnsdist-lua-bindings-protobuf.cc b/pdns/dnsdistdist/dnsdist-lua-bindings-protobuf.cc
new file mode 100644 (file)
index 0000000..ebc165f
--- /dev/null
@@ -0,0 +1,118 @@
+/*
+ * This file is part of PowerDNS or dnsdist.
+ * Copyright -- PowerDNS.COM B.V. and its contributors
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of version 2 of the GNU General Public License as
+ * published by the Free Software Foundation.
+ *
+ * In addition, for the avoidance of any doubt, permission is granted to
+ * link this program with OpenSSL and to (re)distribute the binaries
+ * produced as the result of such linking.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+#include "config.h"
+#include "dnsdist.hh"
+#include "dnsdist-lua.hh"
+
+#include "dnsdist-protobuf.hh"
+#include "dnstap.hh"
+#include "fstrm_logger.hh"
+#include "remote_logger.hh"
+
+#ifdef HAVE_LIBCRYPTO
+#include "ipcipher.hh"
+#endif /* HAVE_LIBCRYPTO */
+
+void setupLuaBindingsProtoBuf(bool client)
+{
+#ifdef HAVE_LIBCRYPTO
+  g_lua.registerFunction<ComboAddress(ComboAddress::*)(const std::string& key)>("ipencrypt", [](const ComboAddress& ca, const std::string& key) {
+      return encryptCA(ca, key);
+    });
+  g_lua.registerFunction<ComboAddress(ComboAddress::*)(const std::string& key)>("ipdecrypt", [](const ComboAddress& ca, const std::string& key) {
+      return decryptCA(ca, key);
+    });
+
+  g_lua.writeFunction("makeIPCipherKey", [](const std::string& password) {
+      return makeIPCipherKey(password);
+    });
+#endif /* HAVE_LIBCRYPTO */
+
+  /* ProtobufMessage */
+  g_lua.registerFunction<void(DNSDistProtoBufMessage::*)(std::string)>("setTag", [](DNSDistProtoBufMessage& message, const std::string& strValue) {
+      message.addTag(strValue);
+    });
+  g_lua.registerFunction<void(DNSDistProtoBufMessage::*)(vector<pair<int, string>>)>("setTagArray", [](DNSDistProtoBufMessage& message, const vector<pair<int, string>>&tags) {
+      for (const auto& tag : tags) {
+        message.addTag(tag.second);
+      }
+    });
+  g_lua.registerFunction<void(DNSDistProtoBufMessage::*)(boost::optional <time_t> sec, boost::optional <uint32_t> uSec)>("setProtobufResponseType",
+                                        [](DNSDistProtoBufMessage& message, boost::optional <time_t> sec, boost::optional <uint32_t> uSec) {
+      message.setType(DNSProtoBufMessage::Response);
+      message.setQueryTime(sec?*sec:0, uSec?*uSec:0);
+    });
+  g_lua.registerFunction<void(DNSDistProtoBufMessage::*)(const std::string& strQueryName, uint16_t uType, uint16_t uClass, uint32_t uTTL, const std::string& strBlob)>("addResponseRR", [](DNSDistProtoBufMessage& message,
+                                                            const std::string& strQueryName, uint16_t uType, uint16_t uClass, uint32_t uTTL, const std::string& strBlob) {
+      message.addRR(DNSName(strQueryName), uType, uClass, uTTL, strBlob);
+    });
+  g_lua.registerFunction<void(DNSDistProtoBufMessage::*)(const Netmask&)>("setEDNSSubnet", [](DNSDistProtoBufMessage& message, const Netmask& subnet) { message.setEDNSSubnet(subnet); });
+  g_lua.registerFunction<void(DNSDistProtoBufMessage::*)(const DNSName&, uint16_t, uint16_t)>("setQuestion", [](DNSDistProtoBufMessage& message, const DNSName& qname, uint16_t qtype, uint16_t qclass) { message.setQuestion(qname, qtype, qclass); });
+  g_lua.registerFunction<void(DNSDistProtoBufMessage::*)(size_t)>("setBytes", [](DNSDistProtoBufMessage& message, size_t bytes) { message.setBytes(bytes); });
+  g_lua.registerFunction<void(DNSDistProtoBufMessage::*)(time_t, uint32_t)>("setTime", [](DNSDistProtoBufMessage& message, time_t sec, uint32_t usec) { message.setTime(sec, usec); });
+  g_lua.registerFunction<void(DNSDistProtoBufMessage::*)(time_t, uint32_t)>("setQueryTime", [](DNSDistProtoBufMessage& message, time_t sec, uint32_t usec) { message.setQueryTime(sec, usec); });
+  g_lua.registerFunction<void(DNSDistProtoBufMessage::*)(uint8_t)>("setResponseCode", [](DNSDistProtoBufMessage& message, uint8_t rcode) { message.setResponseCode(rcode); });
+  g_lua.registerFunction<std::string(DNSDistProtoBufMessage::*)()>("toDebugString", [](const DNSDistProtoBufMessage& message) { return message.toDebugString(); });
+  g_lua.registerFunction<void(DNSDistProtoBufMessage::*)(const ComboAddress&)>("setRequestor", [](DNSDistProtoBufMessage& message, const ComboAddress& addr) {
+      message.setRequestor(addr);
+    });
+  g_lua.registerFunction<void(DNSDistProtoBufMessage::*)(const std::string&)>("setRequestorFromString", [](DNSDistProtoBufMessage& message, const std::string& str) {
+      message.setRequestor(str);
+    });
+  g_lua.registerFunction<void(DNSDistProtoBufMessage::*)(const ComboAddress&)>("setResponder", [](DNSDistProtoBufMessage& message, const ComboAddress& addr) {
+      message.setResponder(addr);
+    });
+  g_lua.registerFunction<void(DNSDistProtoBufMessage::*)(const std::string&)>("setResponderFromString", [](DNSDistProtoBufMessage& message, const std::string& str) {
+      message.setResponder(str);
+    });
+  g_lua.registerFunction<void(DNSDistProtoBufMessage::*)(const std::string&)>("setServerIdentity", [](DNSDistProtoBufMessage& message, const std::string& str) {
+      message.setServerIdentity(str);
+    });
+
+  g_lua.registerFunction<std::string(DnstapMessage::*)()>("toDebugString", [](const DnstapMessage& message) { return message.toDebugString(); });
+  g_lua.registerFunction<void(DnstapMessage::*)(const std::string&)>("setExtra", [](DnstapMessage& message, const std::string& str) {
+      message.setExtra(str);
+    });
+
+  /* RemoteLogger */
+  g_lua.writeFunction("newRemoteLogger", [client](const std::string& remote, boost::optional<uint16_t> timeout, boost::optional<uint64_t> maxQueuedEntries, boost::optional<uint8_t> reconnectWaitTime) {
+      return std::shared_ptr<RemoteLoggerInterface>(new RemoteLogger(ComboAddress(remote), timeout ? *timeout : 2, maxQueuedEntries ? (*maxQueuedEntries*100) : 10000, reconnectWaitTime ? *reconnectWaitTime : 1, client));
+    });
+
+  g_lua.writeFunction("newFrameStreamUnixLogger", [client](const std::string& address) {
+#ifdef HAVE_FSTRM
+      return std::shared_ptr<RemoteLoggerInterface>(new FrameStreamLogger(AF_UNIX, address, !client));
+#else
+      throw std::runtime_error("fstrm support is required to build an AF_UNIX FrameStreamLogger");
+#endif /* HAVE_FSTRM */
+    });
+
+  g_lua.writeFunction("newFrameStreamTcpLogger", [client](const std::string& address) {
+#if defined(HAVE_FSTRM) && defined(HAVE_FSTRM_TCP_WRITER_INIT)
+      return std::shared_ptr<RemoteLoggerInterface>(new FrameStreamLogger(AF_INET, address, !client));
+#else
+      throw std::runtime_error("fstrm with TCP support is required to build an AF_INET FrameStreamLogger");
+#endif /* HAVE_FSTRM */
+    });
+
+  g_lua.registerFunction("toString", &RemoteLoggerInterface::toString);
+}