summaryrefslogtreecommitdiffstats
path: root/dnsdist-lua-bindings-dnsquestion.cc
diff options
context:
space:
mode:
Diffstat (limited to 'dnsdist-lua-bindings-dnsquestion.cc')
-rw-r--r--dnsdist-lua-bindings-dnsquestion.cc78
1 files changed, 64 insertions, 14 deletions
diff --git a/dnsdist-lua-bindings-dnsquestion.cc b/dnsdist-lua-bindings-dnsquestion.cc
index 9d5da2c..4512fc5 100644
--- a/dnsdist-lua-bindings-dnsquestion.cc
+++ b/dnsdist-lua-bindings-dnsquestion.cc
@@ -27,6 +27,7 @@
#include "dnsdist-lua.hh"
#include "dnsparser.hh"
+// NOLINTNEXTLINE(readability-function-cognitive-complexity): this function declares Lua bindings, even with a good refactoring it will likely blow up the threshold
void setupLuaBindingsDNSQuestion(LuaContext& luaCtx)
{
#ifndef DISABLE_NON_FFI_DQ_BINDINGS
@@ -36,10 +37,20 @@ void setupLuaBindingsDNSQuestion(LuaContext& luaCtx)
luaCtx.registerMember<const DNSName (DNSQuestion::*)>("qname", [](const DNSQuestion& dq) -> const DNSName { return dq.ids.qname; }, [](DNSQuestion& dq, const DNSName& newName) { (void) newName; });
luaCtx.registerMember<uint16_t (DNSQuestion::*)>("qtype", [](const DNSQuestion& dq) -> uint16_t { return dq.ids.qtype; }, [](DNSQuestion& dq, uint16_t newType) { (void) newType; });
luaCtx.registerMember<uint16_t (DNSQuestion::*)>("qclass", [](const DNSQuestion& dq) -> uint16_t { return dq.ids.qclass; }, [](DNSQuestion& dq, uint16_t newClass) { (void) newClass; });
- luaCtx.registerMember<int (DNSQuestion::*)>("rcode", [](const DNSQuestion& dq) -> int { return dq.getHeader()->rcode; }, [](DNSQuestion& dq, int newRCode) { dq.getHeader()->rcode = newRCode; });
+ luaCtx.registerMember<int (DNSQuestion::*)>("rcode", [](const DNSQuestion& dq) -> int { return static_cast<int>(dq.getHeader()->rcode); }, [](DNSQuestion& dq, int newRCode) {
+ dnsdist::PacketMangling::editDNSHeaderFromPacket(dq.getMutableData(), [newRCode](dnsheader& header) {
+ header.rcode = static_cast<decltype(header.rcode)>(newRCode);
+ return true;
+ });
+ });
luaCtx.registerMember<const ComboAddress (DNSQuestion::*)>("remoteaddr", [](const DNSQuestion& dq) -> const ComboAddress { return dq.ids.origRemote; }, [](DNSQuestion& dq, const ComboAddress newRemote) { (void) newRemote; });
/* DNSDist DNSQuestion */
- luaCtx.registerMember<dnsheader* (DNSQuestion::*)>("dh", [](const DNSQuestion& dq) -> dnsheader* { return const_cast<DNSQuestion&>(dq).getHeader(); }, [](DNSQuestion& dq, const dnsheader* dh) { *(dq.getHeader()) = *dh; });
+ luaCtx.registerMember<dnsheader* (DNSQuestion::*)>("dh", [](const DNSQuestion& dq) -> dnsheader* { return dq.getMutableHeader(); }, [](DNSQuestion& dq, const dnsheader* dh) {
+ dnsdist::PacketMangling::editDNSHeaderFromPacket(dq.getMutableData(), [&dh](dnsheader& header) {
+ header = *dh;
+ return true;
+ });
+ });
luaCtx.registerMember<uint16_t (DNSQuestion::*)>("len", [](const DNSQuestion& dq) -> uint16_t { return dq.getData().size(); }, [](DNSQuestion& dq, uint16_t newlen) { dq.getMutableData().resize(newlen); });
luaCtx.registerMember<uint8_t (DNSQuestion::*)>("opcode", [](const DNSQuestion& dq) -> uint8_t { return dq.getHeader()->opcode; }, [](DNSQuestion& dq, uint8_t newOpcode) { (void) newOpcode; });
luaCtx.registerMember<bool (DNSQuestion::*)>("tcp", [](const DNSQuestion& dq) -> bool { return dq.overTCP(); }, [](DNSQuestion& dq, bool newTcp) { (void) newTcp; });
@@ -90,7 +101,7 @@ void setupLuaBindingsDNSQuestion(LuaContext& luaCtx)
dq.ids.d_protoBufData->d_requestorID = newValue;
});
luaCtx.registerFunction<bool(DNSQuestion::*)()const>("getDO", [](const DNSQuestion& dq) {
- return getEDNSZ(dq) & EDNS_HEADER_FLAG_DO;
+ return getEDNSZ(dq) & EDNS_HEADER_FLAG_DO;
});
luaCtx.registerFunction<std::string(DNSQuestion::*)()const>("getContent", [](const DNSQuestion& dq) {
return std::string(reinterpret_cast<const char*>(dq.getData().data()), dq.getData().size());
@@ -100,7 +111,11 @@ void setupLuaBindingsDNSQuestion(LuaContext& luaCtx)
auto& buffer = dq.getMutableData();
buffer.clear();
buffer.insert(buffer.begin(), raw.begin(), raw.end());
- reinterpret_cast<dnsheader*>(buffer.data())->id = oldID;
+
+ dnsdist::PacketMangling::editDNSHeaderFromPacket(buffer, [oldID](dnsheader& header) {
+ header.id = oldID;
+ return true;
+ });
});
luaCtx.registerFunction<std::map<uint16_t, EDNSOptionView>(DNSQuestion::*)()const>("getEDNSOptions", [](const DNSQuestion& dq) {
if (dq.ednsOptions == nullptr) {
@@ -187,7 +202,7 @@ void setupLuaBindingsDNSQuestion(LuaContext& luaCtx)
dq.proxyProtocolValues = make_unique<std::vector<ProxyProtocolValue>>();
}
- dq.proxyProtocolValues->push_back({value, static_cast<uint8_t>(type)});
+ dq.proxyProtocolValues->push_back({std::move(value), static_cast<uint8_t>(type)});
});
luaCtx.registerFunction<LuaArray<std::string>(DNSQuestion::*)()>("getProxyProtocolValues", [](const DNSQuestion& dq) {
@@ -212,7 +227,7 @@ void setupLuaBindingsDNSQuestion(LuaContext& luaCtx)
return true;
});
- luaCtx.registerFunction<void(DNSQuestion::*)(const boost::variant<LuaArray<ComboAddress>, LuaArray<std::string>>& response)>("spoof", [](DNSQuestion& dq, const boost::variant<LuaArray<ComboAddress>, LuaArray<std::string>>& response) {
+ luaCtx.registerFunction<void(DNSQuestion::*)(const boost::variant<LuaArray<ComboAddress>, LuaArray<std::string>>&, boost::optional<uint16_t>)>("spoof", [](DNSQuestion& dnsQuestion, const boost::variant<LuaArray<ComboAddress>, LuaArray<std::string>>& response, boost::optional<uint16_t> typeForAny) {
if (response.type() == typeid(LuaArray<ComboAddress>)) {
std::vector<ComboAddress> data;
auto responses = boost::get<LuaArray<ComboAddress>>(response);
@@ -221,8 +236,8 @@ void setupLuaBindingsDNSQuestion(LuaContext& luaCtx)
data.push_back(resp.second);
}
std::string result;
- SpoofAction sa(data);
- sa(&dq, &result);
+ SpoofAction tempSpoofAction(data);
+ tempSpoofAction(&dnsQuestion, &result);
return;
}
if (response.type() == typeid(LuaArray<std::string>)) {
@@ -233,8 +248,8 @@ void setupLuaBindingsDNSQuestion(LuaContext& luaCtx)
data.push_back(resp.second);
}
std::string result;
- SpoofAction sa(data);
- sa(&dq, &result);
+ SpoofAction tempSpoofAction(data, typeForAny ? *typeForAny : std::optional<uint16_t>());
+ tempSpoofAction(&dnsQuestion, &result);
return;
}
});
@@ -243,6 +258,15 @@ void setupLuaBindingsDNSQuestion(LuaContext& luaCtx)
setEDNSOption(dq, code, data);
});
+ luaCtx.registerFunction<void(DNSQuestion::*)(uint16_t infoCode, const boost::optional<std::string>& extraText)>("setExtendedDNSError", [](DNSQuestion& dnsQuestion, uint16_t infoCode, const boost::optional<std::string>& extraText) {
+ EDNSExtendedError ede;
+ ede.infoCode = infoCode;
+ if (extraText) {
+ ede.extraText = *extraText;
+ }
+ dnsQuestion.ids.d_extendedError = std::make_unique<EDNSExtendedError>(ede);
+ });
+
luaCtx.registerFunction<bool(DNSQuestion::*)(uint16_t asyncID, uint16_t queryID, uint32_t timeoutMs)>("suspend", [](DNSQuestion& dq, uint16_t asyncID, uint16_t queryID, uint32_t timeoutMs) {
dq.asynchronous = true;
return dnsdist::suspendQuery(dq, asyncID, queryID, timeoutMs);
@@ -284,7 +308,7 @@ public:
struct timeval now;
gettimeofday(&now, nullptr);
- sender->notifyIOError(std::move(object->query.d_idstate), now);
+ sender->notifyIOError(now, TCPResponse(std::move(object->query)));
return true;
}
@@ -333,9 +357,19 @@ private:
luaCtx.registerMember<const DNSName (DNSResponse::*)>("qname", [](const DNSResponse& dq) -> const DNSName { return dq.ids.qname; }, [](DNSResponse& dq, const DNSName& newName) { (void) newName; });
luaCtx.registerMember<uint16_t (DNSResponse::*)>("qtype", [](const DNSResponse& dq) -> uint16_t { return dq.ids.qtype; }, [](DNSResponse& dq, uint16_t newType) { (void) newType; });
luaCtx.registerMember<uint16_t (DNSResponse::*)>("qclass", [](const DNSResponse& dq) -> uint16_t { return dq.ids.qclass; }, [](DNSResponse& dq, uint16_t newClass) { (void) newClass; });
- luaCtx.registerMember<int (DNSResponse::*)>("rcode", [](const DNSResponse& dq) -> int { return dq.getHeader()->rcode; }, [](DNSResponse& dq, int newRCode) { dq.getHeader()->rcode = newRCode; });
+ luaCtx.registerMember<int (DNSResponse::*)>("rcode", [](const DNSResponse& dq) -> int { return static_cast<int>(dq.getHeader()->rcode); }, [](DNSResponse& dq, int newRCode) {
+ dnsdist::PacketMangling::editDNSHeaderFromPacket(dq.getMutableData(), [newRCode](dnsheader& header) {
+ header.rcode = static_cast<decltype(header.rcode)>(newRCode);
+ return true;
+ });
+ });
luaCtx.registerMember<const ComboAddress (DNSResponse::*)>("remoteaddr", [](const DNSResponse& dq) -> const ComboAddress { return dq.ids.origRemote; }, [](DNSResponse& dq, const ComboAddress newRemote) { (void) newRemote; });
- luaCtx.registerMember<dnsheader* (DNSResponse::*)>("dh", [](const DNSResponse& dr) -> dnsheader* { return const_cast<DNSResponse&>(dr).getHeader(); }, [](DNSResponse& dr, const dnsheader* dh) { *(dr.getHeader()) = *dh; });
+ luaCtx.registerMember<dnsheader* (DNSResponse::*)>("dh", [](const DNSResponse& dr) -> dnsheader* { return dr.getMutableHeader(); }, [](DNSResponse& dr, const dnsheader* dh) {
+ dnsdist::PacketMangling::editDNSHeaderFromPacket(dr.getMutableData(), [&dh](dnsheader& header) {
+ header = *dh;
+ return true;
+ });
+ });
luaCtx.registerMember<uint16_t (DNSResponse::*)>("len", [](const DNSResponse& dq) -> uint16_t { return dq.getData().size(); }, [](DNSResponse& dq, uint16_t newlen) { dq.getMutableData().resize(newlen); });
luaCtx.registerMember<uint8_t (DNSResponse::*)>("opcode", [](const DNSResponse& dq) -> uint8_t { return dq.getHeader()->opcode; }, [](DNSResponse& dq, uint8_t newOpcode) { (void) newOpcode; });
luaCtx.registerMember<bool (DNSResponse::*)>("tcp", [](const DNSResponse& dq) -> bool { return dq.overTCP(); }, [](DNSResponse& dq, bool newTcp) { (void) newTcp; });
@@ -355,7 +389,10 @@ private:
auto& buffer = dr.getMutableData();
buffer.clear();
buffer.insert(buffer.begin(), raw.begin(), raw.end());
- reinterpret_cast<dnsheader*>(buffer.data())->id = oldID;
+ dnsdist::PacketMangling::editDNSHeaderFromPacket(buffer, [oldID](dnsheader& header) {
+ header.id = oldID;
+ return true;
+ });
});
luaCtx.registerFunction<std::map<uint16_t, EDNSOptionView>(DNSResponse::*)()const>("getEDNSOptions", [](const DNSResponse& dq) {
@@ -478,6 +515,15 @@ private:
return setNegativeAndAdditionalSOA(dq, nxd, DNSName(zone), ttl, DNSName(mname), DNSName(rname), serial, refresh, retry, expire, minimum, false);
});
+ luaCtx.registerFunction<void(DNSResponse::*)(uint16_t infoCode, const boost::optional<std::string>& extraText)>("setExtendedDNSError", [](DNSResponse& dnsResponse, uint16_t infoCode, const boost::optional<std::string>& extraText) {
+ EDNSExtendedError ede;
+ ede.infoCode = infoCode;
+ if (extraText) {
+ ede.extraText = *extraText;
+ }
+ dnsResponse.ids.d_extendedError = std::make_unique<EDNSExtendedError>(ede);
+ });
+
luaCtx.registerFunction<bool(DNSResponse::*)(uint16_t asyncID, uint16_t queryID, uint32_t timeoutMs)>("suspend", [](DNSResponse& dr, uint16_t asyncID, uint16_t queryID, uint32_t timeoutMs) {
dr.asynchronous = true;
return dnsdist::suspendResponse(dr, asyncID, queryID, timeoutMs);
@@ -500,5 +546,9 @@ private:
auto query = dnsdist::getInternalQueryFromDQ(dr, false);
return dnsdist::queueQueryResumptionEvent(std::move(query));
});
+
+ luaCtx.registerFunction<std::shared_ptr<DownstreamState>(DNSResponse::*)(void)const>("getSelectedBackend", [](const DNSResponse& dr) {
+ return dr.d_downstream;
+ });
#endif /* DISABLE_NON_FFI_DQ_BINDINGS */
}