From 4fc2f55f761d71aae1f145d5aa94ba929cc39676 Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Sun, 28 Apr 2024 11:34:30 +0200 Subject: Adding upstream version 1.7.3. Signed-off-by: Daniel Baumann --- dnsdist-lua-bindings-dnsquestion.cc | 305 ++++++++++++++++++++++++++++++++++++ 1 file changed, 305 insertions(+) create mode 100644 dnsdist-lua-bindings-dnsquestion.cc (limited to 'dnsdist-lua-bindings-dnsquestion.cc') diff --git a/dnsdist-lua-bindings-dnsquestion.cc b/dnsdist-lua-bindings-dnsquestion.cc new file mode 100644 index 0000000..492f188 --- /dev/null +++ b/dnsdist-lua-bindings-dnsquestion.cc @@ -0,0 +1,305 @@ +/* + * 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-ecs.hh" +#include "dnsdist-lua.hh" +#include "dnsparser.hh" + +void setupLuaBindingsDNSQuestion(LuaContext& luaCtx) +{ + /* DNSQuestion */ + /* PowerDNS DNSQuestion compat */ + luaCtx.registerMember("localaddr", [](const DNSQuestion& dq) -> const ComboAddress { return *dq.local; }, [](DNSQuestion& dq, const ComboAddress newLocal) { (void) newLocal; }); + luaCtx.registerMember("qname", [](const DNSQuestion& dq) -> const DNSName { return *dq.qname; }, [](DNSQuestion& dq, const DNSName newName) { (void) newName; }); + luaCtx.registerMember("qtype", [](const DNSQuestion& dq) -> uint16_t { return dq.qtype; }, [](DNSQuestion& dq, uint16_t newType) { (void) newType; }); + luaCtx.registerMember("qclass", [](const DNSQuestion& dq) -> uint16_t { return dq.qclass; }, [](DNSQuestion& dq, uint16_t newClass) { (void) newClass; }); + luaCtx.registerMember("rcode", [](const DNSQuestion& dq) -> int { return dq.getHeader()->rcode; }, [](DNSQuestion& dq, int newRCode) { dq.getHeader()->rcode = newRCode; }); + luaCtx.registerMember("remoteaddr", [](const DNSQuestion& dq) -> const ComboAddress { return *dq.remote; }, [](DNSQuestion& dq, const ComboAddress newRemote) { (void) newRemote; }); + /* DNSDist DNSQuestion */ + luaCtx.registerMember("dh", [](const DNSQuestion& dq) -> dnsheader* { return const_cast(dq).getHeader(); }, [](DNSQuestion& dq, const dnsheader* dh) { *(dq.getHeader()) = *dh; }); + luaCtx.registerMember("len", [](const DNSQuestion& dq) -> uint16_t { return dq.getData().size(); }, [](DNSQuestion& dq, uint16_t newlen) { dq.getMutableData().resize(newlen); }); + luaCtx.registerMember("opcode", [](const DNSQuestion& dq) -> uint8_t { return dq.getHeader()->opcode; }, [](DNSQuestion& dq, uint8_t newOpcode) { (void) newOpcode; }); + luaCtx.registerMember("tcp", [](const DNSQuestion& dq) -> bool { return dq.overTCP(); }, [](DNSQuestion& dq, bool newTcp) { (void) newTcp; }); + luaCtx.registerMember("skipCache", [](const DNSQuestion& dq) -> bool { return dq.skipCache; }, [](DNSQuestion& dq, bool newSkipCache) { dq.skipCache = newSkipCache; }); + luaCtx.registerMember("useECS", [](const DNSQuestion& dq) -> bool { return dq.useECS; }, [](DNSQuestion& dq, bool useECS) { dq.useECS = useECS; }); + luaCtx.registerMember("ecsOverride", [](const DNSQuestion& dq) -> bool { return dq.ecsOverride; }, [](DNSQuestion& dq, bool ecsOverride) { dq.ecsOverride = ecsOverride; }); + luaCtx.registerMember("ecsPrefixLength", [](const DNSQuestion& dq) -> uint16_t { return dq.ecsPrefixLength; }, [](DNSQuestion& dq, uint16_t newPrefixLength) { dq.ecsPrefixLength = newPrefixLength; }); + luaCtx.registerMember (DNSQuestion::*)>("tempFailureTTL", + [](const DNSQuestion& dq) -> boost::optional { + return dq.tempFailureTTL; + }, + [](DNSQuestion& dq, boost::optional newValue) { + dq.tempFailureTTL = newValue; + } + ); + luaCtx.registerFunction("getDO", [](const DNSQuestion& dq) { + return getEDNSZ(dq) & EDNS_HEADER_FLAG_DO; + }); + luaCtx.registerFunction("getContent", [](const DNSQuestion& dq) { + return std::string(reinterpret_cast(dq.getData().data()), dq.getData().size()); + }); + luaCtx.registerFunction(DNSQuestion::*)()const>("getEDNSOptions", [](const DNSQuestion& dq) { + if (dq.ednsOptions == nullptr) { + parseEDNSOptions(dq); + } + + return *dq.ednsOptions; + }); + luaCtx.registerFunction("getTrailingData", [](const DNSQuestion& dq) { + return dq.getTrailingData(); + }); + luaCtx.registerFunction("setTrailingData", [](DNSQuestion& dq, const std::string& tail) { + return dq.setTrailingData(tail); + }); + + luaCtx.registerFunction("getServerNameIndication", [](const DNSQuestion& dq) { + return dq.sni; + }); + + luaCtx.registerFunction("getProtocol", [](const DNSQuestion& dq) { + return dq.getProtocol().toPrettyString(); + }); + + luaCtx.registerFunction("sendTrap", [](const DNSQuestion& dq, boost::optional reason) { +#ifdef HAVE_NET_SNMP + if (g_snmpAgent && g_snmpTrapsEnabled) { + g_snmpAgent->sendDNSTrap(dq, reason ? *reason : ""); + } +#endif /* HAVE_NET_SNMP */ + }); + + luaCtx.registerFunction("setTag", [](DNSQuestion& dq, const std::string& strLabel, const std::string& strValue) { + dq.setTag(strLabel, strValue); + }); + luaCtx.registerFunction>)>("setTagArray", [](DNSQuestion& dq, const vector>&tags) { + for (const auto& tag : tags) { + dq.setTag(tag.first, tag.second); + } + }); + luaCtx.registerFunction("getTag", [](const DNSQuestion& dq, const std::string& strLabel) { + if (!dq.qTag) { + return string(); + } + + std::string strValue; + const auto it = dq.qTag->find(strLabel); + if (it == dq.qTag->cend()) { + return string(); + } + return it->second; + }); + luaCtx.registerFunction("getTagArray", [](const DNSQuestion& dq) { + if (!dq.qTag) { + QTag empty; + return empty; + } + + return *dq.qTag; + }); + + luaCtx.registerFunction>)>("setProxyProtocolValues", [](DNSQuestion& dq, const std::vector>& values) { + if (!dq.proxyProtocolValues) { + dq.proxyProtocolValues = make_unique>(); + } + + dq.proxyProtocolValues->clear(); + dq.proxyProtocolValues->reserve(values.size()); + for (const auto& value : values) { + dq.proxyProtocolValues->push_back({value.second, value.first}); + } + }); + + luaCtx.registerFunction("addProxyProtocolValue", [](DNSQuestion& dq, uint8_t type, std::string value) { + if (!dq.proxyProtocolValues) { + dq.proxyProtocolValues = make_unique>(); + } + + dq.proxyProtocolValues->push_back({value, type}); + }); + + luaCtx.registerFunction>(DNSQuestion::*)()>("getProxyProtocolValues", [](const DNSQuestion& dq) { + if (!dq.proxyProtocolValues) { + return std::vector>(); + } + + std::vector> result; + result.resize(dq.proxyProtocolValues->size()); + for (const auto& value : *dq.proxyProtocolValues) { + result.push_back({ value.type, value.content }); + } + + return result; + }); + + luaCtx.registerFunction>, std::vector>>& response)>("spoof", [](DNSQuestion& dq, const boost::variant>, std::vector>>& response) { + if (response.type() == typeid(vector>)) { + std::vector data; + auto responses = boost::get>>(response); + data.reserve(responses.size()); + for (const auto& resp : responses) { + data.push_back(resp.second); + } + std::string result; + SpoofAction sa(data); + sa(&dq, &result); + return; + } + if (response.type() == typeid(vector>)) { + std::vector data; + auto responses = boost::get>>(response); + data.reserve(responses.size()); + for (const auto& resp : responses) { + data.push_back(resp.second); + } + std::string result; + SpoofAction sa(data); + sa(&dq, &result); + return; + } + }); + + /* LuaWrapper doesn't support inheritance */ + luaCtx.registerMember("localaddr", [](const DNSResponse& dq) -> const ComboAddress { return *dq.local; }, [](DNSResponse& dq, const ComboAddress newLocal) { (void) newLocal; }); + luaCtx.registerMember("qname", [](const DNSResponse& dq) -> const DNSName { return *dq.qname; }, [](DNSResponse& dq, const DNSName newName) { (void) newName; }); + luaCtx.registerMember("qtype", [](const DNSResponse& dq) -> uint16_t { return dq.qtype; }, [](DNSResponse& dq, uint16_t newType) { (void) newType; }); + luaCtx.registerMember("qclass", [](const DNSResponse& dq) -> uint16_t { return dq.qclass; }, [](DNSResponse& dq, uint16_t newClass) { (void) newClass; }); + luaCtx.registerMember("rcode", [](const DNSResponse& dq) -> int { return dq.getHeader()->rcode; }, [](DNSResponse& dq, int newRCode) { dq.getHeader()->rcode = newRCode; }); + luaCtx.registerMember("remoteaddr", [](const DNSResponse& dq) -> const ComboAddress { return *dq.remote; }, [](DNSResponse& dq, const ComboAddress newRemote) { (void) newRemote; }); + luaCtx.registerMember("dh", [](const DNSResponse& dr) -> dnsheader* { return const_cast(dr).getHeader(); }, [](DNSResponse& dr, const dnsheader* dh) { *(dr.getHeader()) = *dh; }); + luaCtx.registerMember("len", [](const DNSResponse& dq) -> uint16_t { return dq.getData().size(); }, [](DNSResponse& dq, uint16_t newlen) { dq.getMutableData().resize(newlen); }); + luaCtx.registerMember("opcode", [](const DNSResponse& dq) -> uint8_t { return dq.getHeader()->opcode; }, [](DNSResponse& dq, uint8_t newOpcode) { (void) newOpcode; }); + luaCtx.registerMember("tcp", [](const DNSResponse& dq) -> bool { return dq.overTCP(); }, [](DNSResponse& dq, bool newTcp) { (void) newTcp; }); + luaCtx.registerMember("skipCache", [](const DNSResponse& dq) -> bool { return dq.skipCache; }, [](DNSResponse& dq, bool newSkipCache) { dq.skipCache = newSkipCache; }); + luaCtx.registerFunction editFunc)>("editTTLs", [](DNSResponse& dr, std::function editFunc) { + editDNSPacketTTL(reinterpret_cast(dr.getMutableData().data()), dr.getData().size(), editFunc); + }); + luaCtx.registerFunction("getDO", [](const DNSResponse& dq) { + return getEDNSZ(dq) & EDNS_HEADER_FLAG_DO; + }); + luaCtx.registerFunction("getContent", [](const DNSResponse& dq) { + return std::string(reinterpret_cast(dq.getData().data()), dq.getData().size()); + }); + luaCtx.registerFunction(DNSResponse::*)()const>("getEDNSOptions", [](const DNSResponse& dq) { + if (dq.ednsOptions == nullptr) { + parseEDNSOptions(dq); + } + + return *dq.ednsOptions; + }); + luaCtx.registerFunction("getTrailingData", [](const DNSResponse& dq) { + return dq.getTrailingData(); + }); + luaCtx.registerFunction("setTrailingData", [](DNSResponse& dq, const std::string& tail) { + return dq.setTrailingData(tail); + }); + + luaCtx.registerFunction("setTag", [](DNSResponse& dr, const std::string& strLabel, const std::string& strValue) { + dr.setTag(strLabel, strValue); + }); + + luaCtx.registerFunction>)>("setTagArray", [](DNSResponse& dr, const vector>&tags) { + for (const auto& tag : tags) { + dr.setTag(tag.first, tag.second); + } + }); + luaCtx.registerFunction("getTag", [](const DNSResponse& dr, const std::string& strLabel) { + if (!dr.qTag) { + return string(); + } + + std::string strValue; + const auto it = dr.qTag->find(strLabel); + if (it == dr.qTag->cend()) { + return string(); + } + return it->second; + }); + luaCtx.registerFunction("getTagArray", [](const DNSResponse& dr) { + if (!dr.qTag) { + QTag empty; + return empty; + } + + return *dr.qTag; + }); + + luaCtx.registerFunction("getProtocol", [](const DNSResponse& dr) { + return dr.getProtocol().toPrettyString(); + }); + + luaCtx.registerFunction("sendTrap", [](const DNSResponse& dr, boost::optional reason) { +#ifdef HAVE_NET_SNMP + if (g_snmpAgent && g_snmpTrapsEnabled) { + g_snmpAgent->sendDNSTrap(dr, reason ? *reason : ""); + } +#endif /* HAVE_NET_SNMP */ + }); + +#ifdef HAVE_DNS_OVER_HTTPS + luaCtx.registerFunction("getHTTPPath", [](const DNSQuestion& dq) { + if (dq.du == nullptr) { + return std::string(); + } + return dq.du->getHTTPPath(); + }); + + luaCtx.registerFunction("getHTTPQueryString", [](const DNSQuestion& dq) { + if (dq.du == nullptr) { + return std::string(); + } + return dq.du->getHTTPQueryString(); + }); + + luaCtx.registerFunction("getHTTPHost", [](const DNSQuestion& dq) { + if (dq.du == nullptr) { + return std::string(); + } + return dq.du->getHTTPHost(); + }); + + luaCtx.registerFunction("getHTTPScheme", [](const DNSQuestion& dq) { + if (dq.du == nullptr) { + return std::string(); + } + return dq.du->getHTTPScheme(); + }); + + luaCtx.registerFunction(DNSQuestion::*)(void)const>("getHTTPHeaders", [](const DNSQuestion& dq) { + if (dq.du == nullptr) { + return std::unordered_map(); + } + return dq.du->getHTTPHeaders(); + }); + + luaCtx.registerFunction contentType)>("setHTTPResponse", [](DNSQuestion& dq, uint16_t statusCode, const std::string& body, const boost::optional contentType) { + if (dq.du == nullptr) { + return; + } + PacketBuffer vect(body.begin(), body.end()); + dq.du->setHTTPResponse(statusCode, std::move(vect), contentType ? *contentType : ""); + }); +#endif /* HAVE_DNS_OVER_HTTPS */ + + luaCtx.registerFunction("setNegativeAndAdditionalSOA", [](DNSQuestion& dq, bool nxd, const std::string& zone, uint32_t ttl, const std::string& mname, const std::string& rname, uint32_t serial, uint32_t refresh, uint32_t retry, uint32_t expire, uint32_t minimum) { + return setNegativeAndAdditionalSOA(dq, nxd, DNSName(zone), ttl, DNSName(mname), DNSName(rname), serial, refresh, retry, expire, minimum); + }); +} -- cgit v1.2.3