From: Remi Gacogne Date: Thu, 29 Aug 2019 13:15:04 +0000 (+0200) Subject: dnsdist: Split dnsdist-lua-bindings.cc X-Git-Tag: dnsdist-1.4.0-rc2~8^2 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=4d4d5623d084b30bf1ea1e38098450165a003e10;p=pdns dnsdist: Split dnsdist-lua-bindings.cc Hopefully this will reduce the memory usage needed to compile it. --- diff --git a/pdns/dnsdist-lua-bindings.cc b/pdns/dnsdist-lua-bindings.cc index fc51198b0..9ad4b70d3 100644 --- a/pdns/dnsdist-lua-bindings.cc +++ b/pdns/dnsdist-lua-bindings.cc @@ -19,24 +19,11 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ -#include -#include -#include - #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("mapToIPv4", [](const ComboAddress& ca) { return ca.mapToIPv4(); }); g_lua.registerFunction("match", [](nmts_t& s, const ComboAddress& ca) { return s.match(ca); }); -#ifdef HAVE_LIBCRYPTO - g_lua.registerFunction("ipencrypt", [](const ComboAddress& ca, const std::string& key) { - return encryptCA(ca, key); - }); - g_lua.registerFunction("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("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>> 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((*vars)["deferrableInsertLock"]); - } - - if (vars->count("dontAge")) { - dontAge = boost::get((*vars)["dontAge"]); - } - - if (vars->count("keepStaleData")) { - keepStaleData = boost::get((*vars)["keepStaleData"]); - } - - if (vars->count("maxNegativeTTL")) { - maxNegativeTTL = boost::get((*vars)["maxNegativeTTL"]); - } - - if (vars->count("maxTTL")) { - maxTTL = boost::get((*vars)["maxTTL"]); - } - - if (vars->count("minTTL")) { - minTTL = boost::get((*vars)["minTTL"]); - } - - if (vars->count("numberOfShards")) { - numberOfShards = boost::get((*vars)["numberOfShards"]); - } - - if (vars->count("parseECS")) { - ecsParsing = boost::get((*vars)["parseECS"]); - } - - if (vars->count("staleTTL")) { - staleTTL = boost::get((*vars)["staleTTL"]); - } - - if (vars->count("temporaryFailureTTL")) { - tempFailTTL = boost::get((*vars)["temporaryFailureTTL"]); - } - } - - auto res = std::make_shared(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::*)(const DNSName& dname, boost::optional qtype, boost::optional suffixMatch)>("expungeByName", []( - std::shared_ptr cache, - const DNSName& dname, - boost::optional qtype, - boost::optional 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::*)()>("printStats", [](const std::shared_ptr 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::shared_ptr::*)()>("getStats", [](const std::shared_ptr cache) { - std::unordered_map 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::*)(const std::string& fname)>("dump", [](const std::shared_ptr 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("setTag", [](DNSDistProtoBufMessage& message, const std::string& strValue) { - message.addTag(strValue); - }); - g_lua.registerFunction>)>("setTagArray", [](DNSDistProtoBufMessage& message, const vector>&tags) { - for (const auto& tag : tags) { - message.addTag(tag.second); - } - }); - g_lua.registerFunction sec, boost::optional uSec)>("setProtobufResponseType", - [](DNSDistProtoBufMessage& message, boost::optional sec, boost::optional uSec) { - message.setType(DNSProtoBufMessage::Response); - message.setQueryTime(sec?*sec:0, uSec?*uSec:0); - }); - g_lua.registerFunction("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("setEDNSSubnet", [](DNSDistProtoBufMessage& message, const Netmask& subnet) { message.setEDNSSubnet(subnet); }); - g_lua.registerFunction("setQuestion", [](DNSDistProtoBufMessage& message, const DNSName& qname, uint16_t qtype, uint16_t qclass) { message.setQuestion(qname, qtype, qclass); }); - g_lua.registerFunction("setBytes", [](DNSDistProtoBufMessage& message, size_t bytes) { message.setBytes(bytes); }); - g_lua.registerFunction("setTime", [](DNSDistProtoBufMessage& message, time_t sec, uint32_t usec) { message.setTime(sec, usec); }); - g_lua.registerFunction("setQueryTime", [](DNSDistProtoBufMessage& message, time_t sec, uint32_t usec) { message.setQueryTime(sec, usec); }); - g_lua.registerFunction("setResponseCode", [](DNSDistProtoBufMessage& message, uint8_t rcode) { message.setResponseCode(rcode); }); - g_lua.registerFunction("toDebugString", [](const DNSDistProtoBufMessage& message) { return message.toDebugString(); }); - g_lua.registerFunction("setRequestor", [](DNSDistProtoBufMessage& message, const ComboAddress& addr) { - message.setRequestor(addr); - }); - g_lua.registerFunction("setRequestorFromString", [](DNSDistProtoBufMessage& message, const std::string& str) { - message.setRequestor(str); - }); - g_lua.registerFunction("setResponder", [](DNSDistProtoBufMessage& message, const ComboAddress& addr) { - message.setResponder(addr); - }); - g_lua.registerFunction("setResponderFromString", [](DNSDistProtoBufMessage& message, const std::string& str) { - message.setResponder(str); - }); - g_lua.registerFunction("setServerIdentity", [](DNSDistProtoBufMessage& message, const std::string& str) { - message.setServerIdentity(str); - }); - - g_lua.registerFunction("toDebugString", [](const DnstapMessage& message) { return message.toDebugString(); }); - g_lua.registerFunction("setExtra", [](DnstapMessage& message, const std::string& str) { - message.setExtra(str); - }); - - /* RemoteLogger */ - g_lua.writeFunction("newRemoteLogger", [client](const std::string& remote, boost::optional timeout, boost::optional maxQueuedEntries, boost::optional reconnectWaitTime) { - return std::shared_ptr(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(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(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("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::*)(const std::string& certFile, const std::string& keyFile, boost::optional active)>("loadNewCertificate", [](std::shared_ptr ctx, const std::string& certFile, const std::string& keyFile, boost::optional 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::*)(const DNSCryptCert& newCert, const DNSCryptPrivateKey& newKey, boost::optional active)>("addNewCertificate", [](std::shared_ptr ctx, const DNSCryptCert& newCert, const DNSCryptPrivateKey& newKey, boost::optional 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::shared_ptr::*)()>("getCertificatePairs", [](std::shared_ptr ctx) { - std::map> result; - - if (ctx != nullptr) { - size_t idx = 1; - for (auto pair : ctx->getCertificates()) { - result[idx++] = pair; - } - } - - return result; - }); - - g_lua.registerFunction(std::shared_ptr::*)(size_t idx)>("getCertificatePair", [](std::shared_ptr ctx, size_t idx) { - - if (ctx == nullptr) { - throw std::runtime_error("DNSCryptContext::getCertificatePair() called on a nil value"); - } - - std::shared_ptr result = nullptr; - auto pairs = ctx->getCertificates(); - if (idx < pairs.size()) { - result = pairs.at(idx); - } - - return result; - }); - - g_lua.registerFunction::*)(size_t idx)>("getCertificate", [](std::shared_ptr 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::*)()>("printCertificates", [](const std::shared_ptr 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 version)>("generateAndLoadInMemoryCertificate", [](DNSCryptContext& ctx, const std::string& providerPrivateKeyFile, uint32_t serial, time_t begin, time_t end, boost::optional 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::*)()>("getCertificate", [](const std::shared_ptr pair) { - if (pair == nullptr) { - throw std::runtime_error("DNSCryptCertificatePair::getCertificate() called on a nil value"); - } - return pair->cert; - }); - g_lua.registerFunction::*)()>("isActive", [](const std::shared_ptr pair) { - if (pair == nullptr) { - throw std::runtime_error("DNSCryptCertificatePair::isActive() called on a nil value"); - } - return pair->active; - }); - - /* DNSCryptCert */ - g_lua.registerFunction("getMagic", [](const DNSCryptCert& cert) { return std::string(reinterpret_cast(cert.magic), sizeof(cert.magic)); }); - g_lua.registerFunction("getEsVersion", [](const DNSCryptCert& cert) { return std::string(reinterpret_cast(cert.esVersion), sizeof(cert.esVersion)); }); - g_lua.registerFunction("getProtocolMinorVersion", [](const DNSCryptCert& cert) { return std::string(reinterpret_cast(cert.protocolMinorVersion), sizeof(cert.protocolMinorVersion)); }); - g_lua.registerFunction("getSignature", [](const DNSCryptCert& cert) { return std::string(reinterpret_cast(cert.signature), sizeof(cert.signature)); }); - g_lua.registerFunction("getResolverPublicKey", [](const DNSCryptCert& cert) { return std::string(reinterpret_cast(cert.signedData.resolverPK), sizeof(cert.signedData.resolverPK)); }); - g_lua.registerFunction("getClientMagic", [](const DNSCryptCert& cert) { return std::string(reinterpret_cast(cert.signedData.clientMagic), sizeof(cert.signedData.clientMagic)); }); - g_lua.registerFunction("getSerial", [](const DNSCryptCert& cert) { return cert.getSerial(); }); - g_lua.registerFunction("getTSStart", [](const DNSCryptCert& cert) { return ntohl(cert.getTSStart()); }); - g_lua.registerFunction("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(new KeyValueLookupKeySourceIP()); - }); - g_lua.writeFunction("KeyValueLookupKeyQName", [](boost::optional wireFormat) { - return std::shared_ptr(new KeyValueLookupKeyQName(wireFormat ? *wireFormat : true)); - }); - g_lua.writeFunction("KeyValueLookupKeySuffix", [](boost::optional minLabels, boost::optional wireFormat) { - return std::shared_ptr(new KeyValueLookupKeySuffix(minLabels ? *minLabels : 0, wireFormat ? *wireFormat : true)); - }); - g_lua.writeFunction("KeyValueLookupKeyTag", [](const std::string& tag) { - return std::shared_ptr(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(nullptr); - } - return std::shared_ptr(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(nullptr); - } - return std::shared_ptr(new CDBKVStore(fname, refreshDelay)); - }); -#endif /* HAVE_CDB */ - - g_lua.registerFunction::*)(const boost::variant, boost::optional wireFormat)>("lookup", [](std::shared_ptr& kvs, const boost::variant keyVar, boost::optional wireFormat) { - std::string result; - if (!kvs) { - return result; - } - - if (keyVar.type() == typeid(ComboAddress)) { - const auto ca = *boost::get(&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(&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(&keyVar); - kvs->getValue(keyStr, result); - } - - return result; - }); - - g_lua.registerFunction::*)(const DNSName&, boost::optional minLabels, boost::optional wireFormat)>("lookupSuffix", [](std::shared_ptr& kvs, const DNSName& dn, boost::optional minLabels, boost::optional 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::*)()>("reload", [](std::shared_ptr& kvs) { - if (!kvs) { - return false; - } - - return kvs->reload(); - }); - } diff --git a/pdns/dnsdist-lua.cc b/pdns/dnsdist-lua.cc index f448e6c6f..a1aba5321 100644 --- a/pdns/dnsdist-lua.cc +++ b/pdns/dnsdist-lua.cc @@ -2067,7 +2067,11 @@ vector> setupLua(bool client, const std::string& confi setupLuaActions(); setupLuaConfig(client); setupLuaBindings(client); + setupLuaBindingsDNSCrypt(); setupLuaBindingsDNSQuestion(); + setupLuaBindingsKVS(client); + setupLuaBindingsPacketCache(); + setupLuaBindingsProtoBuf(client); setupLuaInspection(); setupLuaRules(); setupLuaVars(); diff --git a/pdns/dnsdist-lua.hh b/pdns/dnsdist-lua.hh index 7ab5d963c..9bd33266d 100644 --- a/pdns/dnsdist-lua.hh +++ b/pdns/dnsdist-lua.hh @@ -86,7 +86,11 @@ typedef NetmaskTree 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(); diff --git a/pdns/dnsdistdist/Makefile.am b/pdns/dnsdistdist/Makefile.am index 92b156034..101a57932 100644 --- a/pdns/dnsdistdist/Makefile.am +++ b/pdns/dnsdistdist/Makefile.am @@ -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 index 000000000..6a25dcf85 --- /dev/null +++ b/pdns/dnsdistdist/dnsdist-lua-bindings-dnscrypt.cc @@ -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("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::*)(const std::string& certFile, const std::string& keyFile, boost::optional active)>("loadNewCertificate", [](std::shared_ptr ctx, const std::string& certFile, const std::string& keyFile, boost::optional 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::*)(const DNSCryptCert& newCert, const DNSCryptPrivateKey& newKey, boost::optional active)>("addNewCertificate", [](std::shared_ptr ctx, const DNSCryptCert& newCert, const DNSCryptPrivateKey& newKey, boost::optional 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::shared_ptr::*)()>("getCertificatePairs", [](std::shared_ptr ctx) { + std::map> result; + + if (ctx != nullptr) { + size_t idx = 1; + for (auto pair : ctx->getCertificates()) { + result[idx++] = pair; + } + } + + return result; + }); + + g_lua.registerFunction(std::shared_ptr::*)(size_t idx)>("getCertificatePair", [](std::shared_ptr ctx, size_t idx) { + + if (ctx == nullptr) { + throw std::runtime_error("DNSCryptContext::getCertificatePair() called on a nil value"); + } + + std::shared_ptr result = nullptr; + auto pairs = ctx->getCertificates(); + if (idx < pairs.size()) { + result = pairs.at(idx); + } + + return result; + }); + + g_lua.registerFunction::*)(size_t idx)>("getCertificate", [](std::shared_ptr 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::*)()>("printCertificates", [](const std::shared_ptr 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 version)>("generateAndLoadInMemoryCertificate", [](DNSCryptContext& ctx, const std::string& providerPrivateKeyFile, uint32_t serial, time_t begin, time_t end, boost::optional 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::*)()>("getCertificate", [](const std::shared_ptr pair) { + if (pair == nullptr) { + throw std::runtime_error("DNSCryptCertificatePair::getCertificate() called on a nil value"); + } + return pair->cert; + }); + g_lua.registerFunction::*)()>("isActive", [](const std::shared_ptr pair) { + if (pair == nullptr) { + throw std::runtime_error("DNSCryptCertificatePair::isActive() called on a nil value"); + } + return pair->active; + }); + + /* DNSCryptCert */ + g_lua.registerFunction("getMagic", [](const DNSCryptCert& cert) { return std::string(reinterpret_cast(cert.magic), sizeof(cert.magic)); }); + g_lua.registerFunction("getEsVersion", [](const DNSCryptCert& cert) { return std::string(reinterpret_cast(cert.esVersion), sizeof(cert.esVersion)); }); + g_lua.registerFunction("getProtocolMinorVersion", [](const DNSCryptCert& cert) { return std::string(reinterpret_cast(cert.protocolMinorVersion), sizeof(cert.protocolMinorVersion)); }); + g_lua.registerFunction("getSignature", [](const DNSCryptCert& cert) { return std::string(reinterpret_cast(cert.signature), sizeof(cert.signature)); }); + g_lua.registerFunction("getResolverPublicKey", [](const DNSCryptCert& cert) { return std::string(reinterpret_cast(cert.signedData.resolverPK), sizeof(cert.signedData.resolverPK)); }); + g_lua.registerFunction("getClientMagic", [](const DNSCryptCert& cert) { return std::string(reinterpret_cast(cert.signedData.clientMagic), sizeof(cert.signedData.clientMagic)); }); + g_lua.registerFunction("getSerial", [](const DNSCryptCert& cert) { return cert.getSerial(); }); + g_lua.registerFunction("getTSStart", [](const DNSCryptCert& cert) { return ntohl(cert.getTSStart()); }); + g_lua.registerFunction("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 index 000000000..5050879af --- /dev/null +++ b/pdns/dnsdistdist/dnsdist-lua-bindings-kvs.cc @@ -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(new KeyValueLookupKeySourceIP()); + }); + g_lua.writeFunction("KeyValueLookupKeyQName", [](boost::optional wireFormat) { + return std::shared_ptr(new KeyValueLookupKeyQName(wireFormat ? *wireFormat : true)); + }); + g_lua.writeFunction("KeyValueLookupKeySuffix", [](boost::optional minLabels, boost::optional wireFormat) { + return std::shared_ptr(new KeyValueLookupKeySuffix(minLabels ? *minLabels : 0, wireFormat ? *wireFormat : true)); + }); + g_lua.writeFunction("KeyValueLookupKeyTag", [](const std::string& tag) { + return std::shared_ptr(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(nullptr); + } + return std::shared_ptr(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(nullptr); + } + return std::shared_ptr(new CDBKVStore(fname, refreshDelay)); + }); +#endif /* HAVE_CDB */ + + g_lua.registerFunction::*)(const boost::variant, boost::optional wireFormat)>("lookup", [](std::shared_ptr& kvs, const boost::variant keyVar, boost::optional wireFormat) { + std::string result; + if (!kvs) { + return result; + } + + if (keyVar.type() == typeid(ComboAddress)) { + const auto ca = *boost::get(&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(&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(&keyVar); + kvs->getValue(keyStr, result); + } + + return result; + }); + + g_lua.registerFunction::*)(const DNSName&, boost::optional minLabels, boost::optional wireFormat)>("lookupSuffix", [](std::shared_ptr& kvs, const DNSName& dn, boost::optional minLabels, boost::optional 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::*)()>("reload", [](std::shared_ptr& 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 index 000000000..e54841b69 --- /dev/null +++ b/pdns/dnsdistdist/dnsdist-lua-bindings-packetcache.cc @@ -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 +#include +#include + +#include "config.h" +#include "dnsdist.hh" +#include "dnsdist-lua.hh" + +void setupLuaBindingsPacketCache() +{ + /* PacketCache */ + g_lua.writeFunction("newPacketCache", [](size_t maxEntries, boost::optional>> 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((*vars)["deferrableInsertLock"]); + } + + if (vars->count("dontAge")) { + dontAge = boost::get((*vars)["dontAge"]); + } + + if (vars->count("keepStaleData")) { + keepStaleData = boost::get((*vars)["keepStaleData"]); + } + + if (vars->count("maxNegativeTTL")) { + maxNegativeTTL = boost::get((*vars)["maxNegativeTTL"]); + } + + if (vars->count("maxTTL")) { + maxTTL = boost::get((*vars)["maxTTL"]); + } + + if (vars->count("minTTL")) { + minTTL = boost::get((*vars)["minTTL"]); + } + + if (vars->count("numberOfShards")) { + numberOfShards = boost::get((*vars)["numberOfShards"]); + } + + if (vars->count("parseECS")) { + ecsParsing = boost::get((*vars)["parseECS"]); + } + + if (vars->count("staleTTL")) { + staleTTL = boost::get((*vars)["staleTTL"]); + } + + if (vars->count("temporaryFailureTTL")) { + tempFailTTL = boost::get((*vars)["temporaryFailureTTL"]); + } + } + + auto res = std::make_shared(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::*)(const DNSName& dname, boost::optional qtype, boost::optional suffixMatch)>("expungeByName", []( + std::shared_ptr cache, + const DNSName& dname, + boost::optional qtype, + boost::optional 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::*)()>("printStats", [](const std::shared_ptr 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::shared_ptr::*)()>("getStats", [](const std::shared_ptr cache) { + std::unordered_map 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::*)(const std::string& fname)>("dump", [](const std::shared_ptr 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 index 000000000..ebc165fef --- /dev/null +++ b/pdns/dnsdistdist/dnsdist-lua-bindings-protobuf.cc @@ -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("ipencrypt", [](const ComboAddress& ca, const std::string& key) { + return encryptCA(ca, key); + }); + g_lua.registerFunction("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("setTag", [](DNSDistProtoBufMessage& message, const std::string& strValue) { + message.addTag(strValue); + }); + g_lua.registerFunction>)>("setTagArray", [](DNSDistProtoBufMessage& message, const vector>&tags) { + for (const auto& tag : tags) { + message.addTag(tag.second); + } + }); + g_lua.registerFunction sec, boost::optional uSec)>("setProtobufResponseType", + [](DNSDistProtoBufMessage& message, boost::optional sec, boost::optional uSec) { + message.setType(DNSProtoBufMessage::Response); + message.setQueryTime(sec?*sec:0, uSec?*uSec:0); + }); + g_lua.registerFunction("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("setEDNSSubnet", [](DNSDistProtoBufMessage& message, const Netmask& subnet) { message.setEDNSSubnet(subnet); }); + g_lua.registerFunction("setQuestion", [](DNSDistProtoBufMessage& message, const DNSName& qname, uint16_t qtype, uint16_t qclass) { message.setQuestion(qname, qtype, qclass); }); + g_lua.registerFunction("setBytes", [](DNSDistProtoBufMessage& message, size_t bytes) { message.setBytes(bytes); }); + g_lua.registerFunction("setTime", [](DNSDistProtoBufMessage& message, time_t sec, uint32_t usec) { message.setTime(sec, usec); }); + g_lua.registerFunction("setQueryTime", [](DNSDistProtoBufMessage& message, time_t sec, uint32_t usec) { message.setQueryTime(sec, usec); }); + g_lua.registerFunction("setResponseCode", [](DNSDistProtoBufMessage& message, uint8_t rcode) { message.setResponseCode(rcode); }); + g_lua.registerFunction("toDebugString", [](const DNSDistProtoBufMessage& message) { return message.toDebugString(); }); + g_lua.registerFunction("setRequestor", [](DNSDistProtoBufMessage& message, const ComboAddress& addr) { + message.setRequestor(addr); + }); + g_lua.registerFunction("setRequestorFromString", [](DNSDistProtoBufMessage& message, const std::string& str) { + message.setRequestor(str); + }); + g_lua.registerFunction("setResponder", [](DNSDistProtoBufMessage& message, const ComboAddress& addr) { + message.setResponder(addr); + }); + g_lua.registerFunction("setResponderFromString", [](DNSDistProtoBufMessage& message, const std::string& str) { + message.setResponder(str); + }); + g_lua.registerFunction("setServerIdentity", [](DNSDistProtoBufMessage& message, const std::string& str) { + message.setServerIdentity(str); + }); + + g_lua.registerFunction("toDebugString", [](const DnstapMessage& message) { return message.toDebugString(); }); + g_lua.registerFunction("setExtra", [](DnstapMessage& message, const std::string& str) { + message.setExtra(str); + }); + + /* RemoteLogger */ + g_lua.writeFunction("newRemoteLogger", [client](const std::string& remote, boost::optional timeout, boost::optional maxQueuedEntries, boost::optional reconnectWaitTime) { + return std::shared_ptr(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(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(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); +}