diff options
Diffstat (limited to 'dnsdist-lua-bindings-dnsquestion.cc')
-rw-r--r-- | dnsdist-lua-bindings-dnsquestion.cc | 78 |
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 */ } |