From 0ed8f0fa16cbcbbfce4af8729e91ef418563bb8e Mon Sep 17 00:00:00 2001 From: Remi Gacogne Date: Tue, 3 Dec 2019 17:10:09 +0100 Subject: [PATCH] dnsdist: Allow wrapping the FFI interface for the existing DNSQuestion object --- pdns/dnsdist-lua-bindings-dnsquestion.cc | 38 +-------- pdns/dnsdist-lua-bindings.cc | 24 ++++++ pdns/dnsdist-lua.cc | 7 ++ pdns/dnsdist.cc | 24 ++++++ pdns/dnsdist.hh | 3 + pdns/dnsdistdist/.gitignore | 1 + pdns/dnsdistdist/Makefile.am | 8 ++ pdns/dnsdistdist/dnsdist-lua-ffi-interface.h | 90 ++++++++++++++++++++ pdns/dnsdistdist/dnsdist-lua-ffi.cc | 79 +++++++++++++++++ pdns/dnsdistdist/dnsdist-lua-ffi.hh | 61 ++----------- regression-tests.dnsdist/test_DOH.py | 20 ----- regression-tests.dnsdist/test_EDNSOptions.py | 14 --- 12 files changed, 246 insertions(+), 123 deletions(-) create mode 100644 pdns/dnsdistdist/dnsdist-lua-ffi-interface.h diff --git a/pdns/dnsdist-lua-bindings-dnsquestion.cc b/pdns/dnsdist-lua-bindings-dnsquestion.cc index eff46f3ab5..71840e7f36 100644 --- a/pdns/dnsdist-lua-bindings-dnsquestion.cc +++ b/pdns/dnsdist-lua-bindings-dnsquestion.cc @@ -64,25 +64,10 @@ void setupLuaBindingsDNSQuestion() return *dq.ednsOptions; }); g_lua.registerFunction("getTrailingData", [](const DNSQuestion& dq) { - const char* message = reinterpret_cast(dq.dh); - const uint16_t messageLen = getDNSPacketLength(message, dq.len); - const std::string tail = std::string(message + messageLen, dq.len - messageLen); - return tail; + return dq.getTrailingData(); }); g_lua.registerFunction("setTrailingData", [](DNSQuestion& dq, const std::string& tail) { - char* message = reinterpret_cast(dq.dh); - const uint16_t messageLen = getDNSPacketLength(message, dq.len); - const uint16_t tailLen = tail.size(); - if(tailLen > (dq.size - messageLen)) { - return false; - } - - /* Update length and copy data from the Lua string. */ - dq.len = messageLen + tailLen; - if(tailLen > 0) { - tail.copy(message + messageLen, tailLen); - } - return true; + return dq.setTrailingData(tail); }); g_lua.registerFunction("getServerNameIndication", [](const DNSQuestion& dq) { @@ -150,25 +135,10 @@ void setupLuaBindingsDNSQuestion() editDNSPacketTTL((char*) dr.dh, dr.len, editFunc); }); g_lua.registerFunction("getTrailingData", [](const DNSResponse& dq) { - const char* message = reinterpret_cast(dq.dh); - const uint16_t messageLen = getDNSPacketLength(message, dq.len); - const std::string tail = std::string(message + messageLen, dq.len - messageLen); - return tail; + return dq.getTrailingData(); }); g_lua.registerFunction("setTrailingData", [](DNSResponse& dq, const std::string& tail) { - char* message = reinterpret_cast(dq.dh); - const uint16_t messageLen = getDNSPacketLength(message, dq.len); - const uint16_t tailLen = tail.size(); - if(tailLen > (dq.size - messageLen)) { - return false; - } - - /* Update length and copy data from the Lua string. */ - dq.len = messageLen + tailLen; - if(tailLen > 0) { - tail.copy(message + messageLen, tailLen); - } - return true; + return dq.setTrailingData(tail); }); g_lua.registerFunction("setTag", [](DNSResponse& dr, const std::string& strLabel, const std::string& strValue) { diff --git a/pdns/dnsdist-lua-bindings.cc b/pdns/dnsdist-lua-bindings.cc index 06cc42f9da..fc25caddf3 100644 --- a/pdns/dnsdist-lua-bindings.cc +++ b/pdns/dnsdist-lua-bindings.cc @@ -172,6 +172,29 @@ void setupLuaBindings(bool client) /* ComboAddress */ g_lua.writeFunction("newCA", [](const std::string& name) { return ComboAddress(name); }); + g_lua.writeFunction("newCAFromRaw", [](const std::string& raw, boost::optional port) { + if (raw.size() == 4) { + struct sockaddr_in sin4; + memset(&sin4, 0, sizeof(sin4)); + sin4.sin_family = AF_INET; + memcpy(&sin4.sin_addr.s_addr, raw.c_str(), raw.size()); + if (port) { + sin4.sin_port = htons(*port); + } + return ComboAddress(&sin4); + } + else if (raw.size() == 16) { + struct sockaddr_in6 sin6; + memset(&sin6, 0, sizeof(sin6)); + sin6.sin6_family = AF_INET6; + memcpy(&sin6.sin6_addr.s6_addr, raw.c_str(), raw.size()); + if (port) { + sin6.sin6_port = htons(*port); + } + return ComboAddress(&sin6); + } + return ComboAddress(); + }); g_lua.registerFunction("tostring", [](const ComboAddress& ca) { return ca.toString(); }); g_lua.registerFunction("tostringWithPort", [](const ComboAddress& ca) { return ca.toStringWithPort(); }); g_lua.registerFunction("toString", [](const ComboAddress& ca) { return ca.toString(); }); @@ -192,6 +215,7 @@ void setupLuaBindings(bool client) g_lua.registerFunction("tostring", [](const DNSName&dn ) { return dn.toString(); }); g_lua.registerFunction("toString", [](const DNSName&dn ) { return dn.toString(); }); g_lua.writeFunction("newDNSName", [](const std::string& name) { return DNSName(name); }); + g_lua.writeFunction("newDNSNameFromRaw", [](const std::string& name) { return DNSName(name.c_str(), name.size(), 0, false); }); g_lua.writeFunction("newSuffixMatchNode", []() { return SuffixMatchNode(); }); g_lua.writeFunction("newDNSNameSet", []() { return DNSNameSet(); }); diff --git a/pdns/dnsdist-lua.cc b/pdns/dnsdist-lua.cc index a2979bac0b..0cb77d6064 100644 --- a/pdns/dnsdist-lua.cc +++ b/pdns/dnsdist-lua.cc @@ -36,6 +36,9 @@ #include "dnsdist-ecs.hh" #include "dnsdist-healthchecks.hh" #include "dnsdist-lua.hh" +#ifdef LUAJIT_VERSION +#include "dnsdist-lua-ffi.hh" +#endif /* LUAJIT_VERSION */ #include "dnsdist-rings.hh" #include "dnsdist-secpoll.hh" @@ -2191,6 +2194,10 @@ vector> setupLua(bool client, bool configCheck, const setupLuaRules(); setupLuaVars(); +#ifdef LUAJIT_VERSION + g_lua.executeCode(getLuaFFIWrappers()); +#endif + std::ifstream ifs(config); if(!ifs) warnlog("Unable to read configuration from '%s'", config); diff --git a/pdns/dnsdist.cc b/pdns/dnsdist.cc index 00cb2e3dfb..75d7c56ea2 100644 --- a/pdns/dnsdist.cc +++ b/pdns/dnsdist.cc @@ -193,6 +193,30 @@ struct DelayedPacket DelayPipe* g_delay = nullptr; +std::string DNSQuestion::getTrailingData() const +{ + const char* message = reinterpret_cast(this->dh); + const uint16_t messageLen = getDNSPacketLength(message, this->len); + return std::string(message + messageLen, this->len - messageLen); +} + +bool DNSQuestion::setTrailingData(const std::string& tail) +{ + char* message = reinterpret_cast(this->dh); + const uint16_t messageLen = getDNSPacketLength(message, this->len); + const uint16_t tailLen = tail.size(); + if (tailLen > (this->size - messageLen)) { + return false; + } + + /* Update length and copy data from the Lua string. */ + this->len = messageLen + tailLen; + if(tailLen > 0) { + tail.copy(message + messageLen, tailLen); + } + return true; +} + void doLatencyStats(double udiff) { if(udiff < 1000) ++g_stats.latency0_1; diff --git a/pdns/dnsdist.hh b/pdns/dnsdist.hh index 9443dc8ce9..44c992d01b 100644 --- a/pdns/dnsdist.hh +++ b/pdns/dnsdist.hh @@ -70,6 +70,9 @@ struct DNSQuestion DNSQuestion& operator=(const DNSQuestion&) = delete; DNSQuestion(DNSQuestion&&) = default; + std::string getTrailingData() const; + bool setTrailingData(const std::string&); + #ifdef HAVE_PROTOBUF boost::optional uniqueId; #endif diff --git a/pdns/dnsdistdist/.gitignore b/pdns/dnsdistdist/.gitignore index 5cec6c5e8f..30c50de897 100644 --- a/pdns/dnsdistdist/.gitignore +++ b/pdns/dnsdistdist/.gitignore @@ -18,6 +18,7 @@ /configure /depcomp /dnsdist.1 +/dnsdist-lua-ffi-interface.inc /dnslabeltext.cc /ext/ipcrypt/Makefile /ext/ipcrypt/Makefile.in diff --git a/pdns/dnsdistdist/Makefile.am b/pdns/dnsdistdist/Makefile.am index a050dfbe94..6e49348621 100644 --- a/pdns/dnsdistdist/Makefile.am +++ b/pdns/dnsdistdist/Makefile.am @@ -10,6 +10,7 @@ CLEANFILES = \ dnsmessage.pb.h \ htmlfiles.h.tmp \ htmlfiles.h \ + dnsdist-lua-ffi-interface.inc \ dnstap.pb.cc \ dnstap.pb.h @@ -17,12 +18,18 @@ dnslabeltext.cc: dnslabeltext.rl $(AM_V_GEN)$(RAGEL) $< -o dnslabeltext.cc BUILT_SOURCES=htmlfiles.h \ + dnsdist-lua-ffi-interface.inc \ dnslabeltext.cc htmlfiles.h: $(srcdir)/html/* $(AM_V_GEN)$(srcdir)/incfiles $(srcdir) > $@.tmp @mv $@.tmp $@ +dnsdist-lua-ffi-interface.inc: dnsdist-lua-ffi-interface.h + echo 'R"FFIContent(' > $@ + cat $< >> $@ + echo ')FFIContent"' >> $@ + SRC_JS_FILES := $(wildcard src_js/*.js) MIN_JS_FILES := $(patsubst src_js/%.js,html/js/%.min.js,$(SRC_JS_FILES)) @@ -136,6 +143,7 @@ dnsdist_SOURCES = \ dnsdist-lua-bindings-packetcache.cc \ dnsdist-lua-bindings-protobuf.cc \ dnsdist-lua-ffi.cc dnsdist-lua-ffi.hh \ + dnsdist-lua-ffi-interface.h dnsdist-lua-ffi-interface.inc \ 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-ffi-interface.h b/pdns/dnsdistdist/dnsdist-lua-ffi-interface.h new file mode 100644 index 0000000000..fa8841d0b8 --- /dev/null +++ b/pdns/dnsdistdist/dnsdist-lua-ffi-interface.h @@ -0,0 +1,90 @@ +/* + * 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. + */ +typedef struct dnsdist_ffi_dnsquestion_t dnsdist_ffi_dnsquestion_t; + +typedef struct dnsdist_ednsoption { + uint16_t optionCode; + uint16_t len; + const void* data; +} dnsdist_ednsoption_t; + +typedef struct dnsdist_http_header { + const char* name; + const char* value; +} dnsdist_http_header_t; + +typedef struct dnsdist_tag { + const char* name; + const char* value; +} dnsdist_tag_t; + +void dnsdist_ffi_dnsquestion_get_localaddr(const dnsdist_ffi_dnsquestion_t* dq, const void** addr, size_t* addrSize) __attribute__ ((visibility ("default"))); +uint16_t dnsdist_ffi_dnsquestion_get_local_port(const dnsdist_ffi_dnsquestion_t* dq) __attribute__ ((visibility ("default"))); +void dnsdist_ffi_dnsquestion_get_remoteaddr(const dnsdist_ffi_dnsquestion_t* dq, const void** addr, size_t* addrSize) __attribute__ ((visibility ("default"))); +uint16_t dnsdist_ffi_dnsquestion_get_remote_port(const dnsdist_ffi_dnsquestion_t* dq) __attribute__ ((visibility ("default"))); +void dnsdist_ffi_dnsquestion_get_qname_raw(const dnsdist_ffi_dnsquestion_t* dq, const char** qname, size_t* qnameSize) __attribute__ ((visibility ("default"))); +uint16_t dnsdist_ffi_dnsquestion_get_qtype(const dnsdist_ffi_dnsquestion_t* dq) __attribute__ ((visibility ("default"))); +uint16_t dnsdist_ffi_dnsquestion_get_qclass(const dnsdist_ffi_dnsquestion_t* dq) __attribute__ ((visibility ("default"))); +int dnsdist_ffi_dnsquestion_get_rcode(const dnsdist_ffi_dnsquestion_t* dq) __attribute__ ((visibility ("default"))); +void* dnsdist_ffi_dnsquestion_get_header(const dnsdist_ffi_dnsquestion_t* dq) __attribute__ ((visibility ("default"))); +uint16_t dnsdist_ffi_dnsquestion_get_len(const dnsdist_ffi_dnsquestion_t* dq) __attribute__ ((visibility ("default"))); +size_t dnsdist_ffi_dnsquestion_get_size(const dnsdist_ffi_dnsquestion_t* dq) __attribute__ ((visibility ("default"))); +uint8_t dnsdist_ffi_dnsquestion_get_opcode(const dnsdist_ffi_dnsquestion_t* dq) __attribute__ ((visibility ("default"))); +bool dnsdist_ffi_dnsquestion_get_tcp(const dnsdist_ffi_dnsquestion_t* dq) __attribute__ ((visibility ("default"))); +bool dnsdist_ffi_dnsquestion_get_skip_cache(const dnsdist_ffi_dnsquestion_t* dq) __attribute__ ((visibility ("default"))); +bool dnsdist_ffi_dnsquestion_get_use_ecs(const dnsdist_ffi_dnsquestion_t* dq) __attribute__ ((visibility ("default"))); +bool dnsdist_ffi_dnsquestion_get_add_xpf(const dnsdist_ffi_dnsquestion_t* dq) __attribute__ ((visibility ("default"))); +bool dnsdist_ffi_dnsquestion_get_ecs_override(const dnsdist_ffi_dnsquestion_t* dq) __attribute__ ((visibility ("default"))); +uint16_t dnsdist_ffi_dnsquestion_get_ecs_prefix_length(const dnsdist_ffi_dnsquestion_t* dq) __attribute__ ((visibility ("default"))); +bool dnsdist_ffi_dnsquestion_is_temp_failure_ttl_set(const dnsdist_ffi_dnsquestion_t* dq) __attribute__ ((visibility ("default"))); +uint32_t dnsdist_ffi_dnsquestion_get_temp_failure_ttl(const dnsdist_ffi_dnsquestion_t* dq) __attribute__ ((visibility ("default"))); +bool dnsdist_ffi_dnsquestion_get_do(const dnsdist_ffi_dnsquestion_t* dq) __attribute__ ((visibility ("default"))); +void dnsdist_ffi_dnsquestion_get_sni(const dnsdist_ffi_dnsquestion_t* dq, const char** sni, size_t* sniSize) __attribute__ ((visibility ("default"))); +const char* dnsdist_ffi_dnsquestion_get_tag(const dnsdist_ffi_dnsquestion_t* dq, const char* label) __attribute__ ((visibility ("default"))); +const char* dnsdist_ffi_dnsquestion_get_http_path(dnsdist_ffi_dnsquestion_t* dq) __attribute__ ((visibility ("default"))); +const char* dnsdist_ffi_dnsquestion_get_http_query_string(dnsdist_ffi_dnsquestion_t* dq) __attribute__ ((visibility ("default"))); +const char* dnsdist_ffi_dnsquestion_get_http_host(dnsdist_ffi_dnsquestion_t* dq) __attribute__ ((visibility ("default"))); +const char* dnsdist_ffi_dnsquestion_get_http_scheme(dnsdist_ffi_dnsquestion_t* dq) __attribute__ ((visibility ("default"))); + +// returns the length of the resulting 'out' array. 'out' is not set if the length is 0 +size_t dnsdist_ffi_dnsquestion_get_edns_options(dnsdist_ffi_dnsquestion_t* ref, const dnsdist_ednsoption_t** out) __attribute__ ((visibility ("default"))); +size_t dnsdist_ffi_dnsquestion_get_http_headers(dnsdist_ffi_dnsquestion_t* ref, const dnsdist_http_header_t** out) __attribute__ ((visibility ("default"))); +size_t dnsdist_ffi_dnsquestion_get_tag_array(dnsdist_ffi_dnsquestion_t* ref, const dnsdist_tag_t** out) __attribute__ ((visibility ("default"))); + +void dnsdist_ffi_dnsquestion_set_result(dnsdist_ffi_dnsquestion_t* dq, const char* str, size_t strSize) __attribute__ ((visibility ("default"))); +void dnsdist_ffi_dnsquestion_set_rcode(dnsdist_ffi_dnsquestion_t* dq, int rcode) __attribute__ ((visibility ("default"))); +void dnsdist_ffi_dnsquestion_set_len(dnsdist_ffi_dnsquestion_t* dq, uint16_t len) __attribute__ ((visibility ("default"))); +void dnsdist_ffi_dnsquestion_set_skip_cache(dnsdist_ffi_dnsquestion_t* dq, bool skipCache) __attribute__ ((visibility ("default"))); +void dnsdist_ffi_dnsquestion_set_use_ecs(dnsdist_ffi_dnsquestion_t* dq, bool useECS) __attribute__ ((visibility ("default"))); +void dnsdist_ffi_dnsquestion_set_ecs_override(dnsdist_ffi_dnsquestion_t* dq, bool ecsOverride) __attribute__ ((visibility ("default"))); +void dnsdist_ffi_dnsquestion_set_ecs_prefix_length(dnsdist_ffi_dnsquestion_t* dq, uint16_t ecsPrefixLength) __attribute__ ((visibility ("default"))); +void dnsdist_ffi_dnsquestion_set_temp_failure_ttl(dnsdist_ffi_dnsquestion_t* dq, uint32_t tempFailureTTL) __attribute__ ((visibility ("default"))); +void dnsdist_ffi_dnsquestion_unset_temp_failure_ttl(dnsdist_ffi_dnsquestion_t* dq) __attribute__ ((visibility ("default"))); +void dnsdist_ffi_dnsquestion_set_tag(dnsdist_ffi_dnsquestion_t* dq, const char* label, const char* value) __attribute__ ((visibility ("default"))); + +void dnsdist_ffi_dnsquestion_set_http_response(dnsdist_ffi_dnsquestion_t* dq, uint16_t statusCode, const char* body, const char* contentType) __attribute__ ((visibility ("default"))); + +size_t dnsdist_ffi_dnsquestion_get_trailing_data(dnsdist_ffi_dnsquestion_t* dq, const char** out) __attribute__ ((visibility ("default"))); + +bool dnsdist_ffi_dnsquestion_set_trailing_data(dnsdist_ffi_dnsquestion_t* dq, const char* data, size_t dataLen) __attribute__ ((visibility ("default"))); + +void dnsdist_ffi_dnsquestion_send_trap(dnsdist_ffi_dnsquestion_t* dq, const char* reason, size_t reasonLen) __attribute__ ((visibility ("default"))); diff --git a/pdns/dnsdistdist/dnsdist-lua-ffi.cc b/pdns/dnsdistdist/dnsdist-lua-ffi.cc index 5653c9f96d..cfffc2c1e3 100644 --- a/pdns/dnsdistdist/dnsdist-lua-ffi.cc +++ b/pdns/dnsdistdist/dnsdist-lua-ffi.cc @@ -55,6 +55,16 @@ void dnsdist_ffi_dnsquestion_get_remoteaddr(const dnsdist_ffi_dnsquestion_t* dq, dnsdist_ffi_comboaddress_to_raw(*dq->dq->remote, addr, addrSize); } +uint16_t dnsdist_ffi_dnsquestion_get_local_port(const dnsdist_ffi_dnsquestion_t* dq) +{ + return dq->dq->local->getPort(); +} + +uint16_t dnsdist_ffi_dnsquestion_get_remote_port(const dnsdist_ffi_dnsquestion_t* dq) +{ + return dq->dq->remote->getPort(); +} + void dnsdist_ffi_dnsquestion_get_qname_raw(const dnsdist_ffi_dnsquestion_t* dq, const char** qname, size_t* qnameSize) { const auto& storage = dq->dq->qname->getStorage(); @@ -286,6 +296,31 @@ size_t dnsdist_ffi_dnsquestion_get_http_headers(dnsdist_ffi_dnsquestion_t* dq, c #endif } +size_t dnsdist_ffi_dnsquestion_get_tag_array(dnsdist_ffi_dnsquestion_t* dq, const dnsdist_tag_t** out) +{ + if (dq->dq->qTag == nullptr || dq->dq->qTag->size() == 0) { + return 0; + } + + dq->tagsVect.clear(); + dq->tagsVect.resize(dq->dq->qTag->size()); + size_t pos = 0; + + for (const auto& tag : *dq->dq->qTag) { + auto& entry = dq->tagsVect.at(pos); + entry.name = tag.first.c_str(); + entry.value = tag.second.c_str(); + ++pos; + } + + + if (!dq->tagsVect.empty()) { + *out = dq->tagsVect.data(); + } + + return dq->tagsVect.size(); +} + void dnsdist_ffi_dnsquestion_set_result(dnsdist_ffi_dnsquestion_t* dq, const char* str, size_t strSize) { dq->result = std::string(str, strSize); @@ -339,6 +374,11 @@ void dnsdist_ffi_dnsquestion_set_temp_failure_ttl(dnsdist_ffi_dnsquestion_t* dq, dq->dq->tempFailureTTL = tempFailureTTL; } +void dnsdist_ffi_dnsquestion_unset_temp_failure_ttl(dnsdist_ffi_dnsquestion_t* dq) +{ + dq->dq->tempFailureTTL = boost::none; +} + void dnsdist_ffi_dnsquestion_set_tag(dnsdist_ffi_dnsquestion_t* dq, const char* label, const char* value) { if (!dq->dq->qTag) { @@ -347,3 +387,42 @@ void dnsdist_ffi_dnsquestion_set_tag(dnsdist_ffi_dnsquestion_t* dq, const char* dq->dq->qTag->insert({label, value}); } + +size_t dnsdist_ffi_dnsquestion_get_trailing_data(dnsdist_ffi_dnsquestion_t* dq, const char** out) +{ + dq->trailingData = dq->dq->getTrailingData(); + if (!dq->trailingData.empty()) { + *out = dq->trailingData.data(); + } + + return dq->trailingData.size(); +} + +bool dnsdist_ffi_dnsquestion_set_trailing_data(dnsdist_ffi_dnsquestion_t* dq, const char* data, size_t dataLen) +{ + return dq->dq->setTrailingData(std::string(data, dataLen)); +} + +void dnsdist_ffi_dnsquestion_send_trap(dnsdist_ffi_dnsquestion_t* dq, const char* reason, size_t reasonLen) +{ + if (g_snmpAgent && g_snmpTrapsEnabled) { + g_snmpAgent->sendDNSTrap(*dq->dq, std::string(reason, reasonLen)); + } +} + +const std::string& getLuaFFIWrappers() +{ + static const std::string interface = +#include "dnsdist-lua-ffi-interface.inc" + ; + static const std::string code = R"FFICodeContent( + local ffi = require("ffi") + local C = ffi.C + + ffi.cdef[[ +)FFICodeContent" + interface + R"FFICodeContent( + ]] + +)FFICodeContent"; + return code; +} diff --git a/pdns/dnsdistdist/dnsdist-lua-ffi.hh b/pdns/dnsdistdist/dnsdist-lua-ffi.hh index 05ba6a4560..913c759474 100644 --- a/pdns/dnsdistdist/dnsdist-lua-ffi.hh +++ b/pdns/dnsdistdist/dnsdist-lua-ffi.hh @@ -24,60 +24,7 @@ #include "dnsdist.hh" extern "C" { - typedef struct dnsdist_ffi_dnsquestion_t dnsdist_ffi_dnsquestion_t; - - typedef struct dnsdist_ednsoption { - uint16_t optionCode; - uint16_t len; - const void* data; - } dnsdist_ednsoption_t; - - typedef struct dnsdist_http_header { - const char* name; - const char* value; - } dnsdist_http_header_t; - - void dnsdist_ffi_dnsquestion_get_localaddr(const dnsdist_ffi_dnsquestion_t* dq, const void** addr, size_t* addrSize) __attribute__ ((visibility ("default"))); - void dnsdist_ffi_dnsquestion_get_remoteaddr(const dnsdist_ffi_dnsquestion_t* dq, const void** addr, size_t* addrSize) __attribute__ ((visibility ("default"))); - void dnsdist_ffi_dnsquestion_get_qname_raw(const dnsdist_ffi_dnsquestion_t* dq, const char** qname, size_t* qnameSize) __attribute__ ((visibility ("default"))); - uint16_t dnsdist_ffi_dnsquestion_get_qtype(const dnsdist_ffi_dnsquestion_t* dq) __attribute__ ((visibility ("default"))); - uint16_t dnsdist_ffi_dnsquestion_get_qclass(const dnsdist_ffi_dnsquestion_t* dq) __attribute__ ((visibility ("default"))); - int dnsdist_ffi_dnsquestion_get_rcode(const dnsdist_ffi_dnsquestion_t* dq) __attribute__ ((visibility ("default"))); - void* dnsdist_ffi_dnsquestion_get_header(const dnsdist_ffi_dnsquestion_t* dq) __attribute__ ((visibility ("default"))); - uint16_t dnsdist_ffi_dnsquestion_get_len(const dnsdist_ffi_dnsquestion_t* dq) __attribute__ ((visibility ("default"))); - size_t dnsdist_ffi_dnsquestion_get_size(const dnsdist_ffi_dnsquestion_t* dq) __attribute__ ((visibility ("default"))); - uint8_t dnsdist_ffi_dnsquestion_get_opcode(const dnsdist_ffi_dnsquestion_t* dq) __attribute__ ((visibility ("default"))); - bool dnsdist_ffi_dnsquestion_get_tcp(const dnsdist_ffi_dnsquestion_t* dq) __attribute__ ((visibility ("default"))); - bool dnsdist_ffi_dnsquestion_get_skip_cache(const dnsdist_ffi_dnsquestion_t* dq) __attribute__ ((visibility ("default"))); - bool dnsdist_ffi_dnsquestion_get_use_ecs(const dnsdist_ffi_dnsquestion_t* dq) __attribute__ ((visibility ("default"))); - bool dnsdist_ffi_dnsquestion_get_add_xpf(const dnsdist_ffi_dnsquestion_t* dq) __attribute__ ((visibility ("default"))); - bool dnsdist_ffi_dnsquestion_get_ecs_override(const dnsdist_ffi_dnsquestion_t* dq) __attribute__ ((visibility ("default"))); - uint16_t dnsdist_ffi_dnsquestion_get_ecs_prefix_length(const dnsdist_ffi_dnsquestion_t* dq) __attribute__ ((visibility ("default"))); - bool dnsdist_ffi_dnsquestion_is_temp_failure_ttl_set(const dnsdist_ffi_dnsquestion_t* dq) __attribute__ ((visibility ("default"))); - uint32_t dnsdist_ffi_dnsquestion_get_temp_failure_ttl(const dnsdist_ffi_dnsquestion_t* dq) __attribute__ ((visibility ("default"))); - bool dnsdist_ffi_dnsquestion_get_do(const dnsdist_ffi_dnsquestion_t* dq) __attribute__ ((visibility ("default"))); - void dnsdist_ffi_dnsquestion_get_sni(const dnsdist_ffi_dnsquestion_t* dq, const char** sni, size_t* sniSize) __attribute__ ((visibility ("default"))); - const char* dnsdist_ffi_dnsquestion_get_tag(const dnsdist_ffi_dnsquestion_t* dq, const char* label) __attribute__ ((visibility ("default"))); - const char* dnsdist_ffi_dnsquestion_get_http_path(dnsdist_ffi_dnsquestion_t* dq) __attribute__ ((visibility ("default"))); - const char* dnsdist_ffi_dnsquestion_get_http_query_string(dnsdist_ffi_dnsquestion_t* dq) __attribute__ ((visibility ("default"))); - const char* dnsdist_ffi_dnsquestion_get_http_host(dnsdist_ffi_dnsquestion_t* dq) __attribute__ ((visibility ("default"))); - const char* dnsdist_ffi_dnsquestion_get_http_scheme(dnsdist_ffi_dnsquestion_t* dq) __attribute__ ((visibility ("default"))); - - // returns the length of the resulting 'out' array. 'out' is not set if the length is 0 - size_t dnsdist_ffi_dnsquestion_get_edns_options(dnsdist_ffi_dnsquestion_t* ref, const dnsdist_ednsoption_t** out) __attribute__ ((visibility ("default"))); - size_t dnsdist_ffi_dnsquestion_get_http_headers(dnsdist_ffi_dnsquestion_t* ref, const dnsdist_http_header_t** out) __attribute__ ((visibility ("default"))); - - void dnsdist_ffi_dnsquestion_set_result(dnsdist_ffi_dnsquestion_t* dq, const char* str, size_t strSize) __attribute__ ((visibility ("default"))); - void dnsdist_ffi_dnsquestion_set_rcode(dnsdist_ffi_dnsquestion_t* dq, int rcode) __attribute__ ((visibility ("default"))); - void dnsdist_ffi_dnsquestion_set_len(dnsdist_ffi_dnsquestion_t* dq, uint16_t len) __attribute__ ((visibility ("default"))); - void dnsdist_ffi_dnsquestion_set_skip_cache(dnsdist_ffi_dnsquestion_t* dq, bool skipCache) __attribute__ ((visibility ("default"))); - void dnsdist_ffi_dnsquestion_set_use_ecs(dnsdist_ffi_dnsquestion_t* dq, bool useECS) __attribute__ ((visibility ("default"))); - void dnsdist_ffi_dnsquestion_set_ecs_override(dnsdist_ffi_dnsquestion_t* dq, bool ecsOverride) __attribute__ ((visibility ("default"))); - void dnsdist_ffi_dnsquestion_set_ecs_prefix_length(dnsdist_ffi_dnsquestion_t* dq, uint16_t ecsPrefixLength) __attribute__ ((visibility ("default"))); - void dnsdist_ffi_dnsquestion_set_temp_failure_ttl(dnsdist_ffi_dnsquestion_t* dq, uint32_t tempFailureTTL) __attribute__ ((visibility ("default"))); - void dnsdist_ffi_dnsquestion_set_tag(dnsdist_ffi_dnsquestion_t* dq, const char* label, const char* value) __attribute__ ((visibility ("default"))); - - void dnsdist_ffi_dnsquestion_set_http_response(dnsdist_ffi_dnsquestion_t* dq, uint16_t statusCode, const char* body, const char* contentType) __attribute__ ((visibility ("default"))); +#include "dnsdist-lua-ffi-interface.h" } // dnsdist_ffi_dnsquestion_t is a lightuserdata @@ -100,11 +47,15 @@ struct dnsdist_ffi_dnsquestion_t DNSQuestion* dq{nullptr}; std::vector ednsOptionsVect; - std::vector httpHeadersVect; + std::vector httpHeadersVect; + std::vector tagsVect; std::unordered_map httpHeaders; + std::string trailingData; boost::optional result{boost::none}; boost::optional httpPath{boost::none}; boost::optional httpQueryString{boost::none}; boost::optional httpHost{boost::none}; boost::optional httpScheme{boost::none}; }; + +const std::string& getLuaFFIWrappers(); diff --git a/regression-tests.dnsdist/test_DOH.py b/regression-tests.dnsdist/test_DOH.py index 790df628fd..eb4b1cfcbf 100644 --- a/regression-tests.dnsdist/test_DOH.py +++ b/regression-tests.dnsdist/test_DOH.py @@ -900,26 +900,6 @@ class TestDOHFFI(DNSDistDOHTest): local ffi = require("ffi") - ffi.cdef[[ - typedef struct dnsdist_ffi_dnsquestion_t dnsdist_ffi_dnsquestion_t; - - typedef struct dnsdist_http_header { - const char* name; - const char* value; - } dnsdist_http_header_t; - - void dnsdist_ffi_dnsquestion_get_sni(const dnsdist_ffi_dnsquestion_t* dq, const char** sni, size_t* sniSize) __attribute__ ((visibility ("default"))); - - const char* dnsdist_ffi_dnsquestion_get_http_path(dnsdist_ffi_dnsquestion_t* dq) __attribute__ ((visibility ("default"))); - const char* dnsdist_ffi_dnsquestion_get_http_query_string(dnsdist_ffi_dnsquestion_t* dq) __attribute__ ((visibility ("default"))); - const char* dnsdist_ffi_dnsquestion_get_http_host(dnsdist_ffi_dnsquestion_t* dq) __attribute__ ((visibility ("default"))); - const char* dnsdist_ffi_dnsquestion_get_http_scheme(dnsdist_ffi_dnsquestion_t* dq) __attribute__ ((visibility ("default"))); - - size_t dnsdist_ffi_dnsquestion_get_http_headers(dnsdist_ffi_dnsquestion_t* ref, const dnsdist_http_header_t** out) __attribute__ ((visibility ("default"))); - - void dnsdist_ffi_dnsquestion_set_http_response(dnsdist_ffi_dnsquestion_t* dq, uint16_t statusCode, const char* body, const char* contentType) __attribute__ ((visibility ("default"))); - ]] - function dohHandler(dq) local scheme = ffi.string(ffi.C.dnsdist_ffi_dnsquestion_get_http_scheme(dq)) local host = ffi.string(ffi.C.dnsdist_ffi_dnsquestion_get_http_host(dq)) diff --git a/regression-tests.dnsdist/test_EDNSOptions.py b/regression-tests.dnsdist/test_EDNSOptions.py index f62a9e3d9e..7b1c8bbeff 100644 --- a/regression-tests.dnsdist/test_EDNSOptions.py +++ b/regression-tests.dnsdist/test_EDNSOptions.py @@ -390,20 +390,6 @@ class TestEDNSOptionsLuaFFI(DNSDistTest): _config_template = """ local ffi = require("ffi") - ffi.cdef[[ - typedef struct dnsdist_ffi_dnsquestion_t dnsdist_ffi_dnsquestion_t; - - typedef struct dnsdist_ednsoption { - uint16_t optionCode; - uint16_t len; - const void* data; - } dnsdist_ednsoption_t; - - void dnsdist_ffi_dnsquestion_get_qname_raw(const dnsdist_ffi_dnsquestion_t* dq, const char** qname, size_t* qnameSize) __attribute__ ((visibility ("default"))); - // returns the length of the resulting 'out' array. 'out' is not set if the length is 0 - size_t dnsdist_ffi_dnsquestion_get_edns_options(dnsdist_ffi_dnsquestion_t* ref, const dnsdist_ednsoption_t** out) __attribute__ ((visibility ("default"))); - ]] - function testEDNSOptions(dq) local options_ptr = ffi.new("const dnsdist_ednsoption_t *[1]") local ret_ptr_param = ffi.cast("const dnsdist_ednsoption_t **", options_ptr) -- 2.39.2